Hari Kishore
Hari Kishore

Reputation: 2890

Can someone explain 'patchesStrategicMerge'

I see patchesStrategicMergein my kustomization.yaml file, but not getting it clearly, like whats its need or why we require that?

kustomization.yaml

resources:
- a.yaml

patchesStrategicMerge:
- b.yaml
- c.yaml

I went through this: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/#customizing and https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md

Upvotes: 25

Views: 45558

Answers (3)

Andrei_N
Andrei_N

Reputation: 440

Now patchesStrategicMerge is deprecated, it should be replaced with https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/#patch-using-path-strategic-merge

Upvotes: 1

Ilias Naamane
Ilias Naamane

Reputation: 11

patchesStrategicMerge is a function used in Kubernetes to apply changes to Kubernetes resources. It's typically utilized when managing configurations via YAML files in Kubernetes using Kustomize. For example given this deployment base file:


    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80

Kustomization file of the previous deployment.


    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization

    resources:
    - deployment.yaml

In order to apply changes, we will define a deployment with same name and another kustomization file which use patchesStrategicMerge.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 6
      template:
        spec:
          containers:
          - name: nginx
            env: 
            - name: ENV
              value: "production"

Kustomization file of the previous deployment


    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization

    namePrefix: prod-

    bases:
    - ../../base

    patchesStrategicMerge:
    - deployment.yaml

Note: The usage for patchesStrategicMerge in this example is to add an environment variable to the deployment as well as updating the number of replicas. ../../base is the path for the original kustomization file.

Upvotes: 1

The Fool
The Fool

Reputation: 20547

This comes in handy you inherit from some base and want to apply partial changes to said base. That way, you can have one source YAML file and perform different customizations based on it, without having to recreate the entire resource. That is one key selling point of kustomize.

The purpose of the Strategic Merge Patch is to be able to patch rich objects partially, instead of replacing them entirely.

Imagine you have a list, of object.

mylist:
 - name: foo
 - name: bar
 - name: baz

How could you change one of the items in the list? With a standard merge patch, you could only replace the entire list. But with a strategic merge patch, you can target one element in the list based on some property, in this case only the name makes sense as it's the only property.

mylist:
 - $patch: delete
   name: foo

In the above example, I used the strategic merge patch to remove the item in the list with the name foo.

Here is another example, suppose I have the following project structure.

sample
├── base
│   ├── kustomization.yaml
│   └── pod.yaml
└── layers
    └── dev
        ├── kustomization.yaml
        └── patch.yaml

In the base, is my full pod definition. While in the layers, I can create multiple layers for different environments, in this case I have only one for dev.

The kustomization.yaml in the base folder looks like this.

resources:
 - pod.yaml

If I execute the base itself with dry run I get this.

kubectl apply -k sample/base --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
  namespace: default
spec:
  containers:
  - image: nginx
    name: nginx
  - command:
    - sleep
    - infinity
  - image: busybox
    name: sidecar

The kustomization.yaml in the dev folder looks like this.

bases:
  - ../../base
patchesStrategicMerge:
  - patch.yaml

And the patch looks like this. I want to enable debug logging for the sidecar. Thefore I am using a merge directive to change its arguments without changing the image. I also want to keep the nginx container.

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
    - $patch: merge
      name: sidecar
      args: [log-level, debug]
kubectl apply -k sample/layers/dev/ --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
  namespace: default
spec:
  containers:
  - args:
    - log-level
    - debug
    command:
    - sleep
    - infinity
    image: busybox
    name: sidecar
  - image: nginx
    name: nginx

Note: The command and args don't make much sense, It's just to illustrate the strategic merge patch.

Upvotes: 42

Related Questions