简体   繁体   中英

Kustomize patch with target namespace

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:

  1. Moving patch to overlay that defines namespace (app).
    It doesn't work, and it is useless as namespace is defined where I need the patch.
    So just apply the patch without restriction, making namespace restriction useless.
  2. Moving namespace to base overlay.
    It doesn't work, patch and namespace defined in same overlay do not apply patch.
    So just apply the patch without restriction, making namespace restriction useless.
  3. Moving namespace to base overlay and patch to app overlay.
    It works, but its' useless as patch will be applied to all overlays that inherit it. Trying to redefine namespace on app overlay do not works.
    So just apply the patch without restriction, making namespace restriction useless.

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:

  1. First, run kustomize in ../base
  2. Apply any transformations defined in the current overlay

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM