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=master
or 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 kubectl
binary from a docker image into the volume. In this case, allanlei/kubectl
is 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.