web-dev-qa-db-ja.com

「docker attach」がハングするのはなぜですか?

ubuntuコンテナを正常に実行できます。

# docker run -it -d ubuntu
3aef6e642327ce7d19c7381eb145f3ad10291f1f2393af16a6327ee78d7c60bb
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
3aef6e642327        ubuntu              "/bin/bash"         3 seconds ago       Up 2 seconds                            condescending_sammet

ただし、docker attachを実行するとハングします。

# docker attach 3aef6e642327

Enterなどのキーを押すまで:

# docker attach 3aef6e642327
root@3aef6e642327:/#
root@3aef6e642327:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

docker attachがハングするのはなぜですか?

更新

コメントを読んだ後、私は答えを得ると思う:

前提条件:

"docker attach"は、新しいttyを開かずに同じttyを再利用します。

(1)デーモンモードなしでdocker runを実行する:

# docker run -it ubuntu
root@eb3c9d86d7a2:/# 

すべてが問題ない場合、lsコマンドを実行します。

root@eb3c9d86d7a2:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@eb3c9d86d7a2:/#

(2)docker runをデーモンモードで実行します。

# docker run -it -d ubuntu
91262536f7c9a3060641448120bda7af5ca812b0beb8f3c9fe72811a61db07fc

実際には、以下は実行中のコンテナから標準出力に出力されているはずです:

root@91262536f7c9:/#

docker attachの実行はハングしているように見えますが、実際には入力を待っています:

# docker attach 91262536f7c9
ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@91262536f7c9:/#
51
Nan Xiao

実際にはhangではありません。下のコメント(コマンドとして "/bin/bash"を実行している)でわかるように、アタッチするときの予想される動作のようです。

私が理解している限り、実行中のシェルとstdin/stdout/stderrに接続します-runコマンドとともに渡すオプションに応じて-出入りするものを表示しますその瞬間から。 (もう少し深い知識を持っている人は、これをより高いレベルで説明できます)。

あなたの質問に対する私のコメントで書いたように、docker githubレポジトリで同様の動作を説明する問題を開いた人々が何人かいます:

あなたがシェルに言及しているので、私はあなたがすでに実行しているシェルを持っていると仮定します。 attachは新しいプロセスを開始しないので、実行中のプロセスのin/out/errストリームに接続する場合の予想される動作は何ですか?私はこれについて考えませんでした。もちろん、これは実行中のシェルにアタッチすることで予想される動作ですが、望ましいのでしょうか?

Docker attachでstdout/stderrをフラッシュして、シェルプロンプトを強制的に印刷することは可能なのでしょうか、それとも少し複雑ですか?それは、すでに実行中のシェルに接続するときに個人的に「期待」することです。

必要に応じてこの問題を解決してください。これを文書化し、フィードバックを得る必要があると感じました。

  • この github issueコメント から取られました。この問題のコメントでより多くの洞察を見つけることができます。

enterの代わりにコマンドの入力を開始する場合、extra空のプロンプト行は表示されません。実行する場合

$ docker exec -it ubuntu <container-ID-or-name> bash 

<container-ID-or-name>は、docker run -it -d ubuntuを実行した後のコンテナのIDまたは名前です(したがって、質問では3aef6e642327またはcondescending_sammet)。newコマンドを実行します。したがって、既存の問題にアタッチするというこの「標準的な問題」はありません。

次を含むディレクトリにDockerfileがある場合:

FROM ubuntu:latest
ADD ./script.sh /timescript.sh 
RUN chmod +x /timescript.sh
CMD ["/timescript.sh"]

そして、以下を含む同じディレクトリに単純なbashスクリプトscript.shを用意します。

#!/bin/bash

#trap ctrl-c and exit, couldn't get out
#of the docker container once attached
trap ctrl_c INT
function ctrl_c() {
    exit
}

while true; do
    time=$(date +%N)
    echo $time;
    sleep  1;
done

次に、(この例ではDockerfileおよびscript.shと同じディレクトリに)ビルドして実行します

$ docker build -t nan-xiao/time-test .
..stuff happening...
$ docker run -itd --name time-test nan-xiao/time-test

最後にattach

$ docker attach time-test

あなたは毎秒時間を印刷するコンテナに接続されてしまいます。 (CTRL-Cで抜ける)

例2

または、たとえば次を含むDockerfileがある場合:

FROM ubuntu:latest
RUN apt-get -y install irssi
ENTRYPOINT ["irssi"]

次に、同じディレクトリで実行します。

$ docker build -t nan-xiao/irssi-test .

それを実行します:

$ docker run -itd --name irssi-test nan-xiao/irssi-test

そして最後に

$ docker attach irssi-test

この特定の動作なしで、実行中のirssiウィンドウになります。もちろん、irrsiを別のプログラムに置き換えることができます。

他の誰かが開発し、すでにデーモンを実行しているコンテナにアタッチしようとしたときにも、この問題に遭遇しました。 (この場合、それはLinuxServerのtransmission dockerイメージでした)。

問題:

起こったのは、端末が「ハング」しているように見えることで、何も入力しても役に立たず、表示されません。 Ctrl-Cのみが私を追い出します。

docker rundocker startdocker attachすべてが成功しなかったため、(コンテナがrunまたはstartで開始された後)必要なコマンドが判明しましたbashを実行します。これは、プルしたコンテナに既にbashが実行されていない可能性があるためです。

解決:

docker exec -it <container-id> bash

(実行中のcontainer-idからdocker ps -aを見つけることができます)。

これにより、rootとして機能するbashを使用してインスタンスに引き込まれます(引き出されたイメージによって他の明示的なセットアップが行われなかったと仮定)。

受け入れられた答えもこれを捕らえたことを知っていますが、私が読んでいたときに解決策が出てこなかったので、もう少し簡潔で明白な別の答えを投稿することにしました。

14
matrixanomaly

docker attach container-nameを実行すると、何も出力されず、Ctrl-cも無効です。だから、最初に試してください

docker attach container-name --sig-proxy=false

ctrl-cで停止できます。何も出力しなかったのはなぜですか?コンテナが出力しないからです。実際に、コンテナを入力して、シェルコマンドを実行する必要があります。正しいコマンドは

docker exec -ti container-name bash
1
Billy Yang

これは、次の理由で一度起こりました。

コンテナ内のbashコマンドが「cat」コマンドを実行している可能性があります。

したがって、コンテナ(bashコマンド)にアタッチすると、実際にはcatコマンドの内部にいますが、これは入力を期待しています。 (ファイルを書き込むためのテキストおよび/またはctrl-d)

1
HerbalMart

私は今日同様の問題を抱えていて、それを修正することができました:

これは私のために起こっていたことです:

docker-compose logs -f nginx
Attaching to laradock_nginx_1

それから、CTRL-Cで終了するまでそこにハングアップします:^CERROR: Aborting.

docker ps -aは、その画像名にはlaradock_nginxと呼ばれるべきものが存在しないことを示したので、そのコンテナを削除して「アップ」するだけだと考えました。

docker stop cce0c32f7556
docker rm cce0c32f7556
docker-compose up -d laradock_nginx

残念ながら:ERROR: No such service: laradock_nginx

そこでSudo rebootを実行し、次にdocker ps -aを実行しましたが、laradock_nginxはまだありませんでした。

幸いなことに、docker-compose up -d nginxが動作し、docker-compose logs -f nginxが動作するようになりました。

0
Ryan

コマンドラインにアクセスできない場合は、開始時に-iフラグを使用してコンテナを実行してください。

0
Ali Motameni