Although ‘kubectl annotate‘ will set an annotation on a object directly, it will not set the annotation on the more deeply nested pod template for a Deployment or Daemonset.
If you want to quickly set the annotation on a pod template (.spec.template.metadata.annotations) without modifying the full manifest, you can use the ‘patch‘ command. As a quick example:
kubectl patch deployment nginx -p '{"spec": {"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"false"}}}} }'
As a full example, let’s create an nginx deployment.
# create deployment $ kubectl create deployment nginx --image=nginx:1.21.3-alpine --replicas=1 # direct annotation only has revision $ kubectl get deployment nginx -o=jsonpath="{.metadata.annotations}" {"deployment.kubernetes.io/revision":"1"} # annotation of pod template is empty $ kubectl get deployment nginx -o=jsonpath="{.spec.template.metadata.annotations}"
Now let’s use the ‘annotate’ command on the deployment. Notice the annotation of the deployment itself is modified, but not the pod template annotation.
# will only annotate deployment directly # not its pod template annotation $ kubectl annotate deployment nginx "test=true" # annotation added directly to deployment $ kubectl get deployment nginx -o=jsonpath="{.metadata.annotations}" | jq { "deployment.kubernetes.io/revision": "1", "test": "true" } # but annotation of pod template is still empty $ kubectl get deployment nginx -o=jsonpath="{.spec.template.metadata.annotations}"
In order to modify the deeper pod template annotation, use ‘patch’.
# this will set deep annotation on pod template $ kubectl patch deployment nginx -p '{"spec": {"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"false"}}}} }' # now pod template successfully shows annotation! $ kubectl get deployment nginx -o=jsonpath="{.spec.template.metadata.annotations}" | jq { "sidecar.istio.io/inject": "false" }
If you want to remove the pod template annotation, you cannot use patch like before because it uses a merge strategy that can only append. But if you use the jsonpatch specification, then you can specify a “remove” operation.
# use jsonpath to do a "remove" operation $ kubectl patch deployment nginx --type=json -p='[{"op":"remove","path":"/spec/template/metadata/annotations/sidecar.istio.io~1inject"}]' deployment.apps/nginx patched # the pod template annotation is now empty again $ kubectl get deployment nginx -o=jsonpath="{.spec.template.metadata.annotations}"
Notice that the forward slash had to be escaped as “~1” per the jsonpatch spec.
To delete the deployment:
kubectl delete deployment/nginx
REFERENCES
github issue, annotate does not do template annotation
stackoverflow, specify remove operation with jsonpath
NOTES
Set revision history limit or else they will build up during rolling restarts
# .spec.revisionHistoryLimit=1 kubectl patch deployment nginx -p '{"spec": {"revisionHistoryLimit":1} }'
rolling restart of deployment
$ kubectl rollout restart deployment/nginx deployment.apps/nginx restarted