Declarative vs Imperative

Declarative Desired State Versus Imperative Commands

An imperative command states an action ("scale to three"); a declarative manifest states a result ("two replicas of this image") and leaves the actions to the cluster. Here kubectl 5,150 writes the front end's manifest, web-deployment.yaml, which is then applied, changed imperatively, compared and applied again:

Imperative drift, detected by kubectl diff and undone by kubectl applyShell
kubectl create deployment web --image=localhost:33500/booknest-web:1.3 --replicas=2 \
  --dry-run=client -o yaml > web-deployment.yaml
kubectl apply -f web-deployment.yaml
kubectl rollout status deployment web >/dev/null
kubectl scale deployment web --replicas=3
kubectl diff -f web-deployment.yaml | grep -E '^[-+] '
kubectl apply -f web-deployment.yaml
kubectl get deployment web
Output
deployment.apps/web created
deployment.apps/web scaled
-  generation: 2
+  generation: 3
-  replicas: 3
+  replicas: 2
deployment.apps/web configured
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    2/2     2            2           2s

The scale created drift; kubectl diff showed it and apply removed it. Applying an unchanged file is a no-op, so manifests are safe to keep in Git 1,932 and apply repeatedly (GitOps, GitOps with Argo CD).