kubectl patch

Update fields of a resource using strategic merge patch, JSON merge patch, or JSON patch.

kubectl patch [TYPE] [NAME] --patch [PATCH] [flags]

Common Flags

FlagShortDescription
--patch-pThe patch to apply, in JSON or YAML format
--patch-fileA file containing the patch to apply
--typePatch type: strategic (default), merge, or json
--namespace-nNamespace of the resource to patch
--dry-runMust be none, server, or client. Preview changes without applying
--subresourcePatch a specific subresource such as status or scale

Examples

Update the replica count of a deployment

kubectl patch deployment my-app -p '{"spec":{"replicas":5}}'

Update a container image

kubectl patch deployment my-app -p '{"spec":{"template":{"spec":{"containers":[{"name":"app","image":"nginx:1.26"}]}}}}'

Add an annotation using JSON patch

kubectl patch deployment my-app --type=json -p '[{"op":"add","path":"/metadata/annotations/updated","value":"true"}]'

Remove a finalizer using JSON merge patch

kubectl patch pod stuck-pod --type=merge -p '{"metadata":{"finalizers":null}}'

Patch from a file

kubectl patch deployment my-app --patch-file patch.yaml

Patch a node to add a taint

kubectl patch node worker-1 -p '{"spec":{"taints":[{"key":"maintenance","effect":"NoSchedule"}]}}'

When to Use kubectl patch

kubectl patch modifies specific fields of a resource without requiring you to provide the entire resource definition. It is ideal for scripted changes, CI/CD pipelines, and targeted updates where you know exactly which field needs to change.

Patch Types Explained

Understanding the three patch types is essential for using patch effectively.

Strategic Merge Patch (default) is Kubernetes-specific and understands how to merge lists intelligently. Each list item has a merge key (usually name), and items are matched and merged by that key:

# Add or update a container in a pod spec — matched by container name
kubectl patch deployment my-app -p '
spec:
  template:
    spec:
      containers:
      - name: app
        image: nginx:1.26
'

JSON Merge Patch follows RFC 7386. It replaces entire lists rather than merging them, which means providing a list overwrites the existing one completely:

# This replaces ALL containers, not just the one named
kubectl patch deployment my-app --type=merge -p '
{"spec":{"template":{"spec":{"containers":[{"name":"app","image":"nginx:1.26"}]}}}}'

JSON Patch follows RFC 6902 and uses explicit operations. It is the most precise and powerful patch type:

# Add an annotation
kubectl patch deployment my-app --type=json \
  -p '[{"op":"add","path":"/metadata/annotations/patched","value":"true"}]'

# Remove a specific container by index
kubectl patch deployment my-app --type=json \
  -p '[{"op":"remove","path":"/spec/template/spec/containers/1"}]'

# Replace the replica count
kubectl patch deployment my-app --type=json \
  -p '[{"op":"replace","path":"/spec/replicas","value":3}]'

Common Patch Operations

Here are the most frequently needed patch operations:

# Scale a deployment
kubectl patch deployment my-app -p '{"spec":{"replicas":10}}'

# Change an image tag
kubectl patch deployment my-app -p \
  '{"spec":{"template":{"spec":{"containers":[{"name":"app","image":"myapp:v2"}]}}}}'

# Add a label
kubectl patch deployment my-app -p '{"metadata":{"labels":{"version":"v2"}}}'

# Add a toleration
kubectl patch deployment my-app -p '{"spec":{"template":{"spec":{"tolerations":[{"key":"special","operator":"Exists","effect":"NoSchedule"}]}}}}'

# Remove finalizers from a stuck resource
kubectl patch pvc stuck-pvc --type=merge -p '{"metadata":{"finalizers":null}}'

Using Patch Files

For complex patches, use a YAML file instead of inline JSON:

# Create a patch file
cat > patch.yaml <<EOF
spec:
  template:
    spec:
      containers:
      - name: app
        resources:
          limits:
            memory: "512Mi"
            cpu: "500m"
          requests:
            memory: "256Mi"
            cpu: "250m"
EOF

# Apply the patch
kubectl patch deployment my-app --patch-file patch.yaml

Patch files are easier to read, review in pull requests, and maintain over time.

Patching in Scripts and CI/CD

Patch is the preferred command for scripted modifications because it does not require an interactive editor and can be expressed as a single command:

# Update image tag in CI/CD pipeline
IMAGE_TAG="${CI_COMMIT_SHA:0:8}"
kubectl patch deployment my-app -p \
  "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"app\",\"image\":\"registry.example.com/app:${IMAGE_TAG}\"}]}}}}"

# Pause a deployment before patching multiple fields
kubectl rollout pause deployment my-app
kubectl patch deployment my-app -p '{"spec":{"replicas":5}}'
kubectl patch deployment my-app --patch-file resource-update.yaml
kubectl rollout resume deployment my-app

Subresource Patching

You can patch subresources like status or scale directly:

# Patch the scale subresource
kubectl patch deployment my-app --subresource=scale -p '{"spec":{"replicas":3}}'

Dry Run and Validation

Always preview patches in production:

# Preview the patch without applying
kubectl patch deployment my-app -p '{"spec":{"replicas":5}}' --dry-run=server -o yaml

# Validate the resulting resource
kubectl patch deployment my-app -p '{"spec":{"replicas":5}}' --dry-run=server

Best Practices

Prefer YAML patch files over inline JSON for readability. Use strategic merge patch for most Kubernetes resources since it understands list merge semantics. Reserve JSON patch for operations that require removing specific list items or precise positional changes. Always use --dry-run=server when patching production resources for the first time.

Interview Questions About This Command

What are the three patch strategies available in kubectl patch?
Strategic merge patch (default) intelligently merges lists using merge keys. JSON merge patch replaces lists entirely. JSON patch uses RFC 6902 operations (add, remove, replace, move, copy, test) for precise modifications.
When would you use JSON patch over strategic merge patch?
JSON patch is needed when you want to remove specific items from a list, add items at specific positions, or perform operations that strategic merge patch cannot express, like removing a single container from a pod spec.
How do you remove a field using kubectl patch?
With merge patch, set the field to null: --type=merge -p '{"field":null}'. With JSON patch, use the remove operation: --type=json -p '[{"op":"remove","path":"/field"}]'.

Common Mistakes

  • Using strategic merge patch to remove list items, which does not work because strategic merge uses directive markers. Use JSON patch type instead.
  • Forgetting that JSON must use double quotes for keys and values when passing patch inline, requiring careful escaping in bash.
  • Not understanding the difference between patch types and accidentally replacing an entire list when using merge patch.

Related Commands