dockerattachとdockerexecの違い


82

どちらもコンテナ内でコマンドを実行できるようになります。どちらもコンテナを取り外すことができます。

では、dockerexecとdockerattachの本当の違いは何ですか?

回答:


85

ドキュメントに追加されたコミットPRがありました:

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

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

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

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

この号で述べたように:

  • アタッチは、コンテナ内で余分なものを実行するためのものではなく、実行中のプロセスにアタッチするためのものです。
  • " docker exec"は、シェルであれ他のプロセスであれ、すでに開始されているコンテナで新しいものを実行するためのものです。

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

一方では、attach特によくあるためLXCコマンドの、名前が付いていないlxc-attach(もっと似ているdocker exec <container> /bin/shが、LXC具体的には)、それは文字通りドッカーが起動プロセスにあなたを取り付ける特定の目的を持っています。
プロセスが何であるかによって、動作が異なる場合があります。たとえば、にアタッチする/bin/bashとシェルが提供されますが、redis-serverにアタッチすると、デーモン化せずに直接redisを開始したようになります。


24

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

一方、docker execコマンドでは、入力するシェルを指定できます。コンテナのPID1には移動しません。これにより、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を使用して内部に入ろうと、コンテナーを終了してもコンテナーは停止しません。


の使用に関する興味深いアイデアnsenter。詳細を教えていただけますか?オプションの説明は順調です。すべての名前空間を入力してみませんか?なぜこれらの特定のもの?
X-ユーリ

7

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

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

私の答えは、上記のステートメントを検証し、それをより明確に理解できるようにすることに焦点を当てます。

ターミナルウィンドウを開き、コマンドを実行し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のリストを表示するPIDPPID

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

コンテナをアタッチした後、コマンドを実行してシェルセッションを作成しますshCTRL-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

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

ここで、を実行しdocker exec -it busybox shます。コンテナ内に入ると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
root                7737                7469                0                   11:43               pts/0               00:00:00            sh
root                7880                7451                0                   11:45               pts/1               00:00:00            sh

PPID第一及び第三のプロセスのは、その確認、同じになりdocker execつつコンテナの環境で新しいプロセスを作成するdocker attachだけで、現在の標準入力/出力/エラーの対応する容器内のメインプロセスの標準入力/出力/エラーを接続しますターミナル。


5

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

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.