実行中のコンテナーでシェルセッションを開始することは可能ですか(sshなし)


341

私はこのコマンドが実行中のコンテナーでbashシェルを実行することを単純に期待していました:

docker run "id of running container" /bin/bash

それは不可能のようです、私はエラーを受け取ります:

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

したがって、実行中のコンテナでbashシェルを実行したい場合(診断目的など)

その中でSSHサーバーを実行し、ssh経由でログインする必要がありますか?


1
docker run CONTAINER1.0で計画されています
kolypto 2014年

7
docker 1.3以降は、この回答に
Thomasleveil 2014年

1
ただdocker attach container_name
maxbellec 2015

1
今日では、2番目の回答の方が、容認された回答よりもはるかに優れているように見えます。受け入れられた回答を変更することを再検討していただけませんか?
jsbueno 2015年

回答:


285

編集:今docker exec -it "id of running container" bashdoc)を使用できます

以前は、この質問に対する答えは次のとおりでした。

本当に必要で、デバッグ環境にいる場合は、これを行うことができますsudo lxc-attach -n <ID> 。idは完全なもの(docker ps -notrunc)である必要があることに注意してください。

ただし、これはお勧めしません。

注意:-notruncは非推奨です--no-trunc。まもなく置き換えられます。


1
なぜあなたはそれに反対するのですか?
Max L.

7
1)それは非常に最近のカーネルを必要とする、2)あなたはそれを追跡することができないようにドッカーの外で何かをしている(ログ、アタッチなど)ので、私はそれをお勧めしません。また、Dockerは現在lxcを使用している可能性がありますが、永久に使用できる保証はありません。
2013

1
0.7.6にアップデートしてください。Dockerは現在lxcを使用しており、lxc-attach問題なく動作するはずです。私はダブルチェックしただけでうまくいきました。(カーネル3.8以前では機能しないことに注意してください)。
2014年

2
0.9の時点で、DockerはデフォルトでLXCで実行されなくなりました。次のdocker -d -e lxc
コマンドでdocker deamon

2
Max L.、あなたのユースケースはデータボリュームで解決できます。テストされていない例:1)データボリューム内のnginxログでコンテナーを実行しますdocker run -v /var/log/nginx -name somename imagename command。2)別のコンテナーを実行して、データボリュームのコンテンツを表示しますdocker run -volumes-from somename -i -t busybox /bin/sh
ciastek 14年

615

docker 1.3では、新しいコマンドがありdocker execます。これにより、実行中のDockerに入ることができます。

docker exec -it "id of running container" bash

2
これは私にとってはうまくいきました。docker runに非常に役立つ追加。
oraserrata 14

実行中のコンテナーの実行中に変更を加え、その変更をオンラインで反映したい場合はどうなりますか?ベストプラクティスは何ですか?
mediaroot

非常に便利。ありがとう
luongnv89

docker ps実行中のインスタンスのIDを取得するために使用
muon

注:コンテナにbashがない場合があります(»exec: "bash":実行可能ファイルが見つかりません«)。使用docker inspect <image>可能なシェルを確認するために使用します。たとえば、docker exec -it <container id> /bin/sh代わりに実行します。
pixelbrackets

14

するだけ

docker attach container_name

コメントで述べたように、コンテナを停止せずに切り離すには、Ctrlpthenと入力しCtrlqます。


5
ありがとう!! それは役に立ちました。そして、実際の質問に関連して、私は何かを追加したいと思います。を使用してコンテナをデバッグした後、の代わりにおよびをdocker attach container_name使用ctrl pctrl qますexitexitコマンドでは、などの容器を停止させctrlpそしてctrl qちょうどそのコンテナをデタッチし、実行していることを保持します
鳳凰

10

状況は変化しているため、現時点では、実行中のコンテナにアクセスするための推奨される方法はを使用することnsenterです。

詳細については、このgithubリポジトリをご覧ください。ただし、一般的には次のようにnsenterを使用できます。

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

または、ラッパーを使用できますdocker-enter

docker-enter <container_name_or_ID>

このトピックに関する良い説明は、JérômePetazzoniのブログエントリ にあります。Dockerコンテナーでsshdを実行する必要がない理由


残念ながら、env変数はこのアプローチを使用するとめちゃくちゃになります(リンクで作成された変数をチェックする場合)。することをお勧めしsource /proc/*/environます。
Tomas Tomecek 2014年

8

実行できない最初のこと

docker run "existing container" command

このコマンドはコンテナーではなくイメージを期待しているので、とにかく新しいコンテナーが生成されます(したがって、確認したいコンテナーではありません)。

dockerを使用すると、別の方法で考えるように自分自身をプッシュする必要があるという事実に同意します(そのため、コンテナーにログオンする必要がないように方法を見つける必要があります)、それでも私はそれが有用であると感じ、これが私が働く方法ですその周りに。

DEAMONモードでスーパーバイザーを介してコマンドを実行します。

それから私docker_loop.sh は私が呼ぶものを実行しますコンテンツはほとんどこれです:

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

コンテナに「アタッチ」し、supervisorctlログを停止/開始/再起動して確認するためのインターフェースを提示できるようにすることです。それで十分ではない場合はCtrl+D、そうすることができ、通常のシステムであるかのように覗き見できるシェルにドロップできます。

また、このシステムはシェルなしのコンテナーに比べて安全ではないので、アカウントに記入してください。コンテナーを保護するために必要なすべての手順を実行してください。


5

このプルリクエストに注意してくださいhttps : //github.com/docker/docker/pull/7409

次のdocker exec <container_id> <command>ユーティリティを実装します。これが利用可能な場合、たとえば、実行中のコンテナ内でsshサービスを開始および停止できるようにする必要があります。

これnsinitを行うこともあります「nsinitは実行中のコンテナの名前空間内のシェルにアクセスするための便利な方法を提供します」が、実行するのは難しいようです。 https://gist.github.com/ubergarm/ed42ebbea293350c30a6


docker execDocker 1.3に
導入さ


1

実際には、コンテナにシェルを含める方法があります。

/root/run.shプロセス、プロセスマネージャ(スーパーバイザ)などを起動すると想定します。

/root/runme.shいくつかのGnu画面のトリックで作成します。

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

これで、docker attachいつでもデーモンがタブ0に、インタラクティブシェルがタブ1 にあり、コンテナ内で何が起こっているかを確認できます。

別のアドバイスは、この画面トリックを含むすべての必要なツールを使用して、本番イメージの上に「開発バンドル」イメージを作成することです。


1

これが私の解決策です

DOckerfileの一部:

...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

「initd.sh」の一部

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

イメージがビルドされた後、execとattachを使用する2つのオプションがあります。

  1. exec(私が使用)を使用して、次を実行:

docker run --name $ CONTAINER_NAME -dt $ IMAGE_NAME

その後

docker exec -it $ CONTAINER_NAME / bin / bash

そして使う

CTRL + Dでデタッチ

  1. アタッチして実行:

docker run --name $ CONTAINER_NAME -dit $ IMAGE_NAME

その後

ドッカーは$ CONTAINER_NAMEを添付

そして使う

CTRL + PおよびCTRL + Qで切り離し

オプションの違いはパラメータ-iにあります


1

2つの方法があります。

アタッチ付き

$ sudo docker attach 665b4a1e17b6 #by ID

exec付き

$ sudo docker exec - -t 665b4a1e17b6 #by ID


0

コンテナーを実行するときに名前を割り当てると便利です。参照container_idは必要ありません。

docker run --name container_name yourimage docker exec -it container_name bash


0

最初に、目的のコンテナのコンテナIDを取得します

docker ps

あなたはこのようなものを得るでしょう:

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                          PORTS                    NAMES
3ac548b6b315        frontend_react-web     "npm run start"     48 seconds ago      Up 47 seconds                   0.0.0.0:3000->3000/tcp   frontend_react-web_1

このコンテナIDをコピーして、次のコマンドを実行します。

docker exec -it container_id sh

docker exec -it 3ac548b6b315 sh


-2

たぶん、あなたは私のように、コンテナーを開発するときにVMの観点から考えるように誤解させられたかもしれません。私のアドバイス:しないようにしてください。

コンテナーは他のプロセスと同じです。実際、デバッグのためにそれらに「アタッチ」したい場合があります(/ proc // envまたはstrace -pと考えてください)が、それは非常に特殊なケースです。

通常はプロセスを「実行」するだけなので、構成を変更したりログを読み取ったりしたい場合は、新しいコンテナを作成し、ディレクトリを共有してstdoutに書き込むことでログをコンテナの外部に書き込むようにします(したがって、Dockerログが機能します)。またはそのようなもの。

デバッグの目的で、シェルを開始してからコードを開始し、CTRL-p + CTRL-qを押してシェルをそのままにしておくことができます。この方法で、次を使用して再接続できます。

docker attach <container_id>

コンテナーが予期しない動作をしているためにコンテナーをデバッグする場合は、https//serverfault.com/questions/596994/how-can-i-debug-a-docker-containerをデバッグしてみてください。 -初期化


これは完全に間違っています。アプリケーションが実行されているLXC名前空間をイントロスペクトできることは「非常に特別なケース」ではなく、開発者にとって一般的で日常的なアクティビティです。
Sleepycal 2014

@sleepycal "開発者"は少し偏ったように聞こえます。いずれにせよ、私はプロセスの内省を使用するので、同じことがコンテナにも当てはまります。それがデバッグの背後にある考え方です。デバッガーをプロセスに接続します(CLIがある場合があります)。コンテナに「ログインしている」と思っても、まだ誤解を招くようです。
エスタニ2014

-4

いいえ、できません。supervisord必要に応じて、sshサーバーを取得するようなものを使用してください。しかし、私は間違いなくその必要性について質問します。

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