はてブでつっこみもらいました が、実行するカレントディレクトリは /var/lib/docker/execdriver/native/$id を使うのが正しいようです。(情報読み違えてた。)こちらには container.json
があるので、ソースツリーからコピーしてくる必要ないですね。
また、コンテナ ID 取得は、docker ps -q --no-trunc
の方が良い、とも教えていただきました。
つっこみにしたがって、最後の方の説明とシェル関数書き換えました。
つっこみありがとうございます!
タイトルまま
Docker でつくったコンテナの中に入って状態を確認するために、コンテナ内で sshd を立ち上げてアクセスする、ってなことを以前やってたんですが、コンテナ内で sshd を立ち上げる、というやり方がいまいちだし、そもそもコンテナの仕組みから考えれば、別に sshd を立ち上げなくても、コンテナと同じ namespace と rootfs に bash なりのプロセスを閉じ込めてやれば良いわけで、そういったことは既に考えている人はいるだろうし、ツールとかありそうだな、ってことで、
Dockerで中を見たいコンテナのPID namespaceとchrootをカレントシェルに割り当てることが簡単にできるようなツールがあれば、中でsshとか立てなくていいかな。
— Gosuke Miyashita (@gosukenator) June 18, 2014
とつぶやいてみたら、
@gosukenator nsenter -- chroot /bin/bash とかでいけないですかねー
— TenForward (@ten_forward) June 18, 2014
と、nsenter なるものの存在を教えて頂いた。
@gosukenator nsenter はちょっと新しい util-linux にしかないので、ソースからコンパイルする必要あると思います。
RHEL/CentOS7 は知らないですけど、Ubuntu 14.04 にはありませんでした。
— TenForward (@ten_forward) June 18, 2014
で、これを見るとちょっと面倒かな、と思ったけど、
@gosukenator docker 的にはそのページに書かれている nsinit を使うのが正解かもしれませんね。docker のソースツリーに入ってるツールですし :-)
(nsinit すっかり忘れてた)
— TenForward (@ten_forward) June 18, 2014
この nsinit は golang 製なので、golang が動く環境であれば go get で入れることができて楽そうなので、nsinit を試してみることにした。
golang 環境は既に整っていて、GOPATH が設定されていて、PATH に $GOPATH/bin が含まれている、という前提。
go get
で nsinit
を入れる。
$ go get github.com/docker/libcontainer/nsinit
こんな感じで実行。
$ sudo -s
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
917756ba04a2 ubuntu:14.04 /bin/bash 51 minutes ago Up 51 minutes lonely_tesla
# cd /var/lib/docker/execdriver/native/9177*
# nsinit exec /bin/bash
daemon@koye:/$
cd して nsinit、ってやるのは、一般ユーザからだとパーミッションの関係でタブ補完が効かなくてだるいので、シェル関数書いてみた。
docker-attach()
{
id=`sudo docker ps -q --no-trunc $1`
root=/var/lib/docker/execdriver/native/$id
sudo sh -c "cd $root && $GOPATH/bin/nsinit exec $2"
}
この関数つかって、コンテナIDと実行するプログラムを与えれば、一発でコンテナの中に入れて便利。
vagrant@vagrant:~$ docker-attach 9177 /bin/bash
daemon@koye:/$
daemon@koye:/$ ps -ef
UID PID PPID C STIME TTY TIME CMD
daemon 1 0 0 10:38 ? 00:00:00 /bin/bash
daemon 14 1 0 10:44 ? 00:00:00 ps -ef