Kustomize: Document strategic merge patch with examples

Created on 30 Aug 2018  Â·  23Comments  Â·  Source: kubernetes-sigs/kustomize

E.g. changing a service port. We should have concrete examples for each operation (delete, replace, merge, etc.)

We don't call our clearly enough that this is how the existing patch directive works, and don't even have a ptr to the canonical doc.
This is even more important given that #169 is introducing an alternative patch method.

kindocumentation lifecyclfrozen prioritimportant-longterm triagaccepted

Most helpful comment

I have no idea how to specify strategic merge in the customization.

All 23 comments

I have no idea how to specify strategic merge in the customization.

Need to document that patches for custome resources are treated as JSON merge patch. #742

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

This shouldn't be marked as stale afaics

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle rotten

/remove-lifecycle rotten

so where is the $patch thing documented? will it be deprecated?

I am also struggling to understand how to use $patch or even whether this is supported (I can't get it to work).

I want to use strategic merge to add a new path to an existing ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - $patch: merge
  - http:
      paths:
      - path: /demo
        backend:
          serviceName: demo-service
          servicePort: 8080

This just doesn't work and $patch bleeds trough to the final YAML.

So is this supposed to work? How?

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

Was struggling with something similar and came across this issue after googling. Would definitely be helpful to have a bit more clarity here.

@ydewit - I think you might not be able to use merge there, based on this:

Recognized directives in YAML patches are replace (the default) and delete (see these notes)

At a guess, the $patch directive might also need to be placed like this:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    ingress.kubernetes.io/rewrite-target: /
spec:
  $patch: replace
  rules:
  - http:
      paths:
      - path: /demo
        backend:
          serviceName: demo-service
          servicePort: 8080

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle rotten

/remove-lifecycle rotten

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

/remove-lifecycle stale

I'm having similar problems understanding how to use this, I can't make head nor tail of it from the linked documentation.

I have the following from an upstream base, I want to remove 'k8s-app: kube-scheduler' from the matchLabels section and put 'component: kube-scheduler' in its place:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    k8s-app: kube-scheduler
  name: kube-scheduler
  namespace: monitoring
spec:
  endpoints:
  - interval: 30s
    port: http-metrics
  jobLabel: k8s-app
  namespaceSelector:
    matchNames:
    - kube-system
  selector:
    matchLabels:
      component: kube-scheduler
      k8s-app: kube-scheduler

It doesn't seem as though it should be hard to do that? No matter what I do with $patch in my patch file, nothing seems to get rid of 'k8s-app: kube-scheduler'. I even get '$patch: replace' etc. in my kustomized output in some instances. That's suggesting i'm probably not even defining my patch correctly in my kustomization.yaml? But I can't seem to understand any of the docs or examples well enough to work out what i'm actually supposed to do and how i'm supposed to do it correctly (or whether it's even possible to do that?)

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

/remove-lifecycle stale

Who will kill this bot... Issue tracker is full of "how", since kustomize doesn't support customisations and requires alien techniques to do basic things. After 20 minutes I have no idea how to merge base ingress and custom with host.

@develar Our docs are in a mess. Please create a Question issue with what you want to do and I am happy to help.

@Shell32-Natsu Yes, I found the working solution, but it is a little bit awkward and complicated. Correct merge will be better.

Say, I have base/ingress.yaml with content:

spec:
  tls:
    - hosts:
        - "specify host"
      secretName: "specify secretName"
  rules:
    - host: "specify host"
      http:
        paths:
          - path: /api/v1
            backend:
              serviceName: backend
              servicePort: 80
          - path: /
            backend:
              serviceName: frontend
              servicePort: 80

What I want to do — in a private overlay to specify spec.rules[0].host.

So, I created company/ingress.yaml and added it to

patchesStrategicMerge:
  - ingress.yaml

Content of company/ingress.yaml :

spec:
  tls:
    - hosts:
        - "example.com"
      secretName: "example_com"
  rules:
    - host: "example.com"

The issue is that — how do I can make it working? kustomize merges it in a way that http paths is lost (as far I understand, instead of merging array element, kustomize simply replace it).
I tried $patch in a various places, but no luck.

I ended up using patchesJson6902, but as many already said, patchesJson6902 is a quite fragile and not logical way.
If you can point me out how configure merge to work correctly, that's will be great.

Merging two lists is quite tricky. In you case, kustomize doesn't know "how to merge the items in the list" since there is no merge key defined in k8s API definition. In this case it will replace the original list by new one.

See also https://github.com/kubernetes-sigs/kustomize/issues/3047#issuecomment-701014534.

Thanks, so, better just to switch to Helm 3 to get clear and maintainable deployment configs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davidknezic picture davidknezic  Â·  3Comments

bcbrockway picture bcbrockway  Â·  5Comments

sidps picture sidps  Â·  5Comments

wuestkamp picture wuestkamp  Â·  3Comments

TechnicalMercenary picture TechnicalMercenary  Â·  3Comments