Edited at

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

More than 3 years have passed since last update.

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の方が行儀がよろしいかなと。