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