The problem with mutated fields Link to heading

Having kubernetes resources that do not sync is a common problem when dealing with a continuos delivery system such as ArgoCD and external components that change those resources.

What happens is:

  • the CD system applies a change based on some configuration
  • the change is overridden by some controller
  • the CD system sees a difference between the observed state and the desired state (the mutation from the step above)

and this goes on forever, unless the CD system is instructed to ignore the differences.

We hit this issue in MetalLB, where we inject the caBundle in the CRDs to make the conversion webhooks work.

Setting the field manager Link to heading

By declaring the manager of a given field, we can instruct the CD system that it shouldn’t care about some fields because they are handled by something else (see the official docs).

Understanding the Field Manager in Controller Runtime Link to heading

The controller runtime is my go to framework when I need to write a kubernetes controller. It offers a very convenient way to set the field manager when updating an object:

    cli.Update(context.TODO(), toUpdate, client.FieldOwner("foo"))

By doing this, the server side will set the field owner and the CD system will be able to understand the change has to be ignored.

Verifying everything works Link to heading

This is the major reason why I am writing this post, and the cause making this work took so much of my time (and I almost gave up).

Turns out that kubectl has a --show-managed-fields flag to set when checking a given resource. Without that, those fields will be hidden in the output to avoid bloating the yaml!

Wrapping up Link to heading

I hope this post may help whoever is looking to set the fieldmanager of a given resource using the controller-runtime, because it took a considerable amount of my time (compared to the final, one liner solution).