Change:
newInitializers: &metav1.Initializers{Pending: []metav1.Initializer{{Name: "init.k8s.io"}}}, err:             "field is immutable once initialization has completed", }, <ins> { name:            "empty initializer list is treated as nil initializer", oldInitializers: nil, newInitializers: &metav1.Initializers{}, verifyUpdatedObj: func(obj runtime.Object) (bool, string) { accessor, err := meta.Accessor(obj) if err != nil { return false, "cannot get accessor" } if accessor.GetInitializers() != nil { return false, "expect nil initializers" } return true, "" }, err: "", }, </ins> } plugin := initializer{

Discussion:
(SEE UPDATE at ) Currently, if you're writing an initializer controller, you're most likely using it to initialize a and deploying the controller with . Therefore you're likely using the following trick to avoid the chicken and egg problem: This bypasses the initializers for the pods and lets your controller to be deployed even though your InitializerConfiguration is configured to capture all pods. Problem occurs when you apply an update to this Deployment with the same manifest containing empty pending list. You get error: I think this is a somewhat major UX issue. It requires users to deploy the initializer controller with the but later on when they need to update the controller with , they can't use the same manifest containing the empty list. /area api /area extensibility /sig api-machinery /kind bug /assign
/cc
We silently ignore some metadata updates, which is one option. Potentially we shouldn't require empty initializers pending, but simply empty initializers (which means - init directly), and only ignore that. Are there any examples of use of SMP for similar? I'm not sure this meets the bar for 1.8 but if we can find an example of something consistent already in the API I'd be willing to review.
I don't have any concrete examples, there's an example initializer at making use the trick, I use it myself, and I suspect many more initializers to come will use this, too. I'm not sure if this would work, but does setting provide a way to skip initialization (if possible at all)? If not, we might actually need a separate field to signal skipping initialization.
/cc
Currently the initializer plugin to on UPDATE, but that happens after it updating already initialized objects. We can simply change their order.
I'd like to amend the issue, it's more serious than I thought. (thanks for bringing it to my attention If you're deploying your Initializer with and if you have an initializerconfiguration for objects, it's impossible to deploy your initializer in the first place without deleting InitializerConfiguration first: is not inherited by the created on is not honored (this field is not propagated to the created Pod). I think (2) should be fixed somehow, otherwise there will be no way of writing an initializer for Pods and deploying the initializer itself using Deployment/ReplicaSet/RC without deleting the InitializerConfiguration first.

Maybe what we need is an exclusion/exemption selector (or namespace(s)) as discussed in to allow deployment of Initializers themselves easier.
For 1, see I don't want to pursue that though, because i) we'll need to fix workload controllers one by one, and ii) we need to carefully consider permission issues. I think we should focus on adding the namespace selector.