Strategic Merge Patches in Kubernetes using Kustomize

In this article, we will explore Strategic Merge Patches in Kubernetes using Kustomize | how to use Strategic Merge Patches step by step with simple YAML examples and a clear directory structure. We will also demonstrate how to replace entire fields using SMP.

Strategic Merge Patches (SMP) are a powerful tool in Kubernetes that allow you to modify Kubernetes resources declaratively. Unlike JSON patches, SMP is designed to merge fields intelligently based on their structure, making it particularly useful for modifying complex resources.

Prerequisites

  • A Kubernetes cluster (local or cloud-based).
  • kubectl installed and configured.
  • Basic understanding of Kubernetes resources and YAML.

Step #1:Set Up Your Directory Structure

Organize your files for better clarity:

.
├── base
│   ├── deployment.yaml
│   └── kustomization.yaml
├── overlays
│   ├── staging
│   │   ├── patch.yaml
│   │   └── kustomization.yaml
│   └── production
│       ├── patch.yaml
│       ├── replace-patch.yaml
│       └── kustomization.yaml
  • base/: Contains the original resource configuration.
  • overlays/: Contains environment-specific patches (e.g., staging, production).

Step #2:Create the Base Deployment

The base deployment YAML defines the core resource. Save it as base/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-container
          image: nginx:1.21
          ports:
            - containerPort: 80

Create the kustomization.yaml file in the base/ directory:

resources:
  - deployment.yaml

This configuration ensures that the base deployment is included when Kustomize processes the resources.

Step #3:Create a Patch for Staging

Strategic Merge Patches modify only the fields specified in the patch YAML. Create overlays/staging/patch.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: my-container
          image: nginx:1.22

Create the kustomization.yaml file in the overlays/staging/ directory:

resources:
  - ../../base

patchesStrategicMerge:
  - patch.yaml
  • replicas: 1: Reduces the replica count for staging.
  • image: nginx:1.22: Updates the container image.

Build the resources for staging:

kustomize build overlays/staging

Output:

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

Step #4:Create a Patch for Production

Similarly, create a patch for the production environment in overlays/production/patch.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 5
  template:
    spec:
      containers:
        - name: my-container
          image: nginx:1.23
          resources:
            limits:
              memory: "256Mi"
              cpu: "500m"

Create the kustomization.yaml file in the overlays/production/ directory:

resources:
  - ../../base

patchesStrategicMerge:
  - patch.yaml
  • replicas: 5: Scales up for production.
  • Resource limits: Ensures the application has dedicated resources.

Build the resources for production:

kustomize build overlays/production

Output:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 5
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-container
          image: nginx:1.23
          resources:
            limits:
              memory: "256Mi"
              cpu: "500m"
          ports:
            - containerPort: 80

Step #5:Replace a Field Using Patches

Strategic Merge Patches can also replace specific fields entirely. For example, replacing the container spec entirely with a new configuration. Create overlays/production/replace-patch.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
        - name: new-container
          image: nginx:1.25
          ports:
            - containerPort: 8080
      # Add the directive to replace the containers
      $patch: replace

Update the kustomization.yaml file in the overlays/production/ directory to include this patch:

resources:
  - ../../base

patchesStrategicMerge:
  - patch.yaml
  - replace-patch.yaml

Build the resources for production with the replace patch:

kustomize build overlays/production | kubectl apply -f -

Output:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 5
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: new-container
          image: nginx:1.25
          ports:
            - containerPort: 8080

Step #6:Verify the Changes

Inspect the generated configurations or applied changes:

Verify Replicas

kubectl get deployment my-app -o jsonpath='{.spec.replicas}'

Verify Container Image

kubectl get deployment my-app -o jsonpath='{.spec.template.spec.containers[0].image}'

Verify Container Name and Port

kubectl get deployment my-app -o jsonpath='{.spec.template.spec.containers[0].name} {.spec.template.spec.containers[0].ports[0].containerPort}'

Notes and Best Practices

  1. Avoid Conflicts: Ensure that the base and patch files do not have conflicting changes.
  2. Validation: Use kubectl diff -k or inspect the output of kustomize build to preview changes before applying them.
  3. Environment-Specific Configurations: Use separate overlays for each environment to maintain clarity.
  4. Resource Naming: The metadata.name field in the patch must match the target resource in the base.
  5. Replace Entire Fields: Use patches to replace fields when necessary to avoid partial merges causing unintended behavior.

Conclusion:

Strategic Merge Patches provide a flexible way to customize Kubernetes resources for different environments. By using patches, you can avoid duplication, ensure consistency, and streamline your deployment workflows. Start incorporating SMP into your Kubernetes projects for better resource management!

Related Articles:

How to Manage Common Labels and Annotations in Kustomize for Base and Overlays

Reference:

kustomize official page

Harish Reddy

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link
Powered by Social Snap