Skip to content

Commit

Permalink
Resource exporter/importer and unit test
Browse files Browse the repository at this point in the history
1. exporter
  serviceexport_controller is responsible to reconcile ServiceExport resource in member cluster and write
  wrapped ResourceExport into leader cluster, meanwhile it will watch Service and Endpoints change via
  event mapping and update ResourceExport when exported Service/Endpoints are updated.

  resourceexport_controller is responsible to reconcile ResourceExport resources and computes all ResourceExports
  from different member clusters into one ResourceExport in leader cluster if the resources are exported
  with the same namespaced name and the same kind, for this moment, we only support Service, Endpoints kind.

  service_controller is mainly do Service clean up, it will reconcile any Service with AntreaMCServiceAnnotation in
  member cluster and clean up it when there is no corresponding ResourceImport in leader cluster.

2. importer
  remote_resourceimport_controller watches leader cluster's ResourceImport events and create corresponding
  ServiceImport, Service and Endpoints with AntreaMCServiceAnnotation in member cluster. ServiceImport name will
  be the same as exported Service, new created Service and Endpoints will have an antrea multicluster prefix.

Notes: serviceexport_controller, service_controller and
remote_resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

3. stale controller
  stale controller is mainly for special cases when resource is deleted during controller restarting
in leader or member cluster, it will be triggered once only when controller starts.

4. add unit test codes.

Signed-off-by: Lan Luo <[email protected]>
  • Loading branch information
luolanzone committed Dec 15, 2021
1 parent 6e66fcb commit 55254ac
Show file tree
Hide file tree
Showing 26 changed files with 3,970 additions and 173 deletions.
2 changes: 2 additions & 0 deletions codecov.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ coverage:

ignore:
- "**/testing/mock_*.go"
- "**/mock_*.go"
- "**/*generate*.go"
- "pkg/client"
- "**/pkg/client"
- "**/*.pb.go"
- "third_party"
211 changes: 211 additions & 0 deletions multicluster/build/yamls/antrea-multicluster-leader-global.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1078,3 +1078,214 @@ status:
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
labels:
app: antrea
name: serviceexports.multicluster.x-k8s.io
spec:
group: multicluster.x-k8s.io
names:
kind: ServiceExport
plural: serviceexports
shortNames:
- svcex
singular: serviceexport
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: ServiceExport declares that the Service with the same name and namespace as this export should be consumable from other clusters.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
status:
description: status describes the current state of an exported service. Service configuration comes from the Service that had the same name and namespace as this ServiceExport. Populated by the multi-cluster service implementation's controller.
properties:
conditions:
items:
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
type: object
type: object
served: true
storage: true
subresources:
status: {}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
labels:
app: antrea
name: serviceimports.multicluster.x-k8s.io
spec:
group: multicluster.x-k8s.io
names:
kind: ServiceImport
plural: serviceimports
shortNames:
- svcim
singular: serviceimport
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: The type of this ServiceImport
jsonPath: .spec.type
name: Type
type: string
- description: The VIP for this ServiceImport
jsonPath: .spec.ips
name: IP
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: ServiceImport describes a service imported from clusters in a ClusterSet.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: spec defines the behavior of a ServiceImport.
properties:
ips:
description: ip will be used as the VIP for this service when type is ClusterSetIP.
items:
type: string
maxItems: 1
type: array
ports:
items:
description: ServicePort represents the port on which the service is exposed
properties:
appProtocol:
description: The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and http://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol. Field can be enabled with ServiceAppProtocol feature gate.
type: string
name:
description: The name of this port within the service. This must be a DNS_LABEL. All ports within a ServiceSpec must have unique names. When considering the endpoints for a Service, this must match the 'name' field in the EndpointPort. Optional if only one ServicePort is defined on this service.
type: string
port:
description: The port that will be exposed by this service.
format: int32
type: integer
protocol:
description: The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". Default is TCP.
type: string
required:
- port
type: object
type: array
x-kubernetes-list-type: atomic
sessionAffinity:
description: 'Supports "ClientIP" and "None". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. Ignored when type is Headless More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies'
type: string
sessionAffinityConfig:
description: sessionAffinityConfig contains session affinity configuration.
properties:
clientIP:
description: clientIP contains the configurations of Client IP based session affinity.
properties:
timeoutSeconds:
description: timeoutSeconds specifies the seconds of ClientIP type session sticky time. The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". Default value is 10800(for 3 hours).
format: int32
type: integer
type: object
type: object
type:
description: type defines the type of this service. Must be ClusterSetIP or Headless.
enum:
- ClusterSetIP
- Headless
type: string
required:
- ports
- type
type: object
status:
description: status contains information about the exported services that form the multi-cluster service referenced by this ServiceImport.
properties:
clusters:
description: clusters is the list of exporting clusters from which this service was derived.
items:
description: ClusterStatus contains service configuration mapped to a specific source cluster
properties:
cluster:
description: cluster is the name of the exporting cluster. Must be a valid RFC-1123 DNS label.
type: string
required:
- cluster
type: object
type: array
x-kubernetes-list-map-keys:
- cluster
x-kubernetes-list-type: map
type: object
type: object
served: true
storage: true
subresources:
status: {}
22 changes: 22 additions & 0 deletions multicluster/build/yamls/antrea-multicluster-leader-namespaced.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,26 @@ rules:
- get
- patch
- update
- apiGroups:
- multicluster.x-k8s.io
resources:
- serviceimports
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- multicluster.x-k8s.io
resources:
- serviceimports/status
verbs:
- get
- patch
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
Expand Down Expand Up @@ -332,6 +352,8 @@ rules:
- resourceexports/status
verbs:
- get
- patch
- update
- apiGroups:
- multicluster.crd.antrea.io
resources:
Expand Down
Loading

0 comments on commit 55254ac

Please sign in to comment.