web-dev-qa-db-ja.com

docker attachとdocker execの違い

どちらもコンテナでコマンドを実行できます。両方ともコンテナを取り外すことができます。

では、docker execとdocker attachの本当の違いは何ですか?

65
MJL

commit PR がドキュメントに追加されました:

注:このコマンド(attach)は、コンテナで新しいプロセスを実行するためのものではありません。 docker execを参照してください。

Docker。実行済みコンテナ(run -d)内でbash\sshを取得する方法? 」に対する答えは、違いを示しています。

(docker> = 1.3) docker attach を使用する場合、シェルのインスタンスを1つだけ使用できます
したがって、コンテナのシェルの新しいインスタンスで新しいターミナルを開く場合は、単に docker exec を実行する必要があります。

dockerコンテナーが/bin/bashコマンドを使用して開始された場合、attachを使用してアクセスできます。そうでない場合は、コンテナー内にbashインスタンスを作成するコマンドexecuteが必要ですexecを使用します。

この問題 で述べたように:

  • 添付は、コンテナ内で余分なものを実行するためではなく、実行中のプロセスに添付するためのものです。
  • docker exec」は、シェルまたはその他のプロセスであっても、すでに開始されたコンテナで新しいことを実行するためのものです。

同じ問題が追加されます:

attachは、特にLXCコマンドlxc-attach(これはdocker exec <container> /bin/shに似ていますが、LXC固有です)のために適切な名前が付けられていませんが、 Dockerプロセスが開始されました。
プロセスによって、動作は異なる場合があります、たとえば、/bin/bashにアタッチするとシェルが提供されますが、redis-serverにアタッチするとユーザーのようになります ' dはデーモン化せずにredisを直接開始しました。

73
VonC

/ bin/bashを使用してコンテナーを開始すると、コンテナーになりますPID 1であり、コンテナーのPID 1の内部に入るためにdocker attachが使用されます。 docker attach <container-id>は、コンテナの起動時に説明したように、PID 1であるため、bashターミナル内に移動します。コンテナを終了すると、コンテナが停止します。

一方、docker execコマンドでは、入力するシェルを指定できます。コンテナのPID 1には移動しません。これにより、bashの新しいプロセスが作成されます。 docker exec -it <container-id> bash。コンテナを終了しても、コンテナは停止しません。

nsenterを使用して、コンテナ内に入ることもできます。 nsenter -m -u -n -p -i -t <コンテナーのpid>コンテナーのPIDを見つけるには、docker inspect <container-id> | grep PID

注: -dフラグを使用してコンテナを起動した場合、attachまたはexecを使用して内部に入るために、コンテナを終了してもコンテナは停止しません。

18

Docker execは新しいコマンドを実行し、コンテナの環境で新しいプロセスを作成しますが、docker attachは、コンテナ内のメインプロセス(PID 1)の標準入力/出力/エラーを対応する現在の標準入力/出力/エラーに接続するだけですターミナル(コマンドの実行に使用しているターミナル)。

コンテナは隔離された環境であり、いくつかのプロセスが環境で実行されています。具体的には、コンテナには、ホストや他のコンテナから隔離された独自のファイルシステムスペースとPIDスペースがあります。 「docker run –it…」を使用してコンテナを起動すると、メインプロセスは擬似ttyとSTDINを開いたままにします。 ttyモードでアタッチすると、構成可能なキーシーケンスを使用してコンテナからデタッチ(および実行したまま)できます。デフォルトのシーケンスはCTRL-p CTRL-qです。 --detach-keysオプションまたは構成ファイルを使用して、キーシーケンスを構成します。 docker attachを使用して、切り離されたコンテナに再接続できます。

Docker execは、コンテナの環境内で、つまりコンテナのPIDスペースに属する新しいプロセスを開始するだけです。

たとえば、「docker run –dit XXX/bin/bash」を使用してコンテナを起動する場合、2つの異なるターミナルを使用してコンテナ(メインプロセス)に接続できます。一方の端末で入力している間、両方の端末が同じttyに接続されているため、もう一方の端末に表示されます。コンテナのメインプロセスにいることに注意してください。「exit」と入力すると、コンテナが終了します(したがって、detach-keysを使用してデタッチする)。両方の端末が終了しました。しかし、2つのターミナルで「docker exec –it XXX/bin/bash」を実行すると、コンテナ内で2つの新しいプロセスが開始され、それらは互いに関連せず、メインプロセスにも関連せず、安全に終了できます。

2
Michael.Sun

マイケル・サンが答えで述べたように

docker execは新しいコマンドを実行し、コンテナの環境で新しいプロセスを作成しますが、docker attachはコンテナ内のメインプロセス(PID 1)の標準入力/出力/エラーを対応する標準入力に接続するだけです。現在の端末(コマンドの実行に使用している端末)の/ output/error。

私の答えは、上記の声明を検証し、より明確に理解できるようにすることに焦点を当てます。

ターミナルウィンドウを開き、docker run -itd --name busybox busybox /bin/shコマンドを実行します。このコマンドは、busyboxがまだ存在しない場合、イメージをプルします。次に、このイメージを使用して、busyboxという名前のコンテナーを作成します。

docker ps -a | grep busyboxコマンドを実行して、コンテナのステータスを確認できます。

docker top busyboxを実行すると、次のような出力が表示されます。

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh

もちろん、PIDPPIDおよびその他の値はあなたの場合は異なります。 pstreetophtopなどの他のツールやユーティリティを使用して、PIDおよびPPIDのリストを表示できます。

PIDPPIDは、プロセスIDと親プロセスIDを意味します。プロセスは、/bin/shコマンドを使用してコンテナを作成および開始したときに開始されました。ここで、コマンドdocker attach busyboxを実行します。これにより、コンテナの標準入力/出力/エラーストリームが端末に接続されます。

コンテナをアタッチしたら、shコマンドを実行してシェルセッションを作成します。 CTRL-p CTRL-qシーケンスを押します。これにより、ターミナルがコンテナから切り離され、コンテナの実行が維持されます。 docker top busyboxを実行すると、リストに2つのプロセスが表示されます。

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh

ただし、2つのプロセスのPPIDは異なります。実際、2番目のプロセスのPPIDは、最初のプロセスのPIDと同じになります。最初のプロセスは、作成したシェルセッションの親プロセスとして機能します。

次に、docker exec -it busybox shを実行します。コンテナ内に入ったら、コマンドdocker top busyboxを実行して、別のターミナルウィンドウでコンテナbusyboxの実行中プロセスのリストを確認します。このようなものが見えるはずです

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh
root                7880                7451                0                   11:45               pts/1               00:00:00            sh

1番目と3番目のプロセスのPPIDは同じです。これにより、docker execはコンテナの環境に新しいプロセスを作成し、docker attachは標準の入力/出力/エラーを接続するだけです。現在の端末の対応する標準入力/出力/エラーに対応するコンテナ内のメインプロセス。

1
Kartik Chauhan