Kustomize: extend patch from one target to multiple targets

Created on 24 Jan 2019  路  27Comments  路  Source: kubernetes-sigs/kustomize

Currently, there are different types of patches supported in Kustomize: strategic merge patch and JSON patch.

patchesStrategicMerge:
- service_port_8888.yaml
- deployment_increase_replicas.yaml
- deployment_increase_memory.yaml

patchesJson6902:
- target:
    version: v1
    kind: Deployment
    name: my-deployment
  path: add_init_container.yaml
- target:
    version: v1
    kind: Service
    name: my-service
  path: add_service_annotation.yaml

Both types need GVKN info to find the unique target to perform the patching. In strategic merge patch, GVKN is included in the patch itself. In JSON patch, the GVKN is specified in kustomization.yaml.

We have seen requests for patching multiple targets by one patch: #409, #412, #567.
The use cases related to those requests include but not limit to

  • override one field for all objects of one type
  • add or remove common command arguments for all containers
  • inject a sidecar proxy as in istio to all containers

We need to figure out the scope of extending the patches and investigate the trade-off among different approaches. Here are some questions to think about

  • Will the extension be only for JSON patch or all types of patches?
  • What is the best way of specifying multiple targets? by label selector, regex matching in names, filter by kind or else?
kinfeature

Most helpful comment

add or remove common command arguments for all containers

How do I make a patch that applies to all of the containers in a deployment with this feature?
I could not any example except one that adds a container to the all of deployment

All 27 comments

/cc @monopole @pwittrock

This is one I've recently ran into when trying to adapt kustomize. JSON Patch helps in some cases but in others it doesn't work. For example, adding to an existing list of initContainers is possible, but if the resource does not have the initContainers configuration then the patch fails to apply.

We really like the idea of being able to apply a single patch to many different resources without needing to alter the resources themselves.

This issue also sounds like it might be similar to https://github.com/kubernetes-sigs/kustomize/issues/627 (at least somewhat)

May also include a related request #824

Is it already work in progress? @Liujingfang1

Open a KEP for this request: kubernetes/enhancements#897

Is it possible to have the PR approved to test this new feature?

This is not started yet. We recently added support for generator and transformer plugins.
Patching multiple targets by one patch can be done through a transformer plugin.

@Liujingfang1 Is there somewhere docs on how to this or some examples?

Another possible use case might be updating/appending labels, like the ones recommended at https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/

@mkobit you can use commonLabels for that.

In case anyone is interested, we've implemented StrategicMergePatch from https://github.com/kubernetes/enhancements/pull/897 as a plugin: https://github.com/sourceability/kustomize-plugins

We plan to implement this feature. Any one who is interested in it is welcome to contribute. Here are the tasks that we can break this feature into.

  • [x] Add types for the extended patches
  • [x] Implement the functionality of getting the set of targets by

    • [x] group, version, kind, name, (The name can be regexp)

    • [x] annotations

    • [x] lables

    • [x] the intersection of all these three

  • [x] Implement the functionality of detecting the type of patches based on content
    either a strategic merge patch or a json merge patch
  • [x] write a new builtin transformer to handle the extended patches type
  • [x] Inside this transformer, based on the type of patch, call either SMP transformer
    or PatchJSON6902 transformer
  • [ ] add logic to make sure there is no conflict among different patches
  • [x] add tests
  • [x] docs and examples

@adrienbrault Do you want to contribute to this feature? We can write a new builtin transformer for it. I listed the steps above.

Also include the feature request from #1157

@Liujingfang1 Sure! I'll try to open a PR next week/in the next few weeks.

All the tasks are done except detecting conflict. We'll address it separately if needed.

@Liujingfang1 Started trying out those features last week with the latest release, it's working great so far! Thank you!

I'm excited that this feature has been implemented, but it's not clear to me how to use it. I get an error message when trying to apply a patch to multiple deployments:

% kustomize version
Version: {KustomizeVersion:3.1.0 GitCommit:95f3303493fdea243ae83b767978092396169baf BuildDate:2019-07-26T18:11:16Z GoOs:linux GoArch:amd64}
% kustomize build .
Error: builtin patch config: [112 97 116 104 58 32 114 101 97 100 121 46 121 97 109 108 10 116 97 114 103 101 116 58 10 32 32 107 105 110 100 58 32 68 101 112 108 111 121 109 101 110 116 10]: unable to get either a Strategic Merge Patch or JSON patch 6902 from 

kustomization.yaml

resources:
- deployment.yaml
patches:
- path: ready.yaml
  target:
    kind: Deployment

ready.yaml

kind: Deployment
spec:
  minReadySeconds: 120

deployment.yaml

kind: Deployment
metadata:
  name: first
spec:
  template:
    spec:
      containers:
      - name: app
        command:
        - true
---
kind: Deployment
metadata:
  name: second
spec:
  template:
    spec:
      containers:
      - name: app
        command:
        - true

@Liujingfang1 Just tested this feature in a project that was halted waiting for it, it worked wonderfully! Thanks to you and all involved! Saved me a lot of redundant projects just to change some environment values!

@keithkml You need to have apiVersion and metadata.name in the patch file. Otherwise, it can't be loaded as a strategic merge patch.

Is this feature gone? I'm on the latest version of kustomize but am not be able to use this due to an error.

unable to get either a Strategic Merge Patch or JSON patch 6902 from

If necessary, I will create a new issue

@leroy0211 Try adding kind and metadata.name fields in your patch file if you haven't and then try. This is what I could figure out from multiple tests using kustomize v3.4.0

add or remove common command arguments for all containers

How do I make a patch that applies to all of the containers in a deployment with this feature?
I could not any example except one that adds a container to the all of deployment

add or remove common command arguments for all containers

How do I make a patch that applies to _all of the containers_ in a deployment with this feature?
I could not any example except one that adds a container to the all of deployment

Just to give a (i thought common) use case: We are using minikube for local development and mount our sourcecode into the pod so that we do not have to rebuild the docker image and restart the pod everytime we change code. So we need to mount volumes for the minikube environment but not for test and production. Creating a patch for every container is not pretty appropriate.

To summarize the problem I like to solve: I can only patch CRD dynamically via patches which does not support patching the container definition because the name must match. Using the patchesJson6902 I could access a specific container definition (path:/spec/job/template/containers/0) but that does not help either because a target resource name for the patch must be specified.

May also include a related request #824

Was this use case addressed?

It looks like there's still no way to apply the same strategic merge patch to multiple target resources. Was that desire supposed to be addressed here?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yujunz picture yujunz  路  5Comments

natasha41575 picture natasha41575  路  3Comments

lionelvillard picture lionelvillard  路  4Comments

mgoodness picture mgoodness  路  4Comments

karlmutch picture karlmutch  路  5Comments