Installing kubectl in a Kubernetes Pod

Without creating custom images

tl;dr Use empty volume, initContainers, and subPath to copy and mount kubectl.


The Why

I needed access to the kubernetes API from within a pod so that the pod can self label itself.

For example, I am currently working with redis and redis-sentinel. When sentinel triggers a reconfigure script, I want the pod to re-label itself to role=masteror role=slave. I didn’t want to create a custom redis image that includes kubectl as it would be another component to maintain.

Also, what if I needed to work with other images requiring kubectl? Seemed like alot of maintenance going the custom image route.

The How

First, create an empty volume to hold the kubectl binary.

volumes:
- name: kubectl
emptyDir: {}

Next, using initContainers, copy out the kubectlbinary from a docker image into the volume. In this case, allanlei/kubectlis an image containing a static binary from kubernetes.

initContainers:
- name: install-kubectl
image: allanlei/kubectl
volumeMounts:
- name: kubectl
mountPath: /data
command: ["cp", "/usr/local/bin/kubectl", "/data/kubectl"]

Finally, mount the kubectl volume into the container using subPath. If you don’t use subPath, then the entire mount path will get overriden or gets mounted as a directory, which is not the goal. subPath allows us to specify certain paths in the volume to be mounted.

volumeMounts:
- name: kubectl
subPath: kubectl
mountPath: /usr/local/bin/kubectl

You’re ready to go! The container is now able to run kubectl which is automatically setup via Service Accounts.

Full Example: