Dockerコンテナ内で操作 attachとexecの違い

  • 66
    いいね
  • 2
    コメント

7/16 hidekuroサンからのコメントを受けて修正

Dockerのコンテナで動作中のシェルへの接続方法

sshdをコンテナ内に立てることなしにシェルに接続する方法として以下の2つがある。

  1. docker attach コンテナ名
  2. docker exec -it コンテナ名 /bin/bash

じゃあ、この2つの違いってなによ?
ということで整理してみた。

docker attach コンテナ名

こっちは単純にdockerコンテナ内で既に起動しているシェルの標準出力につなげるイメージ??

コンテナで起動しているPID=1のプロセスの標準入出力(STDIN/STDOUT)に接続(attach)する。

docker exec -it コンテナ名 /bin/bash

こっちはdockerコンテナで任意のコマンドを実行させる。
-itオプションについては意味合いは以下の通りらしい

オプション名 内容
i 標準入力(STDIN)を開いたままにする
t 擬似ttyに接続する。ディスプレイ(STDOUT)をつなぐイメージ

(結果)ログイン方法の違いによる影響

attachとexecではexitコマンドを実行した場合の挙動が違うみたい。

  • (補足) 以下の様な形でnodejs001コンテナを立ち上げている
コンテナ起動コマンド
sudo docker run -d --name nodejs001 --hostname nodejs001 -p 80:80 -i -t node /bin/bash

まあ、普通。
ポート転送やらはたまたま立ち上げたコンテナがそうだっただけなので、気にしないでね。

attachの場合

attachの場合
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS                NAMES

55905169b4b0        node                "/bin/bash"         29 hours ago        Up 11 minutes             0.0.0.0:80->80/tcp   nodejs001
$ sudo docker attach nodejs001
root@nodejs001:/#
root@nodejs001:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 13:23 ?        00:00:00 /bin/bash
root        12     1  0 13:35 ?        00:00:00 ps -ef
root@nodejs001:/# exit
exit
 sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
55905169b4b0        node                "/bin/bash"         29 hours ago        Exited (0) 4 seconds ago                       nodejs001

見てわかる通り、attachの場合は既にコンテナ内で立ち上がっているPID=1の/bin/bashに対して標準入出力を接続(attach)する形になる。

exitするとコンテナそのものが停止する。
(プライマリプロセス(PID=1)が終了するから?)

execの場合

execの場合
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
55905169b4b0        node                "/bin/bash"         29 hours ago        Up 32 seconds       0.0.0.0:80->80/tcp   nodejs001
$ sudo docker exec -it nodejs001 /bin/bash
root@nodejs001:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 13:40 ?        00:00:00 /bin/bash
root         6     0  0 13:41 ?        00:00:00 /bin/bash
root        11     6  0 13:41 ?        00:00:00 ps -ef
root@nodejs001:/# exit
exit
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
55905169b4b0        node                "/bin/bash"         29 hours ago        Up About a minute   0.0.0.0:80->80/tcp   nodejs001

こちらは新しく/bin/bashプロセスが立ち上がっており、
そちらで標準入出力を行っている。
exitしてもexecした際に実行された/bin/bashプロセス
が終了するだけなので、コンテナは停止しない。

(結論)execとattachどっちを使うべき

個人ならご自由に。

実際に外向けのサービスを使ってたり、
他の人と同一のコンテナを共同利用しているのであれば、
execの方が 不意にコンテナが止めてしまったりといったことが起きづらいため ベターだと思う。

まあ、自分が作業するシェルのプロセスくらい
拾いもんじゃなくて自分で確保せいや と言う観点では、
execの方が行儀がよろしいかなと。