Dry Run Modes
Dry runs let you test commands without actually changing anything in the cluster. This is invaluable for validating manifests and generating YAML templates.
Client-Side Dry Run
The --dry-run=client flag processes the command locally without contacting the API server:
# Test creating a deployment without actually creating it
kubectl create deployment nginx --image=nginx --dry-run=client
# The real power: generate YAML from imperative commands
kubectl create deployment nginx --image=nginx --replicas=3 \
--dry-run=client -o yaml
This outputs a complete YAML manifest that you can save to a file:
kubectl create deployment nginx --image=nginx --replicas=3 \
--dry-run=client -o yaml > deployment.yaml
Client-side dry run is fast because it does not talk to the cluster, but it cannot validate against the cluster's current state or admission webhooks.
Server-Side Dry Run
The --dry-run=server flag sends the request to the API server, which processes it through all validation and admission webhooks without persisting the result:
# Validate a manifest against the live cluster
kubectl apply -f deployment.yaml --dry-run=server
Server-side dry run catches errors that client-side cannot, such as:
- Invalid field values rejected by admission controllers
- Resource quota violations
- Policy violations from tools like OPA Gatekeeper or Kyverno
Comparing the Two Modes
| Feature | Client | Server |
|---|---|---|
| Requires cluster connection | No | Yes |
| Validates schema | Basic | Full |
| Runs admission webhooks | No | Yes |
| Checks resource quotas | No | Yes |
| Speed | Fast | Slightly slower |
Generating YAML Templates
The combination of --dry-run=client -o yaml is one of the most useful kubectl techniques. Instead of writing YAML from scratch, let kubectl generate it:
# Generate a service YAML
kubectl create service clusterip my-svc --tcp=80:8080 \
--dry-run=client -o yaml > service.yaml
# Generate a configmap YAML
kubectl create configmap app-config \
--from-literal=DB_HOST=postgres \
--dry-run=client -o yaml > configmap.yaml
# Generate a job YAML
kubectl create job backup --image=busybox \
-- /bin/sh -c "echo done" \
--dry-run=client -o yaml > job.yaml
Using kubectl diff
Before applying changes, preview exactly what will change:
kubectl diff -f deployment.yaml
This shows a diff between the live resource and your manifest, helping you catch unintended changes before they happen.
Key Takeaways
--dry-run=clientgenerates output locally without a cluster connection--dry-run=servervalidates against the real cluster including admission webhooks- Combine
--dry-run=client -o yamlto generate YAML templates quickly - Use
kubectl diffto preview changes before applying - Server-side dry run is the safest way to validate before production changes