Beliebte Suchanfragen
|
//

How to enter a Docker container

20.7.2014 | 4 minutes of reading time

In previous articles [1 ,2 ,3 ] Lukas Pustina has given an introduction to system-level virtualization with Docker. In this article I discuss 4 options how to connect to a running Docker container and interact with it. All code examples are available on GitHub so you can try yourself.

nsenter

The nsenter tool is part of the util-linux package since version 2.23. It provides access to the namespace of another process. nsenter requires root privileges to work properly. Unfortunately, util-linux is still at version 2.20 in Ubuntu 14.04. To install the latest version (2.24) proceed as follows:

1cd /tmp
2curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-
3cd util-linux-2.24
4./configure --without-ncurses
5make nsenter
6cp nsenter /usr/local/bin

In order to connect to a container, you have to find out the PID of the first process in the container.

1docker inspect --format "{{ .State.Pid }}" <container-id>

With that PID you can connect to the container:

1nsenter --target $PID --mount --uts --ipc --net --pid

nsinit

Since version 0.9 Docker offers its own library for managing containers called libcontainer. The tool nsinit of the libcontainer allows the user direct access to the linux namespace and cgroup kernel features. Before you can install nsinit you have to install the Go runtime environment:

1apt-get install git golang-go
2 
3mkdir -p $HOME/go-dev/bin
4mkdir -p $HOME/go-dev/src
5 
6echo "export GOPATH=\$HOME/go-dev" >> ~/.profile
7echo "PATH=\$PATH:\$GOPATH/bin" >> ~/.profile
8 
9source ~/.profile

In a second step, you install nsinit:

1mkdir -p $GOPATH/src/github.com/dotcloud
2cd $GOPATH/src/github.com/dotcloud
3 
4git clone https://github.com/dotcloud/docker.git
5cd $GOPATH/src/github.com/dotcloud/docker
6 
7/usr/bin/go get -v github.com/dotcloud/docker/vendor/src/github.com/docker/libcontainer/nsinit

nsinit reads the configuration data from the container directory located in /var/lib/docker/execdriver/native/. In order to use nsinit you have to change into that container directory. This requires root privileges because the directory /var/lib/docker is only readable for root. The container id can be determined with the docker ps command. Once you stepped into the directory you can connect to the container:

1nsinit exec /bin/bash

lxc(-attach)

Up to version 0.8.1 LXC was the base for Docker to manage containers and Docker still supports it. But since version 0.9.0 Docker uses libcontainer by default, cutting the dependency to LXC. Thus, you cannot use lxc-attach by default anymore.

If you still want to use lxc-attach you have to restart the Docker daemon with the -e lxc option. With this option Docker will use LXC under the hood again. The easiest way to do so, is to create the file /etc/default/docker (if it does not exist yet) and add the following line:

DOCKER_OPTS=”-e lxc”

Now you have to restart the Docker daemon. To connect to a container you need the full container id:

1docker ps --no-trunc

Now you can connect to the container. For this to work, root privileges are needed again:

1lxc-attach -n <container-id> -- /bin/bash

sshd

The three previous methods all require root privileges on the host system. To avoid that, accessing containers via SSH is a good alternative.

For that you need to build a base image supporting an SSH daemon. At this point we run into the problem that we can only execute one command with the Docker keywords CMD or ENTRYPOINT. If this were the sshd process we could not run any other process. A workaround is to create a script to start all necessary other processes or to use a process management tool like supervisord. There is excellent documentation on how to use supervisord on the Docker website. Once you have started a container with a sshd process, you can connect as usual with a ssh client.

Fazit

The sshd approach is probably the easiest one and the most users are accustomed to connect to a virtual machine via ssh. In addition, you also do not need root privileges in order to connect with a container. However, there are a lot of discussions [1 ,2 ] about whether a container should manage more than one process or not. In the end, you have one additional sshd process per container which is basically not the idea of ​​process virtualization.

For the other three options, root privileges are required. Docker has used LXC to manage its containers up to version 0.8.1. For this reason, it was pretty easy to use lxc-attach. Since version 0.9.0 the Docker daemon must be started with the option -e lxc for still using LXC under the hood. But with this option set, Docker relies on LXC again which might vary across distributions or installations.

nsenter and nsinit are basically equivalent. The main difference between both tools is that nsinit will setup a new process in the container and nsenter will just enter the namespace. Jerome Petazzoni has described it very well in the Docker Blog .

|

share post

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.