First: the patchesJson6902
directive has been deprecated; you should simply be using patches
.
With respect to your question, when you include a base kustomization in the resources
section of your kustomization.yaml
, kustomize neither knows or cares that the base used patches: the patches in your local kustomization.yaml
are simply applied to whatever manifests are generated by your resources
section (and config/secret generators, etc).
So for example if we have this layout:
.
├── base
│ ├── ingress.yaml
│ ├── kustomization.yaml
│ └── set-ingressclass-patch.yaml
└── overlay
├── kustomization.yaml
└── set-ingress-tls-patch.yaml
And the following files:
base/ingress.yaml
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
spec:
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example
port:
name: http
base/set-ingressclass-patch.yaml
:
- path: /metadata/annotations
op: add
value:
kubernetes.io/ingress.class: nginx
base/kustomization.yaml
:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
app: example
resources:
- ingress.yaml
patches:
- target:
kind: Ingress
name: example
path: set-ingressclass-patch.yaml
overlay/set-ingress-tls-patch.yaml
:
- path: /metadata/annotations/cert-manager.io~1cluster-issuer
op: add
value: my_issuer
- path: /spec/tls
op: add
value:
- hosts:
- www.example.com
secretName: example-cert
overlay/kustomization.yaml
:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- target:
kind: Ingress
name: example
path: set-ingress-tls-patch.yaml
Then running kustomize build base
produces:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
labels:
app: example
name: example
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
service:
name: example
port:
name: http
path: /
pathType: Prefix
And running kustomize build overlay
produces:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: my_issuer
kubernetes.io/ingress.class: nginx
labels:
app: example
name: example
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
service:
name: example
port:
name: http
path: /
pathType: Prefix
tls:
- hosts:
- www.example.com
secretName: example-cert
Here we can see that the output of the second kustomize build
commands takes the manifests produced by base
-- which include the patch that sets the ingress class -- and applies the patches in overlay/set-ingress-tls-patch.yaml
.
You didn't show examples of your patches, so it's hard to tell what's actually going on, but I have a theory. Let's take a closer look at the patches in this example.
The manifest base/ingress.yaml
doesn't have an metadata.annotations
section. Our patch...
- path: /metadata/annotations
op: add
value:
kubernetes.io/ingress.class: nginx
...creates the annotations
key and content. But when we apply patches in the overlay, the Ingress resource already has an annotations
section. If we had written overlay/set-ingress-tls-patch.yaml
like this:
- path: /metadata/annotations
op: add
value:
cert-manager.io/cluster-issuer: my_issuer
That would have replaced the annotations
key with a new value! The resulting manifest would look like:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: my_issuer
labels:
app: example
name: example
spec:
...
But we don't want to replace the annotations
section; we want to add a new key. So instead our patch looks like:
- path: /metadata/annotations/cert-manager.io~1cluster-issuer
op: add
value: my_issuer
This is adding a new key under annotations
, rather than replacing the entire annotations
key. The pattern ~1
is how you escape a forward slash in a JSON pointer expression.
The above all works, but I using strategic merge patches would be simpler and more obvious. In that case, base/set-ingressclass-patch.yaml
would look like:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: example
And base/set-ingress-tls-patch.yaml
would look like:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: my_issuer
name: example
spec:
tls:
- hosts:
- www.example.com
secretName: example-cert
Using this style of patch, you don't need to set a target
in your kustomization.yaml
because the target is implied by the kind
and metadata.name
in the patch. E.g., base/kustomization.yaml
would look like:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
app: example
resources:
- ingress.yaml
patches:
- path: set-ingressclass-patch.yaml
I think that's easier to understand than the JSONPatch style patches, but that's a matter of opinion and as we've demonstrated here either will work.