kubectl apply vs set: Choosing the Right Command for Resource Updates
Kubernetes, the leading container orchestration platform, provides powerful tools for managing the lifecycle of applications. A core aspect of this management involves updating existing resources like Deployments, Services, or ConfigMaps. While kubectl offers several commands for this purpose, kubectl apply and the kubectl set/kubectl edit family represent two fundamentally different philosophies: declarative vs. imperative updates.
Understanding when and how to use each approach is crucial for maintaining stable, reliable, and auditable Kubernetes deployments. Misusing these commands can lead to configuration drift, difficult debugging, and operational inconsistencies. This article will delve into the nuances of kubectl apply, kubectl set, and kubectl edit, equipping you with the knowledge to make informed decisions for your resource update strategies.
The Core Challenge: Managing Resource State
In Kubernetes, every component—from a running Pod to a network Service—is represented as an API object. These objects have a desired state, which you define in YAML or JSON manifest files, and an observed state, which reflects their current reality within the cluster. The primary goal of any kubectl update command is to reconcile these two states, but the method of reconciliation varies significantly.
Understanding kubectl apply: The Declarative Approach
kubectl apply is the cornerstone of declarative resource management in Kubernetes. With this approach, you define the desired state of your resources in a local configuration file (or directory of files) and then tell Kubernetes to make the cluster's state match that definition.
How kubectl apply Works (3-Way Merge)
When you run kubectl apply -f your-manifest.yaml, Kubernetes performs a sophisticated three-way merge:
- Last Applied Configuration: The state of the resource as it was last applied using
kubectl apply. This state is stored in an annotation (kubectl.kubernetes.io/last-applied-configuration) on the live object. - Live Configuration: The current state of the resource in the Kubernetes API server.
- New Configuration: The state defined in your
your-manifest.yamlfile.
The merge algorithm compares these three versions to determine what changes need to be made. It intelligently handles conflicts, prioritizing changes from the new configuration while respecting fields that have been imperatively modified since the last apply (though this can lead to issues, as discussed below).
This process ensures idempotency: applying the same manifest multiple times will result in the same cluster state without unintended side effects, provided no other changes have occurred.
Practical Example: Applying a Deployment
Let's say you have a deployment.yaml file:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-webapp
labels:
app: my-webapp
spec:
replicas: 3
selector:
matchLabels:
app: my-webapp
template:
metadata:
labels:
app: my-webapp
spec:
containers:
- name: webapp-container
image: nginx:1.21.0
ports:
- containerPort: 80
To create or update this deployment, you would run:
kubectl apply -f deployment.yaml
If you later change the image to nginx:1.22.0 in deployment.yaml and run kubectl apply again, Kubernetes will update the Deployment to use the new image while preserving other settings.
Benefits of kubectl apply
- Source of Truth: Your configuration files become the single source of truth for your cluster's desired state. This aligns well with GitOps principles.
- Auditability & Version Control: Changes are tracked in your version control system (e.g., Git), providing a clear audit trail and easy rollbacks.
- Consistency: Ensures consistency across environments (development, staging, production).
- Idempotency: Repeated
applyoperations have the same effect, preventing unintended modifications. - Complex Updates: Handles complex updates involving multiple resource types or significant changes across many fields.
When to Use kubectl apply
- Primary method for all resource creation and updates.
- When deploying applications via CI/CD pipelines.
- For managing infrastructure-as-code.
- When working in teams to ensure consistent configurations.
Tips and Warnings for kubectl apply
- Always keep your manifest files up-to-date with the desired state. Any
kubectl setorkubectl editchanges not reflected in your manifest files will be overwritten or cause merge conflicts upon the nextapply. - Field Managers: Kubernetes 1.16+ introduced Server-Side Apply (SSA), which tracks the "field manager" (e.g.,
kubectl, a controller) responsible for each field in a resource. This helps prevent conflicts when multiple sources modify the same resource. While powerful, be aware of how different tools might interact with field management.
Understanding kubectl set and kubectl edit: The Imperative Approach
kubectl set and kubectl edit belong to the imperative family of commands. Instead of defining the desired state in a file, you directly instruct Kubernetes to perform specific actions or modify live objects within the cluster. These commands are excellent for quick, ad-hoc changes but come with certain caveats.
kubectl set: Focused Imperative Modifications
kubectl set is designed for making specific, common modifications to resources without needing to touch a manifest file. It offers several subcommands to modify particular fields.
How kubectl set Works
kubectl set directly modifies the live object in the Kubernetes API server based on the command-line arguments you provide. It does not interact with local manifest files or update the last-applied-configuration annotation.
Practical Example: Setting an Image
To update the image of a container within a deployment named my-webapp:
kubeclt set image deployment/my-webapp webapp-container=nginx:1.22.0
This command directly modifies the image field for the webapp-container within the my-webapp Deployment. If you had previously managed my-webapp with kubectl apply, this change would create a "drift" between your local deployment.yaml and the live cluster state.
Other common kubectl set commands:
kubectl set resources: To set resource requests/limits.kubectl set env: To add or update environment variables.kubectl set selector: To modify a resource's selector.
kubectl edit: Interactive Imperative Modifications
kubectl edit allows you to directly modify any field of a live resource object in your cluster using your configured default text editor (e.g., vi, nano).
How kubectl edit Works
When you run kubectl edit <resource-type>/<resource-name>:
kubectlfetches the current YAML definition of the live resource from the API server.- It opens this definition in your local text editor.
- You make your desired changes and save the file.
kubectlthen sends the modified definition back to the API server, which attempts to apply the changes. If there are syntax errors or invalid fields, the changes will be rejected.
Like kubectl set, kubectl edit also operates directly on the live object and does not update local manifest files or the last-applied-configuration annotation.
Practical Example: Editing a Deployment
To open the my-webapp deployment in your editor:
kubeclt edit deployment/my-webapp
Your editor will open with a YAML representation of the live deployment. You can then change fields like replicas, image, or add new annotations/labels. Once you save and close the editor, kubectl attempts to apply those changes.
Benefits of kubectl set and kubectl edit
- Speed: Excellent for quick, one-off fixes or debugging in a development environment.
- Flexibility: Directly modify any field of a resource (with
edit). - Ad-hoc Changes: Useful when you don't have a manifest file readily available or don't want to create one for a trivial change.
When to Use kubectl set/kubectl edit
- Debugging in a development cluster: Temporarily increasing replica counts or changing an image to test a fix.
- Small, non-critical, temporary changes in non-production environments.
- Exploring resource definitions:
kubectl editis a convenient way to see the full, live YAML of a resource.
Warnings for kubectl set and kubectl edit
- Configuration Drift: Changes made with
setoreditare not reflected in your local manifest files. The nextkubectl applyfrom your manifest will overwrite these imperative changes or cause conflicts. - Lack of Auditability: These changes are not tracked in version control, making it hard to know who changed what and when, hindering debugging and compliance.
- Non-Idempotent: Repeatedly making the same imperative change can lead to unexpected behavior if the initial state is unknown.
- Risk of Errors: Manual editing (especially with
edit) increases the chance of introducing syntax errors or invalid configurations.
Key Differences: kubectl apply vs. kubectl set/kubectl edit
To summarize the core distinctions:
| Feature | kubectl apply (Declarative) |
kubectl set/kubectl edit (Imperative) |
|---|---|---|
| Approach | Define desired state in file, Kubernetes reconciles. | Directly manipulate live objects or specific fields. |
| Source of Truth | Local configuration files (e.g., Git repository). | The live cluster object itself (ephemeral). |
| Idempotency | Yes, applying the same file yields the same result. | No, not inherently. Each command is an explicit action. |
| Auditability | High (changes tracked in Git, last-applied-configuration). |
Low (no version control, changes are immediate on cluster). |
| Conflict Mgmt. | 3-way merge, uses last-applied-configuration annotation. |
Overwrites directly (for set) or merges interactively (for edit). |
| Use Case | Production deployments, CI/CD, GitOps, team collaboration. | Quick fixes, debugging, ad-hoc changes in non-production. |
| Risk of Drift | Low, as long as files are kept current. | High, very likely to cause configuration drift from source files. |
Choosing the Right Command: Best Practices
For production environments and collaborative teams, the choice is clear:
- Always prefer
kubectl apply(or GitOps tools built on it like Argo CD or Flux CD) for managing your Kubernetes resources. This ensures your cluster's state is version-controlled, auditable, and consistent. - Treat your Kubernetes manifest files as your single source of truth. All changes to resource configurations should ideally originate from these files and be committed to version control.
Imperative commands like kubectl set and kubectl edit should be reserved for:
- Temporary debugging or testing in development/staging clusters. If you use them, ensure you either revert the change or immediately update your source manifest files to reflect the new state.
- One-off, ephemeral operations that do not represent a desired long-term state (e.g., pausing a deployment for a brief moment).
Hybrid Approach (Use with Caution)
In some scenarios, you might find yourself needing to quickly hotfix something in production. While generally discouraged, if you must use kubectl edit:
- Understand the implications of configuration drift.
- Immediately capture the changes by doing
kubectl get <resource> -o yaml > new-manifest.yaml. - Integrate those changes back into your version-controlled manifest files as quickly as possible.
Warning: Regularly using kubectl edit or kubectl set in production without updating your source manifests will lead to an unmanageable, unrecoverable cluster state where the actual configuration diverges wildly from what your team thinks it should be.
Conclusion
kubectl apply, kubectl set, and kubectl edit are all powerful tools for interacting with your Kubernetes cluster. However, they serve different purposes and embody distinct philosophies of resource management. By understanding the declarative nature of kubectl apply and the imperative nature of kubectl set and kubectl edit, you can adopt best practices that lead to more stable, reliable, and maintainable Kubernetes deployments.
For nearly all persistent resource management, especially in production, embrace kubectl apply and version control your configuration files. Reserve imperative commands for temporary, ad-hoc troubleshooting and ensure any critical changes are quickly reflected back in your declarative manifests. This discipline will be invaluable for smooth operations and seamless collaboration within your Kubernetes environment.