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:
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 webOutput
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).