Containers are great! They encapsulate a complete system; when configured correctly they are secure and if they run once, they run everywhere.
When it comes to debugging things, containers start to get complicated. If e.g. a container is build running as a non root user and you docker exec
into it, but the container does not have sudo
or netstat
installed and you want to see its current network properties like open ports, how do you do that? Or if you want to see the environment variables that were injected to the container and the container was started with?
One way to do that would be to copy a static binary of e.g. netstat
into the container and fiddle with root privileges. I asked myself (and Google): Is there not a better way to do something like that?
nsenter
to the rescue! With this command (you have to be root for that) you enter the so called namespace of a process on the host. All that you have to know is the PID of the process with e.g. ps aux | less
. See the following example:
## Enter Process namespace, and attach to network namespace of given PID
nsenter -t $PID -n
After executing the script you just see a (new) plain shell. And now you can execute netstat
to see, if all ports that you wished for are open and listening. To leave the namespace just type exit
or CTRL-D
and you are back in the original shell.
But as written earlier, it is also possible to enter the specific environment of a container. See the following example:
# Enter process namespace with the environment variables set
sudo /usr/bin/nsenter --target $PID --mount --uts --ipc --net --pid env -i - $(sudo cat /proc/$PID/environ | xargs -0) bash
Given a process PID and executing that script, you are in a new shell showing even the environment variables that were given, when starting the process - awesome 🥳!
Last but not least a little helper script that is also available as a Gist here
# Copy&paste the following snippet to a machine to create a script that enters a namespace of a given PID with environment set: ./dockerEnter 1234
echo "sudo /usr/bin/nsenter --target \$1 --mount --uts --ipc --net --pid env -i - \$(sudo cat /proc/\$1/environ | xargs -0) bash" > enterDocker.sh; chmod +x enterDocker.sh;
For detailed information see man nsenter
!
Top comments (0)