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

Update finalizer of ResourceExport to be domain-qualified #6742

Merged
merged 1 commit into from
Oct 22, 2024

Conversation

Dyanngg
Copy link
Contributor

@Dyanngg Dyanngg commented Oct 14, 2024

Fixes #6741

multicluster/apis/multicluster/constants/constants.go Outdated Show resolved Hide resolved
// Note for ResourceExports created before Antrea v2.2, LegacyResourceExportFinalizer may still be present
// and needs to be removed before a ResourceExport is deleted.
if r.DeletionTimestamp.IsZero() && !stringExistsInSlice(r.Finalizers, constants.DomainQualifiedResourceExportFinalizer) {
r.Finalizers = append(r.Finalizers, constants.DomainQualifiedResourceExportFinalizer)
Copy link
Contributor

Choose a reason for hiding this comment

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

Obviously this predates this PR, but I am surprised to see a webhook being in charge of adding the finalizer. Is there a recommendation to do that somewhere? I usually see it done in the controller itself (Reconcile). cc @luolanzone

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @antoninbas I think the Finalizer is not necessarily handled by the reconciler. If I recall it correctly, the main purpose is to stop deleting the ResourceExport during creation, because if it's already converted by the leader controller into ResourceImport, there will be no way to clean up the corresponding info in the ResourceImport when the ResourceExport is deleted by the user.

@@ -101,7 +101,7 @@ func (r *ResourceExportReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// clean up any replicated resources like ResourceImport.
// For more details about using Finalizers, please refer to https://book.kubebuilder.io/reference/using-finalizers.html.
if !resExport.DeletionTimestamp.IsZero() {
if common.StringExistsInSlice(resExport.Finalizers, constants.ResourceExportFinalizer) {
if common.AnyExistsInSlice(resExport.Finalizers, []string{constants.LegacyResourceExportFinalizer, constants.DomainQualifiedResourceExportFinalizer}) {
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 not sure, but would it make sense to update the finalizer as part of the Reconcile (we could do it earlier in the function), so that:

  1. the legacy finalizer can be updated to the new one whenever an object is reconciled, reducing the possibility of the legacy finalizer "sticking around"
  2. the rest of the code only needs to worry about the new finalizer

cc @luolanzone

Copy link
Contributor

Choose a reason for hiding this comment

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

@antoninbas do you mean to update the Finalizer to the new one in the reconcile? I think we can't guarantee the Finalizer can be updated for all ResourceExports before deletion, we still need to handle the case that both legacy and new one are in the ClusterSet. And this may lead a conflict that one reconciler is updating the Finalizer but another one is deleting it. So I feel we should have only one place to add the Finalizer.

Copy link
Contributor

@antoninbas antoninbas Oct 15, 2024

Choose a reason for hiding this comment

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

finalizers are usually handled by the controller that owns the resource (that includes adding the finalizer but also processing the finalizer and removing the finalizer), so I am not sure I understand both of your points:

I think we can't guarantee the Finalizer can be updated for all ResourceExports before deletion

And this may lead a conflict that one reconciler is updating the Finalizer but another one is deleting it

Do we have more than one controller / reconciler responsible for the finalizer, or using the finalizer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we have more than one controller / reconciler responsible for the finalizer, or using the finalizer?

I'll try to put my understanding of it here as best as I can, using Service as example:

  1. End users can create a ServiceExport in member clusters. A controller in member cluster [a] will try to create a ResourceExport for this object in the leader cluster. This is currently when a finalizer is put on the resource.
  2. End users can also delete that ServiceExport in member cluster. That controller [a] is also responsible for deleting the ResourceExport in the leader cluster.
  3. A controller [b] in the leader cluster watches for ResourceExports in its own cluster, and reconciles them (by creating corresponding ResourceImports). When it sees an ResourceExport being deleted, it performs necessary cleanups regarding ResourceImports, and then removes the finalizers on ResourceExport and allows it to be deleted.

So if we treat controller [a] solely as a client, not a controller/reconciler, then it's pretty clear that controller [b] actually "owns" ResourceExports. I think @antoninbas's suggestion would actually make sense here:

  1. If we have controller [b] put up finalizers for ResourceExports at the beginning of Reconciles (and making sure the finalizer is set before dealing with ResourceImport logics), then allowing client [a] to create-delete ResourceExports in short succession is actually fine: the leader cluster has not even processed the event yet, so there will not be dangling ResourceImports that contains information of that deleted ResourceExport.
  2. Even if there are ResourceImports in the leader cluster for the same named Service, it will only contain endpoints from ResourceExport created by another member cluster, which would actually have finalizers on it.

In other words, we change the logic to, we add a finalizer to ResourceExports only when we know there are going to be side-effects in the leader cluster, not when the resource is created at apiserver

Copy link
Contributor Author

Choose a reason for hiding this comment

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

However @antoninbas do you think this change warrants a separate PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

finalizers are usually handled by the controller that owns the resource (that includes adding the finalizer but also processing the finalizer and removing the finalizer), so I am not sure I understand both of your points:

I think we can't guarantee the Finalizer can be updated for all ResourceExports before deletion

And this may lead a conflict that one reconciler is updating the Finalizer but another one is deleting it

Do we have more than one controller / reconciler responsible for the finalizer, or using the finalizer?

At the moment, we have the webhook in the leader and the *Exporter controllers in the member cluster to add the Finalizer during ResourceExport creation, the reconciler itself in the leader will remove the Finalizer. The Finalizer in the webhook is a special one for AntreaClusterNetworkPolicyKind since it will be created by the end user if I recall it correctly. The original purpose is to stop the side-affect when the user or "the controller [a]" in the scenario mentioned by @Dyanngg delete the ResourceExport and leads to some dangling ResourceImports.
But you are right, it should be more clear if we can move all Finalizer operations to the leader controller, @Dyanngg could you help to double check and move forward? I think we may need a seperate PR for the change. Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, we can handle this in a future PR

@luolanzone luolanzone added the area/multi-cluster Issues or PRs related to multi cluster. label Oct 15, 2024
@luolanzone
Copy link
Contributor

/test-multicluster-e2e

1 similar comment
@XinShuYang
Copy link
Contributor

/test-multicluster-e2e

@luolanzone
Copy link
Contributor

/test-multicluster-e2e

1 similar comment
@luolanzone
Copy link
Contributor

/test-multicluster-e2e

Copy link
Contributor

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

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

LGTM

@Dyanngg
Copy link
Contributor Author

Dyanngg commented Oct 17, 2024

/test-all /test-multicluster-e2e

antoninbas
antoninbas previously approved these changes Oct 17, 2024
Copy link
Contributor

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

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

LGTM

@Dyanngg
Copy link
Contributor Author

Dyanngg commented Oct 17, 2024

/test-all /test-multicluster-e2e

@Dyanngg
Copy link
Contributor Author

Dyanngg commented Oct 17, 2024

/test-multicluster-e2e

Copy link
Contributor

@luolanzone luolanzone left a comment

Choose a reason for hiding this comment

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

LGTM

@Dyanngg
Copy link
Contributor Author

Dyanngg commented Oct 21, 2024

/test-multicluster-e2e All tests were passing before addressing the last comment

@antoninbas
Copy link
Contributor

We should probably mention this in the release notes, so I'm adding the label for this

@antoninbas antoninbas added the action/release-note Indicates a PR that should be included in release notes. label Oct 22, 2024
@antoninbas antoninbas merged commit 5062aae into antrea-io:main Oct 22, 2024
52 of 59 checks passed
@Dyanngg Dyanngg deleted the fix-mc-finalizers branch October 22, 2024 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action/release-note Indicates a PR that should be included in release notes. area/multi-cluster Issues or PRs related to multi cluster.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ResourceExport should use "domain-qualified" finalizers to conform to K8s requirements
4 participants