RHEL/CentOS 6 上で Docker に nsinit/nsenter を使って attach する方法のメモです。
CoreOS ですと、すでに Qiita に投稿されている方がいらっしゃいます。
結論から言いますと、 util-linux に入っている nsenter を使う方がよいです。 nsinit のほうはちょっと苦労します。
util-linux に入っている nsenter を使う
Attaching to a container with Docker 0.9 and libcontainer に
書いてある方法でいけます。
ただし、 gettext を 0.18.3 以上にしないとビルドできないため、 gettext もソースからビルドします。
途中、ルーチンとエイリアス定義をしていますが、好みに応じて変更してください。
-
gettext インストール
curl -LO http://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.1.tar.xztar xf gettext-0.19.1.tar.xzcd gettext-0.19.1./configure --prefix=/opt/gettext-0.19.1make -j4 && sudo make install
-
util-linux インストール
curl -LO https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.2.tar.xztar xf util-linux-2.24.2.tar.xzcd util-linux-2.24.2CFLAGS=-I/opt/gettext-0.19.1/include LDFLAGS=-L/opt/gettext-0.19.1/lib ./configure --prefix=/opt/util-linux-2.24.2make -j4 && sudo make install
-
nsenterするためのシェルスクリプトのルーチンを~/.bashrcなどに定義するdocker_nsenter() { declare container_id=$1 if [ -z "$container_id" ]; then echo "Usage: docker_container <container_id>" >&2 return 1 fi /opt/util-linux-2.24.2/bin/nsenter --mount --uts --ipc --net --pid --target $(docker inspect --format '{{.State.Pid}}' $container_id) } alias docker-nsenter='docker_nsenter' -
source ~/.bashrcでルーチン読み込み -
docker-nsenterでプロセスに attach する-
docker psでコンテナID確認
-
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dc1681d20f84 ssh-gateway:latest /bin/sh -c /sbin/ini 8 days ago Up 6 days 0.0.0.0:49153->22/tcp suspicious_pasteur
```
* docker-nsenter <container_id> で attach
```
docker-nsenter dc16
[root@dc1681d20f84 /]#
```
docker/libcontainer に入っている nsinit を使う
こちらは CentOS の場合、現状それなりに苦労します(最初諦めた)。
nsinit を使うためには、 Go が必要です。
go get をしたあと、 Docker 1.0 では動かないため(HEAD の Docker が必要)、タグに巻き戻して パッチ をあてています。
お作法などがありそうな気がしていますが、 Go に未熟で分かっていないので、もっと良い方法がありましたら教えて下さい。
-
Go 環境をインストール
yum install golang
-
パッケージを入れるためのディレクトリ(
GOPATH) を作成mkdir /var/lib/goecho 'export GOPATH=/var/lib/go' >> ~/.bashrc; source ~/.bashrc
-
nsinitをインストール(要パッチ)- Docker v1.0 の場合
go get -d github.com/docker/libcontainer/nsinitcd $GOPATH/src/github.com/docker/libcontainergit checkout -b v1.0.1+patch v1.0.1git fetch origin refs/pull/58/headgit cherry-pick FETCH_HEADgo install github.com/docker/libcontainer/nsinit
- Docker v1.1 の場合
go get -d github.com/docker/libcontainer/nsinitcd $GOPATH/src/github.com/docker/libcontainergit checkout -b v1.1.0+patch v1.1.0git fetch origin refs/pull/58/headgit cherry-pick FETCH_HEAD-
go install github.com/docker/libcontainer/nsinit/main- 注 v1.1.0 ではコマンド構成が代わり、 github.com/docker/libcontainer/nsinit /main としないとインストールできません
mv $GOPATH/bin/main $GOPATH/bin/nsinit
- Docker v1.0 の場合
-
nsinitするためのシェルスクリプトのルーチンを~/.bashrcなどに定義するdocker_nsinit() { declare container_id=$1 if [ -z "$container_id" ]; then echo "Usage: docker_nsinit <container_id> <command> [[args]...]" >&2 return 1 fi shift declare full_container_id=$(docker inspect --format '{{.Id}}' $container_id) (cd /var/lib/docker/execdriver/native/$full_container_id && $GOPATH/bin/nsinit $*) } alias docker-nsinit='docker_nsinit' -
source ~/.bashrcでルーチン読み込み -
docker-nsinitでプロセスに attach する-
docker psでコンテナID確認
-
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dc1681d20f84 ssh-gateway:latest /bin/sh -c /sbin/ini 8 days ago Up 6 days 0.0.0.0:49153->22/tcp suspicious_pasteur
```
* docker-nsinit <container_id> exec -- bash で attach
```
docker-nsinit dc16 exec -- bash
[root@dc1681d20f84 /]#
```
なお、 nsinit に関しては、以下のエラーメッセージが表示されるというはまりを経験しました。
-
nsenter: Failed to open ns file "/proc/1408/ns/pid" for ns "pid" with error: "No such file or directory"と怒られる -
2014/06/29 23:22:06 failed to exec: bridge is not specifiedと怒られる-
Docker v1.0 において、パッチを最新の master にマージすると発生します
-
Victor Marmol によれば、
Yes, there have been a few changes to libcontainer that have not yet been integrated into Docker. If you're using libcontainer alongside Docker you must build with the version tagged for that Docker release. In this case, we've changed the checkpoint to include the network information.
とのことで、Docker 1.0 を使う場合は v1.0.1 タグにマージしないといけません。
-