kubectl replace
Replace a resource by filename or stdin. The resource must already exist, and the entire object is replaced with the new definition.
kubectl replace -f [FILE] [flags]Common Flags
| Flag | Short | Description |
|---|---|---|
| --filename | -f | Filename, directory, or URL to file to use to replace the resource |
| --force | — | Delete and recreate the resource if it cannot be updated in place |
| --cascade | — | Must be background, foreground, or orphan. Used with --force |
| --grace-period | — | Grace period for deletion when using --force |
| --save-config | — | Save the configuration in the annotation for future apply usage |
| --validate | — | Validate the input before sending (default true) |
Examples
Replace a resource from a file
kubectl replace -f deployment.yamlForce replace a resource (delete and recreate)
kubectl replace -f deployment.yaml --forceReplace from stdin
kubectl get deployment my-app -o yaml | sed 's/nginx:1.25/nginx:1.26/' | kubectl replace -f -Replace with grace period for force delete
kubectl replace -f pod.yaml --force --grace-period=0Replace and save config for future apply usage
kubectl replace -f deployment.yaml --save-configWhen to Use kubectl replace
kubectl replace performs a full replacement of a resource. Unlike kubectl apply, which merges changes, replace sends the complete object definition to the API server. The existing resource is entirely overwritten with the provided specification. This makes replace predictable but potentially destructive if your local manifest is incomplete.
Replace vs Apply
The key distinction is how each command handles existing fields:
# Apply: merges changes, preserves fields you don't specify
kubectl apply -f deployment.yaml
# Replace: overwrites everything with exactly what's in the file
kubectl replace -f deployment.yaml
With apply, if a controller set an annotation or an HPA changed the replica count, those fields are preserved. With replace, any field not in your file is removed. This means you need a complete, up-to-date manifest.
The Get-Modify-Replace Workflow
The safest way to use replace is the get-modify-replace pattern:
# Get the current state
kubectl get deployment my-app -o yaml > deployment.yaml
# Edit the file
vim deployment.yaml
# Replace with the modified version
kubectl replace -f deployment.yaml
This ensures your replacement manifest includes all current fields, minimizing the risk of accidentally removing controller-managed fields.
Pipe-Based Replacement
You can combine get and replace through a pipe for quick inline changes:
# Update an image inline
kubectl get deployment my-app -o yaml | \
sed 's|image: nginx:1.25|image: nginx:1.26|' | \
kubectl replace -f -
# Add a label inline
kubectl get deployment my-app -o yaml | \
yq '.metadata.labels.version = "v2"' | \
kubectl replace -f -
This pattern is useful in scripts where you need to modify a specific field programmatically.
Force Replace
When you need to change immutable fields, --force deletes and recreates the resource:
# Force replace when immutable fields have changed
kubectl replace -f service.yaml --force
# Force replace with no grace period (immediate deletion)
kubectl replace -f pod.yaml --force --grace-period=0
Force replace causes downtime because the resource is deleted before the new version is created. For Services, this means the ClusterIP changes unless you specify it explicitly. For Deployments, the pods are terminated and recreated.
When Replace Is Appropriate
Replace is the right choice in these scenarios:
- Atomic updates: When you want to ensure the resource matches your manifest exactly, with no merged remnants from previous configurations.
- Immutable field changes: When you need to change fields that cannot be updated in place, such as Job selectors or PVC storage class.
- Controlled overwrites: When you explicitly want to remove fields that were added by controllers or manual edits.
- CI/CD with complete manifests: When your pipeline always generates complete resource definitions and you want deterministic outcomes.
# CI/CD pipeline using replace for deterministic deployments
kubectl get deployment my-app &>/dev/null && \
kubectl replace -f deployment.yaml || \
kubectl create -f deployment.yaml
Resource Version Conflicts
Replace uses the resourceVersion field for optimistic concurrency. If the resource was modified between your get and replace, the replace fails with a conflict error:
# This might fail if someone else modified the resource
kubectl replace -f deployment.yaml
# error: the object has been modified; please apply your changes to the latest version
# Solution: get the latest version and try again
kubectl get deployment my-app -o yaml > deployment.yaml
# Make your changes again
kubectl replace -f deployment.yaml
This conflict detection prevents accidental overwrites of concurrent changes.
Best Practices
Prefer kubectl apply for most workflows because it is safer with the three-way merge. Use replace only when you need full resource replacement semantics. Always base your replacement manifest on the current live state using kubectl get -o yaml. Avoid --force in production unless you understand the downtime implications. If you use replace in CI/CD, ensure your manifests are always complete and up to date.
Interview Questions About This Command
Common Mistakes
- Using replace without realizing it overwrites the entire resource, removing fields that were set by controllers or other tools.
- Using --force on production services without understanding it causes downtime during the delete-recreate cycle.
- Applying a stale YAML file with replace that is missing fields added since the file was last updated.