I'm trying to selectively apply a patch based on target:namespace, but it isn't working.
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
patches:
- path: deployment-imagepullpolicy-prod.json
target:
kind: Deployment
namespace: prod
# base/kustomization.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
spec:
containers:
- name: app
imagePullPolicy: Always
# base/deployment-imagepullpolicy-prod.json
[
{
"op": "replace",
"path": "/spec/template/spec/containers/0/imagePullPolicy",
"value": "IfNotPresent"
}
]
# app/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base
namespace: prod
When I generate resources ( kubectl kustomize app
) the patch isn't there. If target:namespace restriction is removed then it works.
Based on @larks answer, I made some tests.
First, my use case: I have a bunch of apps overlays with environment overlays inside it, we use Always
image pull policy as default but we need that prod environment use ifNotPresent
policy. Today we do this with patchesStrategicMerge
, but this approach is subject to human failures, so a selective patch that will be applied to any new app created, without human interaction, would be great.
Now, the tests:
Any patches in your base
directory need to operate correctly when you run kustomize
in base
. Because you're not setting namespace: prod
in base
, that patch will never work.
Even if you move the patch into your app
overlay, it won't work the way you're currently using it because patches are applied before the namespace
directive in your kustomization.yaml
, so the namespace: prod
condition is never going to match.
However, I would argue this arrangement doesn't make sense: just use different overlays for different namespaces.
In this case, I think the solution is to move the patch into the app
overlay and remove the namespace: prod
condition, so that you have this layout:
.
├── app
│ ├── deployment-imagepullpolicy-prod.json
│ └── kustomization.yaml
└── base
├── deployment.yaml
└── kustomization.yaml
And app/kustomization.yaml
looks like:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base
namespace: prod
patches:
- path: deployment-imagepullpolicy-prod.json
target:
kind: Deployment
namespace: prod
Update
Kustomize creates a pipeline. When you write something like:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base
namespace: prod
That means, effectively:
kustomize
in ../base
So any patches in your base
directory need to apply when you run kustomize
in the base
directory . Your patch, as you've currently written, doesn't apply to any resources in base
, so it's effectively a no-op.
The only way to apply that patch is to move it into the app
overlay and remove the namespace
condition. Because you're setting namespace: prod
in app/kustomization.yaml
, using a namespace
condition on the patch doesn't make any sense: all your resources are going to have namespace: prod
, so there's no point to the condition.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.