Lab 04 - Imperative vs. declarative objects

Lab 04 - Imperative vs. declarative objects

Goal: feel why apply is the only thing you put in a pipeline. Chapter: Declarative vs. imperative

Imperative

# 1 - an action, executed once
kubectl create deploy web --image nginx:1.27
kubectl create deploy web --image nginx:1.27      # AlreadyExists - not idempotent
kubectl scale deploy web --replicas 2
kubectl delete deploy web

Declarative

# 2 - generate the manifest instead of writing it
cd ~
kubectl create deploy web --image nginx:1.27 --replicas 2 \
  --dry-run=client -o yaml > web.yaml
cat web.yaml
# 3 - validate against the API without storing anything
kubectl apply -f web.yaml --dry-run=server

client only builds the object locally; server runs full validation and admission, then throws the result away.

# 4 - apply twice
kubectl apply -f web.yaml
kubectl apply -f web.yaml                          # "unchanged"
# 5 - change the file, preview, apply
sed -i 's/nginx:1.27/nginx:1.28/' web.yaml
kubectl diff -f web.yaml
kubectl apply -f web.yaml
# 6 - where apply keeps its memory
kubectl get deploy web -o yaml | grep -A2 last-applied-configuration

Drift

# 7 - someone "fixes" production by hand
kubectl scale deploy web --replicas 5
kubectl get deploy web                             # 5
kubectl diff -f web.yaml                           # git says 2
kubectl apply -f web.yaml
kubectl get deploy web                             # back to 2

The manual change is silently reverted by the next deployment. Either change the file, or do not use apply for that object.

create vs replace vs apply

# 8 - imperative object config
kubectl create -f web.yaml                         # AlreadyExists
kubectl replace -f web.yaml                        # full overwrite of spec

Discovery

Infodiscover

Task A. Apply web.yaml with server-side apply, then find which field manager owns spec.replicas.

kubectl apply -f web.yaml --server-side --force-conflicts
kubectl get deploy web -o yaml --show-managed-fields | grep -B2 -A3 'manager:'

--force-conflicts takes over fields previously owned by client-side apply.

Task B. Generate a manifest for a Pod tools running busybox:1.36 with command sleep 3600, save it to tools.yaml, and create it declaratively.

kubectl run tools --image busybox:1.36 --restart=Never \
  --dry-run=client -o yaml -- sleep 3600 > tools.yaml
kubectl apply -f tools.yaml

Clean up

kubectl delete -f web.yaml -f tools.yaml --ignore-not-found