dockerでいろいろ実験
dockerでコンテナを作っていろいろ実験などをしていると、シェルでコンテナに入りたくなる場合が結構あります。
dockerにはattach
というコマンドがあります。
このコマンドでコンテナのシェルに入れると説明されている時がありますが、このコマンドではシェルに入ることはできません。
コンテナが予めシェル起動状態で作られ起動されていれば、attach
コマンドでシェルに入ることは可能です。
しかし普通、コンテナの多くはなにかのプロセスを動かす為のもので、シェルログインされることを想定されていないですよね。
ですのでattach
しても、それらのプロセスが吐くログが表示されたり、全くの黒画面だけという状態になることがほとんどかと思います。
attach
はあくまでも-d
(dettach状態)で作成起動したコンテナをフォアグランドに戻すためのコマンドのようです
ssh
で入るという話も見かけますが、コンテナに余計なプロセスを動かすのはなんとも悪手だと思います。
コンテナにシェルで入りたい時はexec
コマンドを使いましょう。
たぶんexecuteの略ですよね多分。名前の通りコンテナに対してコマンドを実行してくれるコマンドです。
コンテナに入ってみる
例えばMySQLコンテナを作ってシェルに入る例です。
attachを使った場合
最初にattach
を使った場合を見てみます。
# docker run -d --name testdb -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=testdb mysql
e9435ea08d1e7051bce4fda61067464204f65ab2c451286d9e4a73d68b6add7b
# docker attach testdb
//なにも表示されない
公式のMySQLコンテナはシェル起動がされませんし、もしattach
を実行しても何も表示されません。もちろん何の入力も受け付けてもらえません。
もし-i
オプションや-t
オプションを付けて起動してもログが表示されますが、シェルには入れません。
# docker run -it -d --name testdb -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=testdb mysql
08bbab5d4286273b72e023f3eb532616be0f6402d445e27d039ade028d323e7e
# docker attach testdb
Database initialized
MySQL init process in progress...
2016-09-03T04:05:09.396786Z 0 [Note] mysqld (mysqld 5.7.10) starting as process 38 ...
2016-09-03T04:05:09.401114Z 0 [Note] InnoDB: PUNCH HOLE support available
2016-09-03T04:05:09.401157Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
〜〜〜〜〜
〜〜〜〜〜
〜〜〜〜〜
もしattach
でコンテナのシェルに入れるとしたら最初からシェルを起動してコンテナを作った場合です。
# docker run -it -d --name testdb -e MYSQL_ROOT_PASSWORD=pass -eMYSQL_DATEBASE=testdb mysql /bin/bash
53f1cf70c7dee33a9d88a64dac3fd6208c0bdb74cbff4063e31055cb9ca37068
# docker attach testdb
root@53f1cf70c7de:/#
確かにシェルに入れていますが、Dockerfile
で定義されているコンテナのデフォルトコマンドを/bin/bash
で書き換えてしまっていることになるため、このコンテナではmysqld
が動いていません。
データベースコンテナなのに、これでは本末転倒です。
root@53f1cf70c7de:/# ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 20244 3288 ? Ss 04:10 0:00 /bin/bash
root 6 0.0 0.0 17496 1988 ? R+ 04:14 0:00 ps auxf
docker execコマンドを使った場合
exec
を使って以下のようにコンテナに入ることができます。
# docker run -d --name testdb -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=testdb mysql
e9435ea08d1e7051bce4fda61067464204f65ab2c451286d9e4a73d68b6add7b
# docker exec -i -t testdb /bin/bash
root@e9435ea08d1e:/#
コンテナ作成時にコマンドを上書きしていないのでちゃんとmysqld
が動いている状態です。
root@e9435ea08d1e:/# ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
mysql 1 0.0 3.0 1578432 181008 ? Ssl 03:57 0:01 mysqld
root 111 0.0 0.0 20224 3100 ? Ss 04:14 0:00 /bin/bash
root 115 0.0 0.0 17500 2048 ? R+ 04:15 0:00 ps auxf
これでコンテナの機能を阻害せずにコンテナに自由に入ることができますね。
おまけ
execはコマンド実行のコマンドなので、もちろんシェル起動以外にもコンテナにさまざまなコマンドを発行することが可能です。
# docker exec -it testdb ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 116 0.0 0.0 17496 2088 ? Rs+ 04:23 0:00 ps auxf
mysql 1 0.0 3.0 1578432 181008 ? Ssl 03:57 0:01 mysqld
ですので、sshで入ったり、変にシェル起動させたコンテナを作らなくても、execコマンドで簡単にコンテナ操作が行えます。
dockerでいろいろ実験するときの強い味方になると思いますよ。
まとめ
- attachコマンドではシェルに入れない
- シェル起動してコンテナを作るともともとのコンテナのプロセスが立ち上がらない場合がある
- コンテナに入りたい時はexecコマンドでシェルを起動して入る
- execコマンドではいろんなコマンド実行が可能