kubernetes / client-go

Go client for Kubernetes.
Apache License 2.0
8.78k stars 2.9k forks source link

Server-Side Apply: ExtractPod should specify `UID` #1346

Open gnuletik opened 2 months ago

gnuletik commented 2 months ago

TLDR

When using server side apply with ExtractPod, a controller may recreate a resource that was deleted by attempting to remove a finalizer.

Context

I have a controller that watches pods to remove finalizer using Server-Side Apply (to avoid race condition between controllers as suggested here).

It removes the finalizer in the following way:

podApplyConfig, err := coreac.ExtractPod(pod, fm)
if err != nil {
        return fmt.Errorf("coreac.ExtractPod: %w", err)
}

// updating something
podApplyConfig.Finalizers = nil

_, err = w.client.CoreV1().Pods(ns).Apply(ctx, podApplyConfig, meta.ApplyOptions{FieldManager: smtg})
if err != nil {
        return fmt.Errorf("client.Apply: %w", err)
}

The SharedInformer sometimes sends the event multiple times, which leads to pod being recreated after deletion, given this scenario:

Fix

Kubernetes specs specify that:

Create is blocked on apply if uid is provided link

See KEPS

We can manually call podApply := podApply.WithUID(pod.UID) to workaround this.

However, I think that it would be better that ExtractPod (and similar method for other resources) sets the UID before returning it.

https://github.com/kubernetes/client-go/blob/aa7909e7d7c0661792ba21b9e882f3cd6ad0ce53/applyconfigurations/core/v1/pod.go#L72-L84

WDYT?

I can make a PR if that sounds good to you. However, this part of the codebase seems to be generated, so I'd need a hint on where to edit that.

Thanks!