K3s, containerd and root shell access to a container

When installing Rancher’s K3s on a “containerd”-based platform (so not using Docker to run your containers), it might not be as obvious as one expects to gain root access inside the containers.

But why might you need this at all? Typically, in a Kubernetes environment you’ll not be in touch with the containers directly, and that’s a good thing. But sometimes you might need to diagnose some problem, or things didn’t work out as expected (like having wrong permissions on a PV, so that the de-privileged software in the container cannot write to that storage). And sometimes, even if you can start a shell inside the container using i. e. “kubectl exec -ti <podname> — sh” (or similar, depending on what shell is available in the specific container), you may find yourself running the shell with a non-root user and no way to up your privileges (no “su” binary, no root password, or similar).

Were you using “docker”, you could jump to the machine running the container and call “docker exec -ti -u 0 sh“, or use the “-u 0” parameter to “crictl” if it were supported with k3s.

But what to do if you’re running K3s based on containerd and your “crictl” does not offer the required flags? You can use “runc”, but you will have to know where your towl is^W^W^W the container state root directory is placed (it’s “/run/containerd/runc/k8s.io” in my case):

Use “k3s crictl ps” to fetch the (short) ID of the container you need to shell into, then “runc --root <state root dir> list” to fetch the long ID of the container (it’ll start with the short ID” used by crictl), and then call:
runc --root <state root dir> exec -t -u 0 <log id> sh

Of course, if you need to run a different command than “sh”, give that as the parameter to “runc exec”, followed by any required parameters.

This entry was posted in Linux and tagged , . Bookmark the permalink.

Leave a Reply