-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
What broke? What's expected?
The scaffolding produces the following kustomizeconfig.yaml:
# the following config is for teaching kustomize where to look at when substituting nameReference.
# It requires kustomize v2.1.0 or newer to work properly.
nameReference:
- kind: Service
version: v1
fieldSpecs:
- kind: MutatingWebhookConfiguration
group: admissionregistration.k8s.io
path: webhooks/clientConfig/service/name
- kind: ValidatingWebhookConfiguration
group: admissionregistration.k8s.io
path: webhooks/clientConfig/service/name
namespace:
- kind: MutatingWebhookConfiguration
group: admissionregistration.k8s.io
path: webhooks/clientConfig/service/namespace
create: true
- kind: ValidatingWebhookConfiguration
group: admissionregistration.k8s.io
path: webhooks/clientConfig/service/namespace
create: trueIn this configuration, nameReference is redundant, and namespace is incorrect. This configuration can be safely removed entirely. This will:
- Have no effect when building
config/defaultdirectly, because it is redundant - Fix the bug described below when using this kustomize as a base.
The nameReference is redundant because it's already present in kustomize's default configuration:
- kind: Service
version: v1
fieldSpecs:
- path: spec/serviceName
kind: StatefulSet
group: apps
- path: spec/rules/http/paths/backend/serviceName
kind: Ingress
- path: spec/backend/serviceName
kind: Ingress
- path: spec/rules/http/paths/backend/service/name
kind: Ingress
- path: spec/defaultBackend/service/name
kind: Ingress
- path: spec/service/name
kind: APIService
group: apiregistration.k8s.io
- path: webhooks/clientConfig/service
kind: ValidatingWebhookConfiguration
group: admissionregistration.k8s.io
- path: webhooks/clientConfig/service
kind: MutatingWebhookConfiguration
group: admissionregistration.k8s.ioThis is doing nothing and can just be removed.
With the caveat that I am not a kustomize developer, just some rando who spent way too many hours trying to work out what was going on in a complex unfamiliar codebase:
The namespace directive is subtly wrong. The issue here is that the purpose of the namespace transformer is to directly set the namespace of objects, not to update the namespace in references to those objects. References are defined by the nameReference configuration. One of the last things kustomize will do in its pipeline is FixBackReferences(), which fixes up references to objects which have been modified by a transformer. The problem is that because we configured the namespace transformer to write directly to the reference, the internal state of this tracking is now wrong. This means (IIUC) that webhooks/clientConfig/service/namespace is updated by the namespace transformer, not by FixBackReferences which would have updated it anyway because we modified the Service object it
But the end result is the same, so why does this matter?
If you use this kustomization as a base for an overlay that performs a second transformation on the Service object, because the internal state is now incorrect the reference will not be updated.
I have submitted the following PRs related to this issue in projects which are based on kubebuilder scaffolding from a variety of versions over many years:
- Remove invalid kustomizeconfig from config/webhook cluster-api-provider-azure#5982
- 🐛 Remove invalid kustomizeconfig from config/webhook cluster-api-provider-aws#5759
- Remove invalid kustomizeconfig from config/webhook cluster-api-provider-gcp#1565
- 🐛 Remove invalid kustomizeconfig from config/webhook cluster-api-provider-openstack#2850
- Remove invalid kustomizeconfig from config/webhook cluster-api-provider-ibmcloud#2541
- 🐛 Remove invalid kustomizeconfig cluster-api-provider-vsphere#3685
- 🐛 Remove invalid kustomizeconfig from config/webhook metal3-io/cluster-api-provider-metal3#2959
Reproducing this issue
Build kubebuilder from source. I used commit c169977, but given the number of CAPI providers I just posted PRs for this issue has been around for years.
$ ../bin/kubebuilder init --domain example.com --repo github.com/example/test
$ ../bin/kubebuilder create api --group foo --version v1 --kind Foo
$ ../bin/kubebuilder create webhook --group foo --version v1 --kind Foo --defaulting
Note that config/webhook contains the offending kustomiseconfig.yaml.
An overlay which produces incorrect output due to this:
Create the following kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- /path/to/any/kubebuilder/config/default
transformers:
- |
apiVersion: builtin
kind: NamespaceTransformer
metadata:
name: set-namespaces
namespace: example-new-namespaceThis is invoking the namespace transformer as an external transformer for... reasons. This is sometimes useful. Incidentally this does not manifest when invoking the namespace transformer via the builtin namespace directive (although it is the same transformer in both cases). I didn't get all the way to the bottom of this, but it appears to relate to a difference on ordering of how they are applied.
Inspect the output of kustomize build. Note that while the Service object's namespace has been correctly updated, the reference to it in MutatingWebhookConfiguration has not: it is still whatever it was directly transformed to by the builtin namespace directive.
Now remove the offending kustomizeconfig.yaml. You can just comment it out in config/webhook/kustomization.yaml. Note that the output is now correct. It is correct:
- When building
config/defaultdirectly - i.e. the configuration was redundant in any case - When transforming the Service object a second time in an overlay
KubeBuilder (CLI) Version
Version: cmd.version{KubeBuilderVersion:"v4.10.1-20-gc16997712", KubernetesVendor:"1.34.1", GitCommit:"c1699771232235a0890c270957e1a866b033aabe", BuildDate:"2025-11-21T13:56:26Z", GoOs:"linux", GoArch:"amd64"}
PROJECT version
3, 2
Plugin versions
Other versions
No response
Extra Labels
No response