kubectl patch deployment: A Practical Guide
Learn how to use `kubectl patch` deployment for targeted updates in Kubernetes. Get practical examples, best practices, and troubleshooting tips.
The kubectl patch command is a powerful tool for making on-the-fly modifications to Kubernetes resources, but its imperative nature introduces the risk of configuration drift. When you patch a live object, you create a discrepancy between your cluster's state and the source of truth in your Git repository. This guide explains how to use the precision of kubectl patch deployment for targeted updates while maintaining a consistent, auditable environment. We'll cover best practices for validation, versioning your patches, and integrating them into a robust GitOps workflow to ensure every change is deliberate, tracked, and aligned with your declarative configurations.
Unified Cloud Orchestration for Kubernetes
Manage Kubernetes at scale through a single, enterprise-ready platform.
Key takeaways:
- Use
kubectl patchfor surgical, scripted updates: This command is ideal for making precise, atomic changes to live resources, such as updating a container image or modifying an environment variable, making it a powerful tool for automation and CI/CD pipelines. - Select the right patch strategy for predictable results: Understand the difference between a strategic merge (for native K8s objects), a JSON merge (to replace entire lists), and a JSON patch (for granular control). Always validate your changes with
--dry-run=serverto prevent unintended side effects. - Prevent configuration drift by managing patches via GitOps: Applying patches manually separates your live cluster state from your version-controlled manifests. To maintain a single source of truth, commit patch files to your repository and use a platform like Plural to automate their application, ensuring all changes are auditable and consistent.
What Is kubectl patch?
kubectl patch updates a live Kubernetes resource by submitting a partial object to the API server. Instead of sending a full manifest, you modify only the fields you care about—such as a container image tag or replica count. The API server merges the patch into the existing object and persists the result.
This makes kubectl patch suitable for targeted, atomic updates in scripts and CI/CD pipelines. Unlike kubectl replace or a full kubectl apply, it avoids re-specifying the entire resource and reduces the risk of overwriting unrelated fields.
The kubectl patch Command Explained
The command updates resources in place:
kubectl patch deployment api \
--type='merge' \
-p '{"spec":{"replicas":3}}'
You provide:
- Resource type (
deployment) - Resource name (
api) - Patch payload (
-p) - Patch strategy (
--type)
Kubernetes supports three patch strategies:
Strategic Merge Patch (default for built-ins)
Understands Kubernetes object schemas. For example, it merges container lists using name as the merge key instead of replacing the entire list.
JSON Merge Patch (--type=merge)
Performs a simple structural merge. Lists are replaced entirely, not merged. Useful for straightforward updates but less granular.
JSON Patch (--type=json)
Implements RFC 6902 operations (add, remove, replace) with explicit JSON Pointer paths:
kubectl patch deployment api \
--type='json' \
-p='[{"op":"replace","path":"/spec/replicas","value":5}]'
This is the most precise and predictable option for automation.
kubectl patch vs. apply vs. edit
These commands serve different operational models:
kubectl edit
Opens the live object in a local editor and pushes changes back to the cluster. It’s interactive and unsuitable for automation or reproducibility.
kubectl apply
Declarative. Submits a full manifest and reconciles the live object to match it. This is the standard pattern in GitOps workflows because Git remains the source of truth.
kubectl patch
Imperative but non-interactive. It’s ideal for scripted, field-level updates where managing a full manifest is unnecessary. However, because it modifies live state directly, it can introduce configuration drift unless changes are reconciled back into version control.
In production environments—especially those using GitOps platforms like Plural—kubectl patch should be treated as a surgical tool. Use it for controlled, minimal updates, and ensure any durable change is reflected in declarative configuration to maintain consistency and auditability.
Choosing a Patch Method
kubectl patch supports three patch strategies: strategic merge, JSON merge, and JSON patch. The correct choice depends on the resource type and how precise the mutation must be. Each strategy has different merge semantics, especially around lists and nested objects, so understanding their behavior is essential to avoid unintended mutations.
Strategic Merge Patch
Strategic merge is the default for built-in Kubernetes resources. It is schema-aware and uses merge keys defined in the Kubernetes API (for example, name for containers) to intelligently merge lists and objects.
Example:
kubectl patch deployment api \
-p '{"spec":{"template":{"spec":{"containers":[{"name":"api","image":"api:v2"}]}}}}'
If the Deployment has multiple containers, only the container with name: api is updated. Other fields—ports, env, resources—remain intact.
Limitations:
- Works only for built-in resource types.
- For Custom Resource Definitions (CRDs), Kubernetes falls back to JSON merge semantics because no strategic schema is defined.
Use strategic merge for routine updates to native resources when you want safe, field-level merges without replacing entire lists.
JSON Merge Patch (--type=merge)
JSON merge patch performs a structural merge of JSON objects. It is not schema-aware. When you patch a list, the entire list is replaced.
Example risk scenario:
If a Pod has two containers and you submit:
{
"spec": {
"containers": [
{ "name": "api", "image": "api:v2" }
]
}
}
The result will be a Pod with only that single container. The second container is removed.
Use JSON merge when:
- You intend to replace an entire object or list.
- You are working with CRDs and understand full replacement semantics.
Avoid it for partial list updates unless full replacement is intentional.
JSON Patch (--type=json)
JSON patch implements RFC 6902. It applies explicit operations (add, remove, replace, etc.) against exact JSON Pointer paths.
Example:
kubectl patch deployment api \
--type='json' \
-p='[
{"op":"replace","path":"/spec/template/spec/containers/0/image","value":"api:v2"}
]'
This replaces only the image of the first container. No other fields are touched.
Advantages:
- Fully explicit operations.
- Safe for modifying individual list elements.
- Predictable behavior for automation and CI/CD pipelines.
- Works consistently for both built-in resources and CRDs.
Use JSON patch when you need deterministic, granular control—especially in scripts or production automation where unintended merges are unacceptable.
Practical Guidance
- Built-in resource + simple field update → Strategic merge.
- Full object/list replacement → JSON merge.
- Precise field or list-element mutation → JSON patch.
For GitOps-managed clusters (e.g., with Plural), treat all patch operations as temporary unless the corresponding declarative manifest is updated. Patch strategy determines how the API server mutates state; your workflow determines whether that mutation remains authoritative or is reconciled back to Git.
How to Patch a Kubernetes Deployment
Patching a Deployment lets you mutate a live workload without submitting a full manifest. It’s appropriate for scoped changes such as updating a container image, adjusting environment variables, or modifying replica counts. Unlike kubectl apply, which reconciles an entire declarative spec, kubectl patch performs a field-level mutation against the existing object.
This makes it useful in automation and CI/CD contexts where a single value must change without managing the full resource definition. Because patches mutate live state, precision and validation are critical—incorrect list handling or path targeting can remove configuration unintentionally.
kubectl patch Syntax for Deployments
The general structure is:
kubectl patch <resource_type> <resource_name> \
--type=<strategic|merge|json> \
-p '<patch_content>'
You can also provide patch content via --patch-file.
For Deployments (a built-in resource), the default strategic type is typically appropriate because it merges lists using schema-defined keys (such as container name).
Example structure:
kubectl patch deployment nginx-deployment \
--type='strategic' \
-p '{"spec":{"replicas":3}}'
This updates only the replicas field without affecting other parts of the spec.
Step-by-Step Example: Updating a Container Image
Assume a Deployment named nginx-deployment with a container named nginx. To update the image:
kubectl patch deployment nginx-deployment \
--type='strategic' \
-p '{
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:1.21.6"
}
]
}
}
}
}'
Because this mutates the Pod template, Kubernetes triggers a rolling update. The Deployment controller creates new ReplicaSet revisions and replaces existing Pods incrementally.
Key points:
- Only the container with
name: nginxis updated. - Other container fields (ports, env, resources) remain unchanged.
- A new rollout revision is created.
Verify Before and After Applying
Always validate server-side before persisting:
kubectl patch deployment nginx-deployment \
--type='strategic' \
-p '<patch_content>' \
--dry-run=server -o yaml
This sends the patch to the API server for admission validation and returns the merged result without writing it.
After applying:
Check rollout status:
kubectl rollout status deployment/nginx-deployment
Inspect the updated image:
kubectl get deployment nginx-deployment -o jsonpath='{.spec.template.spec.containers[*].image}'
Or review the full resource:
kubectl describe deployment nginx-deploymentOperational Guidance
- Use
--dry-run=serverfor schema validation. - Prefer
strategicfor built-in resources unless explicit JSON Patch operations are required. - Understand list semantics—incorrect patch structures can remove containers or fields.
- In GitOps-managed environments (e.g., with Plural), reflect permanent changes in Git immediately to prevent reconciliation drift.
kubectl patch is effective for controlled, incremental updates. Treat it as a surgical mutation tool and pair it with verification steps to maintain deployment stability.
Common Use Cases for kubectl patch
The kubectl patch command is a versatile tool for making targeted, live updates to Kubernetes resources. Instead of replacing an entire resource configuration with kubectl apply, you can modify specific fields, which is faster and often safer for minor changes. This approach is useful for a variety of day-to-day operational tasks, from updating application configurations to scaling services. Let's look at some of the most common scenarios where kubectl patch proves invaluable.
Update a Container Image
One of the most frequent uses for kubectl patch is updating a container image. When you need to roll out a new version of your application, you can directly update the image tag in a Deployment or Pod specification. This action triggers a rolling update without requiring a full kubectl apply of a modified manifest. For example, to update a container named kubernetes-serve-hostname in a pod, you can use a strategic merge patch. The name field is used as a key to identify which container in the list to modify.
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new-image:v2"}]}}'
This command precisely targets the image field, making it an efficient way to deploy updates.
Modify Environment Variables
Configuration changes often involve updating environment variables. With kubectl patch, you can add, remove, or modify these variables for a container without redeploying the entire application. This is ideal for tasks like updating an API endpoint, changing a feature flag, or rotating a non-sensitive configuration value. The patch targets the env array within the container specification. This method allows for quick configuration adjustments, which is essential for dynamic environments where settings need to be tweaked frequently. For example, you can add a new variable like this:
kubectl patch deployment my-app -p '{"spec":{"template":{"spec":{"containers":[{"name":"my-container","env":[{"name":"FEATURE_FLAG","value":"enabled"}]}]}}}}'
Scale Replicas
Adjusting the number of replicas for a Deployment, ReplicaSet, or StatefulSet is a core task in managing application scalability. While kubectl scale is designed specifically for this, kubectl patch can also accomplish it, particularly when scripting automated workflows. By targeting the replicas field in the resource's spec, you can declaratively set the desired number of pods. This is a straightforward way to respond to changes in traffic or workload demands. Using a merge patch, the command is simple and direct, ensuring your application scales up or down as needed.
kubectl patch deployment nginx-deployment -p '{"spec":{"replicas":5}}'
Change Resource Limits and Requests
Properly managing container resources is critical for cluster stability and performance. kubectl patch allows you to fine-tune the CPU and memory requests and limits for a container on the fly. This is useful when you observe that an application is either under-resourced or consuming more resources than necessary. By patching the resources field, you can optimize resource allocation across your cluster, preventing resource contention and ensuring applications have what they need to run efficiently. This helps maintain a healthy and cost-effective cluster environment.
kubectl patch deployment my-app --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/resources/limits/cpu", "value":"500m"}]'
Add Annotations and Labels
Labels and annotations are key-value pairs that attach metadata to Kubernetes objects. You can use kubectl patch to add or modify them without disrupting the resource. Labels are used to identify and select objects, such as grouping all pods belonging to a specific service. Annotations hold non-identifying metadata that can be used by tools and libraries. For instance, you might add an annotation to trigger a CI/CD pipeline or to link to a monitoring dashboard. Patching metadata is a common operation for integrating Kubernetes with external tooling and automation systems.
kubectl patch deployment my-deployment -p '{"metadata":{"annotations":{"last-updated-by":"admin"}}}'
Best Practices for Patching Deployments
Using kubectl patch offers a powerful way to make targeted, on-the-fly updates to your Kubernetes deployments. However, its imperative nature requires a disciplined approach to avoid introducing instability or configuration drift. Adhering to a set of best practices ensures that you can leverage the speed and flexibility of kubectl patch without compromising the reliability and maintainability of your clusters. These practices focus on validation, versioning, and integrating patches into a structured workflow, which is essential for managing Kubernetes environments at scale.
Test Changes with --dry-run
Before applying any patch to a live deployment, you should validate its effects. The --dry-run flag is an essential tool for this purpose, allowing you to simulate the patch operation without making any actual changes to the cluster state. You can use either --dry-run=client to perform client-side validation or --dry-run=server to send the request to the API server for a more comprehensive check. This practice helps you catch syntax errors, invalid field values, or other potential issues before they impact your running applications. For example, running a patch with --dry-run=server confirms the API server will accept the change, preventing mistakes in a production environment.
Use Version Control for Patches
For anything beyond a simple, one-off command, storing your patches in a version control system like Git is critical. When you define complex updates using JSON Patch or merge patch files, committing them to a repository provides a transparent audit trail. This allows your team to track who made what change, when, and why. It also simplifies collaboration and code reviews for configuration changes. This practice is a foundational element of GitOps, where Git serves as the single source of truth for your cluster's desired state. By versioning your patches, you ensure that every modification is reproducible and auditable.
Understand Atomic Updates and Rollbacks
While kubectl patch is excellent for quick, targeted fixes and automation scripts, it's important to know when to use other commands. For managing the lifecycle of your primary resources, kubectl apply is often a better choice because it works declaratively. It compares your local configuration file with the live object and applies only the necessary changes. Unlike apply, patch operations are imperative and don't contribute to the deployment's revision history. This means you cannot use kubectl rollout undo to revert a change made with patch. Rollbacks must be handled manually by applying a counter-patch or reverting to a previous configuration file from version control.
Prevent Configuration Drift
The most significant risk of using kubectl patch is introducing configuration drift. When you patch a live object, you alter its running state without updating the original YAML manifest stored in your repository. This creates a discrepancy between your declared source of truth and the actual state of your cluster. Over time, this drift makes your environment unpredictable and difficult to manage, undermining the core principles of Infrastructure as Code. To combat this, it's crucial to have a process for reflecting patched changes back into your source manifests. A robust GitOps workflow, like the one managed by Plural CD, automatically reconciles the cluster state against your Git repository, effectively preventing and correcting drift.
Integrating kubectl patch with GitOps
While kubectl patch is a powerful command for making targeted, live changes, running it manually against a production cluster introduces significant risk. Manual patches create configuration drift, where the live state of your cluster diverges from the state defined in your Git repository. This discrepancy makes the system difficult to audit, reproduce, and manage over time. When a problem occurs, it's challenging to determine whether the cause is the declared configuration or an ad-hoc patch applied days or weeks earlier.
Integrating kubectl patch into a GitOps workflow solves this problem by enforcing a declarative approach. Instead of applying patches directly to the cluster, you commit the patch files to your Git repository. A CI/CD pipeline then automates the application of these patches, ensuring every change is version-controlled, peer-reviewed, and auditable. This method treats your infrastructure and its modifications as code, establishing Git as the single source of truth for your cluster's state. By adopting GitOps, you maintain the precision of kubectl patch while gaining the safety, consistency, and scalability of an automated system. This is essential for managing complex Kubernetes environments where manual changes can easily lead to instability and operational overhead.
Manage Patches in Your CI/CD Pipeline
To integrate patching into your CI/CD pipeline, store your patch files—whether strategic merge, JSON merge, or JSON patch—within your Git repository alongside your other Kubernetes manifests. Your pipeline should be configured to apply these patches as a step in the deployment process. This method ensures that every modification is tracked and versioned. Using a GitOps approach allows you to automate the deployment of patches, creating a streamlined and auditable trail for every change. For example, a pipeline can be triggered on a merge to the main branch, automatically running kubectl patch with the committed patch file against the target deployment in the specified cluster.
How Plural Manages GitOps Deployments
Plural is built around a GitOps-first philosophy, providing a robust foundation for managing deployments and patches at scale. The platform’s continuous deployment capabilities ensure that your cluster's state always reflects what's defined in your Git repository. When you commit a patch file, Plural’s agent detects the change and applies it automatically, preventing configuration drift. This workflow makes every deployment and patch auditable, consistent, and easy to roll back if something goes wrong. By leveraging Plural, you can manage patches declaratively without sacrificing the control and visibility needed for enterprise-grade Kubernetes fleet management.
Create Environment-Specific Patching Strategies
In most real-world scenarios, you need different configurations for development, staging, and production environments. A GitOps workflow is ideal for managing these variations. You can structure your repository to handle environment-specific patches, for instance, by using separate directories or branches for each environment (e.g., patches/staging/ and patches/production/). This allows you to define the desired state declaratively for each environment in a single repository. Your CI/CD pipeline can then apply the correct patches based on the target environment, ensuring that changes like scaling replicas or adjusting resource limits are tailored appropriately without manual intervention.
Troubleshooting kubectl patch
Even with a clear understanding of the different patch strategies, operations can fail. Patching modifies live resources, so errors can have an immediate impact. Here’s how to address common issues that arise when using kubectl patch.
Common Errors and How to Fix Them
When a patch command fails, Kubernetes usually provides an error message that points you in the right direction. Most issues stem from incorrect syntax or references in the patch itself.
Common errors include:
- Validation errors: If you see a "validation error," it means the path to the field you're changing or the value you're providing is incorrect. Double-check your patch against the resource's schema to ensure the path is valid and the value is the correct data type.
- Resource not found: An error like "unable to find container named X" indicates a mismatch. The name of the resource, container, or field in your patch must exactly match the one in the live object definition.
- Incorrect merge behavior: If a patch isn't merging as expected, especially with lists or arrays, the default strategic merge patch might not be suitable. In these cases, switching to a more explicit JSON Patch often resolves the ambiguity by letting you define the exact operation (
add,replace,remove).
Debug Failed Patch Operations
Before applying a patch to a live cluster, you should always validate it. The kubectl patch command includes a --dry-run flag that lets you simulate the operation without making any actual changes, which is essential for preventing mistakes in production environments.
To debug a patch, you can use the following commands:
--dry-run=client: This performs a client-side validation of your command. It checks for syntax errors but doesn't verify if the API server will accept the change.--dry-run=server: This sends the patch to the Kubernetes API server for full validation, including schema checks and admission controller logic, but stops before persisting the change.
For a more detailed inspection, combine a server-side dry run with YAML output: kubectl patch ... --dry-run=server -o yaml. This command returns the complete resource manifest as it would look after the patch is applied. You can then compare this output to the original resource definition to confirm the change is exactly what you intended.
Resolve Resource Version Conflicts
A significant challenge with kubectl patch is its potential to cause configuration drift. When you patch a live object, you are only changing the resource running in the cluster. The original YAML manifest stored in your version control system remains unchanged. This creates a discrepancy between your desired state in Git and the actual state in the cluster.
This drift complicates future updates and makes rollbacks difficult. While kubectl patch is effective for quick fixes, it should not replace a declarative approach for managing your primary resources. For most deployments, it's better to use kubectl apply with a version-controlled manifest. This practice ensures your Git repository remains the single source of truth. Adopting a GitOps workflow, which is central to how Plural manages deployments, helps prevent configuration drift by automatically reconciling the cluster state with your manifests.
Related Articles
- How to Implement GitOps Across Clusters for Scale
- kubectl edit deployment: A Complete Guide
- Deploy to Kubernetes: The Ultimate 2024 Guide
Unified Cloud Orchestration for Kubernetes
Manage Kubernetes at scale through a single, enterprise-ready platform.
Frequently Asked Questions
When should I use kubectl patch instead of kubectl apply? Use kubectl patch for small, targeted, and often automated changes where you need to modify only a few specific fields of a live resource, such as updating a container image tag in a CI/CD script. Use kubectl apply for declarative configuration management, where you want the cluster's state to match a complete manifest file stored in version control. apply is better for managing the entire lifecycle of a resource, while patch is ideal for surgical, imperative updates.
How can I roll back a change made with kubectl patch? Changes made with kubectl patch are not tracked in a deployment's revision history, so you cannot use kubectl rollout undo to revert them. To roll back a patch, you must apply a counter-patch that restores the previous values or use kubectl apply with a version-controlled manifest that contains the last known good configuration. This is why storing configurations in Git is critical for maintaining a reliable rollback path.
Why did my patch delete other items in a list when I only wanted to add one? This typically happens when you use a JSON merge patch (--type=merge) on a list, such as the containers or env array in a deployment. A merge patch replaces the entire list with the one you provide. To add or modify a single item within a list without affecting the others, you should use a strategic merge patch (the default for native resources) or a JSON patch (--type=json), which allows you to specify precise operations like add or replace on a specific list element.
Is it safe to use kubectl patch for production changes? Using kubectl patch directly on a production cluster carries the risk of creating configuration drift, where the live state of the resource no longer matches the manifest in your Git repository. This makes your system harder to manage and audit. The safest approach is to integrate patching into a GitOps workflow. Instead of running the command manually, you commit the patch file to your repository, and a tool like Plural CD automatically applies the change, ensuring every modification is version-controlled and auditable.
Does kubectl patch work the same way for Custom Resources (CRDs)? Not exactly. The default strategic merge patch logic is built into Kubernetes for its native resources like Deployments and Pods. This logic does not automatically extend to Custom Resources. When you use kubectl patch on a CRD without specifying a type, it defaults to a JSON merge patch. This means patching a list within a CRD will replace the entire list, which can be an unexpected behavior if you're used to how it works with standard deployments. For precise changes to CRDs, it is often better to use a JSON patch.
Newsletter
Join the newsletter to receive the latest updates in your inbox.