• $annotations  holds all annotations as a JSON object, with annotation names as properties. • With  to_entries , we convert a JSON object like  { "a": "b"}  into a an array with entries like  { "key": "a", "value": "b" } . See the  jq  documentation for more details. • .[]  selects the array entries individually. • From these entries, we pick only the ones with the matching key. There can be only zero or one matches that survive this filter. • Finally, we extract the value ( .value ) and convert it with  @uri  so that it can be used as part of an URI. This expression converts a JSON structure like { "k8spatterns.io/pattern" : "Controller", "k8spatterns.io/podDeleteSelector" : "app=webapp" } to a selector  app%3Dwebapp . If the script can extract a  selector , we can use it now directly to select the Pods to delete. First, we look up all Pods that match the selector, and then we delete them one by one with direct API calls. This shell script-based controller is, of course, not production-grade (e.g., the event loop can stop any time), but it nicely reveals the base concepts without too much boilerplate code for us. The remaining work is about creating resource objects and container images. The controller script itself is stored in a ConfigMap  config-watcher-controller  and can be easily edited later if required. We use a Deployment to create a Pod for our controller with two containers: • One Kubernetes API  Ambassador  container that exposes the Kubernetes API on localhost on port 8001. The image  k8spatterns/kubeapi-proxy  is an Alpine Linux with a local  kubectl  installed and  kubectl proxy  started with the proper CA and token mounted. The original version, kubectl-proxy, was written by Marko Lukša, who introduced this proxy in  Kubernetes in Action . • The main container that executes the script contained in the just-created Config‐ Map. We use here an Alpine base image with  curl  and  jq  installed. You can find the Dockerfiles for the  k8spatterns/kubeapi-proxy  and  k8spatterns/ curl-jq  images in our example Git repository. Solution  |  183