どちらもコンテナ内でコマンドを実行できるようになります。どちらもコンテナを取り外すことができます。
では、dockerexecとdockerattachの本当の違いは何ですか?
回答:
ドキュメントに追加されたコミット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を開始したようになります。
コンテナーが/ 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を使用して内部に入ろうと、コンテナーを終了してもコンテナーは停止しません。
マイケルサンが彼の答えで述べたように
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
もちろん、PID
、PPID
およびその他の値は、あなたのケースでは異なるであろう。あなたは、同様のような他のツールやユーティリティを使用することができpstree
、top
、htop
のリストを表示するPID
とPPID
。
PID
そしてPPID
プロセス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
ただし、PPID
2つのプロセスは異なります。実際、PPID
2番目のプロセス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
だけで、現在の標準入力/出力/エラーの対応する容器内のメインプロセスの標準入力/出力/エラーを接続しますターミナル。
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つの新しいプロセスが開始され、それらは相互に関連せず、メインプロセスにも関連しないため、安全に終了できます。 。
nsenter
。詳細を教えていただけますか?オプションの説明は順調です。すべての名前空間を入力してみませんか?なぜこれらの特定のもの?