Installing kubectl in a Kubernetes Pod

Without creating custom images

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

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.

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.

The Adventures of Me