1. Introduction
Some container images are configured with non-superusers as their default user. So, when we create Kubernetes deployments with such images, we may be unable to run commands that require root access. Of course, not being able to run our desired commands in a pod can be frustrating. Fortunately, there’s a way around this limitation.
In this tutorial, we discuss how to execute commands as root on Kubernetes pods when the default user is a non-superuser.
2. Using docker exec
When we run a command that requires superuser privilege on this pod whose default user is not a superuser, we get a Permission denied error:
$ kubectl exec -it baeldung-75ffbb8556-kvbnq -- bash -c "apt update"
Reading package lists... Done
W: chmod 0700 of directory /var/lib/apt/lists/partial failed - SetupAPTPartialDirectory (1: Operation not permitted)
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
command terminated with exit code 100
We could’ve tried using sudo, but this container does not have it installed. Plus, as seen above, we might not even be able to install it without root access. And even if we could install sudo, we may not be able to add the user to the sudo group. So, in fewer words, sudo may be of no help in this situation; we need to gain root access.
To gain root access in a Kubernetes pod using docker exec, we must have access to the node running the pod. Then once in the node, we must get the pod’s container ID first.
By adding a few options to the regular kubectl get pod command and filtering the output with sed, we can get a pod’s container ID:
$ kubectl get pods [podname] -o jsonpath={.status.containerStatuses[].containerID} | sed 's/docker:\/\///'
Using the command above helps us get our pod’s container ID without having to sift through so much information.
Let’s try it out on our pod:
$ kubectl get pods baeldung-75ffbb8556-kvbnq -o jsonpath={.status.containerStatuses[].containerID} | sed 's/docker:\/\///'
3d35bf9c2d1c4817ddb69c627ee219ab5a9902e34f7781bba1bb2028549f3201
Once we have the container ID, we gain root access using docker exec:
$ docker exec -it -u root 3d35bf9c2d1c4817ddb69c627ee219ab5a9902e34f7781bba1bb2028549f3201 bash
root@baeldung-75ffbb8556-kvbnq:/#
We’re also able to run commands requiring root access from outside the pod’s terminal:
$ docker exec -it -u root 3d35bf9c2d bash -c "apt update"
Hit:1 http://deb.debian.org/debian bookworm InRelease
Hit:2 http://deb.debian.org/debian bookworm-updates InRelease
Hit:3 http://deb.debian.org/debian-security bookworm-security InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
Of course, we can combine the docker exec and kubectl get pods commands into a single command:
$ docker exec -it -u root $(kubectl get pods [podname] -o jsonpath={.status.containerStatuses[].containerID} | sed 's/docker:\/\///') bash
Let’s see it in action:
$ docker exec -it -u root $(kubectl get pods baeldung-75ffbb8556-kvbnq -o jsonpath={.status.containerStatuses[].containerID} | sed 's/docker:\/\///') bash
root@baeldung-75ffbb8556-kvbnq:/#
As we can see, when we use both sets of commands in one go, we get the same results as before.
3. Configuring the Container to Run With root User by Default
The option we described in the previous section will come in handy when we only need temporary root access. But if we need continuous root access, we can configure the container to run as root from the start:
apiVersion: v1
kind: Pod
metadata:
name: baeldung
spec:
containers:
- name: baeldung
image: jenkins:2.60.3
securityContext:
runAsUser: 0
runAsGroup: 0
In the manifest above, setting runAsUser to 0 and runAsGroup to 0 under securityContext configures the pod to run as root user and root group, respectively.
So, when we run kubectl apply -f on that manifest and go into the pod’s terminal, we have root access from the start:
$ kubectl exec -it baeldung -- bash
root@baeldung:/#
We should note that running a container as the root user is not advised as it poses potential security threats. So, when we do this, we try to weigh the benefits against the downsides first.
4. Conclusion
In this article, we talked about how to gain root access in non-superuser Kubernetes pods. Then, we looked at how to configure a non-superuser pod to run as the root user by default.