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.
Table of Contents
Prerequisites
- A Kubernetes cluster (local or cloud-based).
kubectlinstalled 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
- Avoid Conflicts: Ensure that the base and patch files do not have conflicting changes.
- Validation: Use
kubectl diff -kor inspect the output ofkustomize buildto preview changes before applying them. - Environment-Specific Configurations: Use separate overlays for each environment to maintain clarity.
- Resource Naming: The
metadata.namefield in the patch must match the target resource in the base. - 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: