Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resource exporter/importer and unit test #3024

Merged

Conversation

luolanzone
Copy link
Contributor

@luolanzone luolanzone commented Nov 11, 2021

This PR is mainly for resource exporter/importer:

  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.

  1. 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.

  2. 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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

  1. add unit test codes.

This PR is based on #3111, please kindly review top commit.
Signed-off-by: Lan Luo [email protected]

@luolanzone luolanzone added the area/multi-cluster Issues or PRs related to multi cluster. label Nov 11, 2021
@luolanzone luolanzone force-pushed the resource-controllers branch 3 times, most recently from 7b380a2 to 646bf65 Compare November 12, 2021 08:06
@luolanzone luolanzone force-pushed the feature/multi-cluster branch from eef025e to adc61a8 Compare November 15, 2021 08:01
@luolanzone luolanzone force-pushed the resource-controllers branch 3 times, most recently from b61b082 to be4ab6e Compare November 16, 2021 02:43
Copy link
Contributor

@jianjuns jianjuns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A general question - why we need to label the exported service? Could not we just identify the Services based on ServiceExport?

"sigs.k8s.io/controller-runtime/pkg/client"
)

type fakeRemoteCluster struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comments to indicate this is for unit tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

"antrea.io/antrea/multicluster/controllers/multicluster/internal"
)

// we should only have one remote leader cluster for demo purpose
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: we -> We

only have -> have only

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we have "demo" in the comments? If it is a temporary status, say "temporarily" or "at this moment", etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


// we should only have one remote leader cluster for demo purpose
// so check and return the first remote cluster.
func getRemoteCluster(remoteMgr *internal.RemoteClusterManager) (internal.RemoteCluster, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel not necessary to add a separate file for this func. Can we move it to service_controller.go?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, both service_controller.go and serviceexport_controller.go will call it, so I move it into utils.go. let me it move back.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

import "k8s.io/apimachinery/pkg/types"

const (
AntreaMcsLabel = "antrea.io/multi-cluster"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we follow our convention to use upper cases for abbrs, then "Mcs" should be "MCS".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we use label but not annotation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the main reason is there is no annotation selector, so I use label.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, how we use label selectors?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use labelselector to filter resource export in resourceexport_controller.go, eg https://github.com/antrea-io/antrea/pull/3024/files#diff-4a5af6131176d9b4bd232b0185161872343c0f501be3f061e07a555cc3b2dcb8R168
and
https://github.com/antrea-io/antrea/pull/3024/files#diff-4a5af6131176d9b4bd232b0185161872343c0f501be3f061e07a555cc3b2dcb8R318 etc. I feel in some cases we can use annotation, and some other cases we need label so we can use label selector. for service controller part, I will check if possible to use annotation instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel ideally we should not add labels in user created resources. It is redundant data, and more importantly we cannot prevent users from removing the labels. If example, they can just apply a yaml to update an existing Services and that will remove labels added by us.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, that make sense, thanks to point out, I will check how to achieve the same feature in a different way.

Copy link
Contributor Author

@luolanzone luolanzone Nov 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @jianjuns I updated it with an annotation instead of a label, the main purpose of this info is to reduce the service/endpoint update events and watch those exported resource event only https://github.com/antrea-io/antrea/pull/3024/files#diff-1e1d6e2558b5bb86a952c580e877a8a072c499a0c278194afb4d0948ae459d10R407-R443, we can skip adding any annotation and watch all services/endpoints, but I feel it will be a big effort to handle unnecessary services/endpoints change in ServiceExport reconciler. let me know what's your thought. thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But annotation is the same as label that can be removed by users (sorry if my previous comments are not clear). I feel watching all Services and Endpoints is ok, as it is just by one controller in the cluster. AntreaProxy watches all Services and Endpoints in all hosts.

Separator = '/'
)

// TODO: Use NamespacedName stringer method instead of this. eg nsName.String()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

. eg -> , e.g.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


// GetNamespacedName returns the objects name as NamespacedName struct.
func GetNamespacedName(namespace, name string) types.NamespacedName {
return types.NamespacedName{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a func for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it help us to build up a new types.NamespacedName with given strings, not from K8s object directly, so we construct it by ourself, mainly purpose is to avoid duplicate codes, only remote_resourceimport_controller.go use it for now, let me move it from helper to remote_resourceimport_controller.go

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But types.NamespacedName{namespace, name} is very simple and just one line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we can use types.NamespacedName{namespace, name} but it will give us a warning about k8s.io/apimachinery/pkg/types.NamespacedName composite literal uses unkeyed fieldscomposites, so I feel it's a little bit long to have both key and name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me change it back to struct directly, so we have less function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}
}

func GetPointer(str string) *string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need a func?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are a few fields requires string pointer,https://github.com/antrea-io/antrea/pull/3024/files#diff-1e1d6e2558b5bb86a952c580e877a8a072c499a0c278194afb4d0948ae459d10R362-R371, I added this to avoid define a string and get its pointer repeatedly, but looks like only serviceexporter_controller.go use this function, I will move it and name it as getPointer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@codecov-commenter
Copy link

codecov-commenter commented Nov 17, 2021

Codecov Report

Merging #3024 (faafaf9) into feature/multi-cluster (d36c406) will increase coverage by 1.15%.
The diff coverage is 65.93%.

Impacted file tree graph

@@                    Coverage Diff                    @@
##           feature/multi-cluster    #3024      +/-   ##
=========================================================
+ Coverage                  39.76%   40.92%   +1.15%     
=========================================================
  Files                        189      188       -1     
  Lines                      21880    22568     +688     
=========================================================
+ Hits                        8701     9236     +535     
- Misses                     12324    12392      +68     
- Partials                     855      940      +85     
Flag Coverage Δ
unit-tests 40.92% <65.93%> (+1.15%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...icluster/cmd/multicluster-controller/controller.go 4.68% <ø> (ø)
multicluster/cmd/multicluster-controller/member.go 0.00% <0.00%> (ø)
...ulticluster/cmd/multicluster-controller/options.go 8.33% <0.00%> (ø)
...llers/multicluster/member_clusterset_controller.go 0.00% <0.00%> (ø)
...s/multicluster/memberclusterannounce_controller.go 66.96% <ø> (ø)
...uster/controllers/multicluster/stale_controller.go 47.19% <47.19%> (ø)
...llers/multicluster/core/fake_remote_common_area.go 61.53% <61.53%> (ø)
...ntrollers/multicluster/serviceexport_controller.go 67.61% <68.15%> (+67.61%) ⬆️
...ers/multicluster/core/resourceimport_controller.go 68.39% <68.39%> (ø)
...trollers/multicluster/resourceexport_controller.go 70.16% <70.61%> (+70.16%) ⬆️
... and 11 more

@luolanzone luolanzone force-pushed the resource-controllers branch 2 times, most recently from be5de9c to 479dfc3 Compare November 17, 2021 07:16
metadata:
name: serviceexports.multicluster.x-k8s.io
spec:
group: multicluster.x-k8s.io
Copy link
Contributor Author

@luolanzone luolanzone Nov 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jianjuns , I am wondering if it's OK to copy serviceexports CRD definition from mcs api repo? or we should move it as own one API group? if we move it to our own group, I think we need to define ServiceExport and ServiceImport objects.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel ok to copy the yaml. Let us see if @tnqn has an opinion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to put these copied yamls in a separate directory?

Copy link
Contributor

@jianjuns jianjuns Dec 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder for the question.

Is it possible to put these copied yamls in a separate directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I was thinking to move it in a separate PR when we rename the core package.

AntreaMcsLabel = "antrea.io/multi-cluster"
AntreaMcsAutoGenLabel = "antrea.io/multi-cluster-autogenerated"
SourceImportLabel = "antrea.io/resource-import-name"
AntreaMCSAutoGenAnnotation = "antrea.io/multi-cluster-autogenerated"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you think about "multicluster.antrea.io/imported-service" and "multicluster.antrea.io/resource-import-name"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, will do.

@@ -209,7 +209,7 @@ func (r *ResourceImportReconciler) handleResImpUpdateForEndpoints(ctx context.Co
r.installedResImports.Add(*resImp)
return ctrl.Result{}, nil
}
if _, ok := ep.Labels[common.AntreaMcsAutoGenLabel]; !ok {
if _, ok := ep.Labels[common.AntreaMCSAutoGenAnnotation]; !ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you done the change to switch from label to annotation, and remove the "multi-cluster" label on exported Services?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, @jianjuns , this is a multi-cluster service created by our own codes, so I suppose it should be ok to add a label?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is ok, but I think you plan to change from label to annotation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you like to use label selector for imported services? But you changed the constant name to AntreaMCSAutoGenAnnotation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, my mistake, I think both label or annotation should work, I will check and move it as annotation if it can filter event based on annotation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you watch with filters? I remember watch can have the apiserver side filter the updates with labels. Not sure about annotation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, there is a standalone service_controller.go to do clean up job in case ResourceImport in leader have been removed but member cluster fail to watch the event eg: mcs controller is down accidentally.
controller-runtime provides a predicate to do the filter. I used it like below in service_controller.go, I think annotation should also work with custom predicate funcs, I will try locally first.

func (r *ServiceReconciler) SetupWithManager(mgr ctrl.Manager) error {
	instance, _ := predicate.LabelSelectorPredicate(metav1.LabelSelector{
		MatchLabels: map[string]string{
			common.AntreaMCSAutoGenAnnotation: "true",
		},
	})
	return ctrl.NewControllerManagedBy(mgr).
		For(&corev1.Service{}).WithEventFilter(instance).
		WithOptions(controller.Options{
			MaxConcurrentReconciles: common.DefaultWorkerCount,
		}).
		Complete(r)
}

@luolanzone luolanzone force-pushed the feature/multi-cluster branch from 9b32acf to f55dbad Compare November 22, 2021 01:41
@luolanzone luolanzone force-pushed the resource-controllers branch 5 times, most recently from 99a9737 to 839a110 Compare November 24, 2021 09:12
Copy link
Contributor

@jianjuns jianjuns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In commit message:

remote_resourceimport_controller watches leader cluster's ResourceImport events and create corresponding

create -> creates

@@ -88,6 +93,11 @@ func run(o *Options) error {
} else {
o.options.CertDir = certDir
}
// TODO: These leader checks should go once we have a separate command for leader and member controller
if o.leader {
// on the leader we want the reconciler to run for a given namspace instead of cluster scope
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

namesapce -> Namespace

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, there are some codes from Aravinda's common area, I will leave it to her to address, then I will do a rebase after that. cc @aravindakidambi

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, Ill address this

// TODO: These leader checks should go once we have a separate command for leader and member controller
if o.leader {
// on the leader we want the reconciler to run for a given namspace instead of cluster scope
o.options.Namespace = env.GetPodNamespace()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question - what will happen if a cluster is both leader and member?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we will provide Namespace based manifests for leader and member, which mean a cluster can run MCS controller both as leader and member at the same time in different Namespace.

setupLog = ctrl.Log.WithName("setup")
validationWebhooks = []string{"antrea-multicluster-validating-webhook-configuration"}
mutationWebhooks = []string{"antrea-multicluster-mutating-webhook-configuration"}
setupLog = ctrl.Log.WithName("setup")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tnqn once asked about using klog. What is the conclusion for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure,we will remove this one @aravindakidambi

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done.

IsMember: o.member,
}
if err = clusterSetReconciler.SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "ClusterSet")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We typically do not long if we return the error (which will be logged by the caller too). Could you check if the error logs are necessary?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will remove them

@@ -202,17 +238,32 @@ func createClients(kubeConfig *rest.Config) (
return client, aggregatorClient, apiExtensionClient, nil
}

func getCAConifg() *certificate.CAConfig {
func getCAConifg(isLeader bool) *certificate.CAConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel it might be better not to call env.GetPodNamespace() everywhere, and so wonder can we call it once in run(), and pass it as a parameter to getCAConfig() and getValidationWebhooks() rather than passing isLeader. No strong opinion. Just for you to consider.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, done.

creationSucceed = true
}

if creationSucceed {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Service is created in this func, but ServiceImport was created earlier, we should return here too, and not check changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

// Update MCS logic here
if _, ok := svc.Annotations[common.AntreaMCServiceAnnotation]; !ok {
klog.InfoS("Service has no desired annotation "+common.AntreaMCServiceAnnotation+", skip update", "service", svcName.String())
return ctrl.Result{}, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is when users manually created a Service with MCS prefix, or they removed the annotation on an imported Service? Should we return an error and retry for either case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, I will check this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add a step to check conflicts and skip creation if there is the same Service with MCS prefix, are you suggesting that we should always return error if this is a service with MCS prefix but no annotation, so admin can correct it manually?

klog.ErrorS(err, "fail to list ResourceExports, retry later")
return newResImport, false, err
}
// when there is only one Service ResourceExport, ResourceImport should reflect the change
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How MCSAPI handles this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they didn't handle this case, MCSAPI repo only create a sample for Service creation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you think we return an error and let controller retry (until conflict is resolved)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this kind conflict can only be handled manually, do you mean this kind of situation should be corrected by admin when they do service export, so we can let controller retry after admin resolve conflict?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, I leave the logic to update ResourceImport when there is only one ResourceExport and for other cases, it will return error. let me know if it's suitable or not.

switch resExport.Spec.Kind {
case common.ServiceKind:
resImport, changed, err = r.refreshServiceResourceImport(&resExport, existResImport, createResImport)
case common.EndpointsKind:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Today we support exporting only the Endpoints directly, but not externalIP of LB type Services? When later we use externalIP or ClusterIP as the Endpoints, ResourceExportReconciler in the leader cluster should create EndpointImport based on the exported Service spec, or ResourceImportReconciler of member clusters should handle that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ResourceExportReconciler should do this part, I will revisit this later how to minimize the change. thanks.

@luolanzone luolanzone force-pushed the resource-controllers branch 3 times, most recently from e76b682 to dff1449 Compare December 1, 2021 09:13
@@ -40,12 +42,12 @@ import (

const (
// cached indexer
resImportIndexerByNameKind = "resourceimport.by.namekind"
resImportIndexer = "resimp.indexer"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit - what you think about "name.kind" or even "nk".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, rename indexer as name.kind

r.installedResImports.Add(*resImp)
if len(svcImpObj.Spec.IPs) == 0 {
// requeue the event to update ServiceImport's ClusterSetIP
return ctrl.Result{}, fmt.Errorf("ServiceImport %s ClusterSetIP is empty", klog.KObj(svcImpObj))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Humm - how long it takes for the retry? Thinking whether we should optimize by watching Services to get the IP faster but I know it is much complexer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the codes, it seems using the default rate limit here https://github.com/kubernetes/client-go/blob/master/util/workqueue/default_rate_limiters.go#L39, interval should be from 5ms to 10s. if multiple failures happened, the interval will be like baseDelay*2^<num-failures>, baseDelay is 5ms, not sure if this kind of interval is enough or not, I will check if I can add more logic in service_controller to watch Service change, then update the IP

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still trying to understand if we need a Service controller or not. If not, could we think about a simpler solution to handle this, like some way to requeue the event after a short interval?

Copy link
Contributor Author

@luolanzone luolanzone Dec 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

service controller only watch those service with mcs annotation, so I suppose it should be OK to have one? I haven't found a valid new way to handle the case when ResourceImport is deleted but event is not handled because of crashed controller in member cluster. I will check if reconciler can run like RunOnce().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jianjuns about requeue for ClusterSetIP setting, when we return empty result with error, the event will actually be requeued, do you mean the interval controlled by default rate limit is not short enough?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is always ms to seconds, that should be good enough.

Copy link
Contributor Author

@luolanzone luolanzone Dec 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jianjuns I removed service_controller and add a standard controller named stale_controller without using kuberbuilder manager framework, it will run only once if no error happens during stale Service/ServiceImport clean up. no unit test code yet, let me know if you have more comments. thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think better to get @tnqn 's suggestion here. Could you check with him?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, I have pinged him directly, let's see if there is comment from @tnqn

@@ -160,25 +174,27 @@ func (r *ResourceImportReconciler) handleResImpUpdateForService(ctx context.Cont
return ctrl.Result{}, err
}
svcImpObj := getMCServiceImport(resImp)
if !reflect.DeepEqual(*svc, corev1.Service{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just check svc.Spec.ClusterIP?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

if creationSucceed {
if svcCreated && svcImpCreated {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check both, or just svcImpCreated? At least for r.installedResImports.Add(*resImp) we should not care about svcCreated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix via check svcImpNotFound only

@@ -143,15 +145,27 @@ func (r *ResourceImportReconciler) handleResImpUpdateForService(ctx context.Cont
if err != nil && !apierrors.IsNotFound(err) {
return ctrl.Result{}, err
}
var creationSucceed bool
mcsObj := getMCSForServiceImport(resImp)
if !reflect.DeepEqual(*svc, corev1.Service{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it to check if the Service exists or not? If so should we just check IsNotFound, or add a bool variable for that (which can replace svcCreated, svcImpCreated).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done via using svcImpNotFound

@@ -247,6 +263,13 @@ func (r *ResourceImportReconciler) handleResImpUpdateForEndpoints(ctx context.Co
if err != nil && !epNotFound {
return ctrl.Result{}, err
}
if !reflect.DeepEqual(*ep, corev1.Endpoints{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just check the Endpoints exists or not?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, reuse epNotFound now

// when there is only one Service ResourceExport, ResourceImport should reflect the change
// otherwise, it should skip it due to it's impossible to determine which one is desired.
// When there is only one Service ResourceExport, ResourceImport should reflect the change
// otherwise, it should always return error so controller can retry later if admin fix the issue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "assuming users can fix the conflicts"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@luolanzone luolanzone changed the title exporter/importer and unit test Resource exporter/importer and unit test Dec 2, 2021
Copy link
Contributor

@jianjuns jianjuns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the commit message of "More stale cleanup and remove unnecessary subset info"

  1. add ResourceExport clean up in stale_controller which handle the case
    add -> Add, handle -> handles

when controller in member crashed and ServiceExport is deleted during
crash.

crached -> restarts?

klog.InfoS("Starting StaleController")
defer klog.InfoS("Shutting down StaleController")

if err := c.RunOnce(); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we should do clean up before other controllers start to run, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only clean up those stale resources, eg, remove MC Service and ServiceImport when corresponding ResourceImport does not existing in leader cluster anymore, so it should be fine to no run before other controllers because other controllers will do nothing for a deleted resource which is already gone before reconciling and no delete event at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking about any possible race condition here, e.g. stalecontroller (as it is not atomic to get imports, services, and delete) deletes new Services?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stale controller will get ServiceList from local first, then ResourceImportList from leader, so it means if new derived Service being created but not in ServiceList, we either have new ResourceImport in ResourceImportList or not have it, in first case Service won't be deleted because there is corresponding ResourceImport, in second case, nothing will be done.

@luolanzone luolanzone force-pushed the resource-controllers branch 2 times, most recently from 8aebad0 to c86cf1a Compare December 15, 2021 02:51
@luolanzone luolanzone force-pushed the resource-controllers branch 2 times, most recently from 0810d08 to 55254ac Compare December 15, 2021 06:00
Copy link
Contributor

@jianjuns jianjuns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly on formatting.

@@ -1079,6 +1079,217 @@ status:
conditions: []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel we should rename this yml to antrea-multicluster-member.yml. Not necessarily in this PR though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I think we can do this rename and move copied yaml to different directory in a new PR.

metadata:
name: serviceexports.multicluster.x-k8s.io
spec:
group: multicluster.x-k8s.io
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to put these copied yamls in a separate directory?

multicluster/controllers/multicluster/common/helper.go Outdated Show resolved Hide resolved
multicluster/controllers/multicluster/common/helper.go Outdated Show resolved Hide resolved
@luolanzone luolanzone force-pushed the resource-controllers branch 3 times, most recently from d450c75 to e6ff1e9 Compare December 17, 2021 02:14
}
if !svcNotFound {
// Here we will skip creating derived MC Service when a Service with the same name
// is already exists but not previously created by Importer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is already exists -> already exists but is not

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

metadata:
name: serviceexports.multicluster.x-k8s.io
spec:
group: multicluster.x-k8s.io
Copy link
Contributor

@jianjuns jianjuns Dec 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder for the question.

Is it possible to put these copied yamls in a separate directory?

"service", svcImpName.String(), "resourceimport", klog.KObj(resImp))

var err error
cleanup_serviceimport := func() (ctrl.Result, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleanupServiceImport

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -99,7 +99,7 @@ func (r *MemberClusterSetReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel common_area.go in commonarea pkg is not a problem. But would let you decide the appropriate naming here. "core" might be too general and not accurate here.

client.Client
Scheme *runtime.Scheme
type (
// ResourceExportReconciler reconciles a ResourceExport object
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, probably we can move the comment here, like "ResourceExportReconciler reconciles ResourceExports in leader cluster"?


func (r *ResourceExportReconciler) handleDeleteEvent(ctx context.Context, resImportName types.NamespacedName, resExport *mcsv1alpha1.ResourceExport) error {
reList := &mcsv1alpha1.ResourceExportList{}
err := r.Client.List(ctx, reList, &client.ListOptions{LabelSelector: getLabelSelector(resExport)})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thought we can just remove endpoints from the ResourceImport. Not sure that is a better strategy or not.

But could you add some comments?

return ctrl.Result{}, err
}

resImportName := types.NamespacedName{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor suggestion - might be simpler if getResourceImportName() returns a NamespacedName.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, refined it.

)

var (
leaderNamespace string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not mean we must create a new struct to hold these variables, but meant for OO better not to use global variables. I saw you change to pass clusterConfig as func arguments, but originally I was thinking can they be members of ServiceExportReconciler.

)

// TODO: Use NamespacedName stringer method instead of this. e.g. nsName.String()
func NamespacedName(namespace, name string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

namespace -> Namespace

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this one is my mistake. It should be "namespace" indeed.

@luolanzone
Copy link
Contributor Author

Hi @jianjuns @aravindakidambi I have created a separate PR #3153 to rename core package and move
ServiceExport and ServiceImport CRD manifest to a new forlder. please help to take a look. thanks

Copy link
Contributor

@jianjuns jianjuns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

)

// TODO: Use NamespacedName stringer method instead of this. e.g. nsName.String()
func NamespacedName(Namespace, name string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this one is my mistake. It should be "namespace" indeed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
@luolanzone
Copy link
Contributor Author

Hi @jianjuns I fixed the last comment in this PR, Could you help to approve this if it looks good to you? I will rebase the PR#3153 and address your comments on it.

@luolanzone luolanzone merged commit f9e5f48 into antrea-io:feature/multi-cluster Dec 22, 2021
luolanzone added a commit to luolanzone/antrea that referenced this pull request Dec 22, 2021
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
luolanzone added a commit to luolanzone/antrea that referenced this pull request Jan 16, 2022
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
luolanzone added a commit to luolanzone/antrea that referenced this pull request Jan 18, 2022
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
luolanzone added a commit to luolanzone/antrea that referenced this pull request Jan 18, 2022
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
luolanzone added a commit to luolanzone/antrea that referenced this pull request Jan 19, 2022
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
luolanzone added a commit that referenced this pull request Jan 19, 2022
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
luolanzone added a commit to luolanzone/antrea that referenced this pull request Jan 20, 2022
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
luolanzone added a commit to luolanzone/antrea that referenced this pull request Jan 20, 2022
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
yanjunz97 pushed a commit to yanjunz97/antrea that referenced this pull request Feb 14, 2022
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.

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.

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.

Notes: serviceexport_controller, stale_controller and
resourceimport_controller will run only in member cluster,
resourceexport_controller will run only in leader cluster.

Signed-off-by: Lan Luo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/multi-cluster Issues or PRs related to multi cluster.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants