kubectl apply vs set: Choosing the Right Command for Resource Updates

Navigate the critical choice between `kubectl apply` (declarative) and `kubectl set`/`kubectl edit` (imperative) for managing Kubernetes resource updates. This comprehensive guide breaks down how each command works, their fundamental differences, and when to use them effectively. Learn to leverage declarative management for consistency and GitOps, while understanding the role of imperative commands for quick, ad-hoc fixes. Master best practices to prevent configuration drift and ensure stable, auditable Kubernetes deployments.

31 views

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:

  1. 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.
  2. Live Configuration: The current state of the resource in the Kubernetes API server.
  3. New Configuration: The state defined in your your-manifest.yaml file.

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 apply operations 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 set or kubectl edit changes not reflected in your manifest files will be overwritten or cause merge conflicts upon the next apply.
  • 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>:

  1. kubectl fetches the current YAML definition of the live resource from the API server.
  2. It opens this definition in your local text editor.
  3. You make your desired changes and save the file.
  4. kubectl then 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 edit is a convenient way to see the full, live YAML of a resource.

Warnings for kubectl set and kubectl edit

  • Configuration Drift: Changes made with set or edit are not reflected in your local manifest files. The next kubectl apply from 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:

  1. Understand the implications of configuration drift.
  2. Immediately capture the changes by doing kubectl get <resource> -o yaml > new-manifest.yaml.
  3. 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.