Dockerコンテナの初期化をデバッグするにはどうすればよいですか?


93

コンテナに問題がありましたが、完全にビルドされても、正しく起動しません。原因は、Dockerfileに追加した回避策です(自己構成の/ etc / hostsルーティングを使用するため)

RUN mkdir -p -- /lib-override /etc-override && cp /lib/libnss_files.so.2 /lib-override
ADD hosts.template /etc-override/hosts
RUN perl -pi -e 's:/etc/hosts:/etc-override/hosts:g' /lib-override/libnss_files.so.2
ENV LD_LIBRARY_PATH /lib-override

そこには明らかにいくつかのエラーがありますが、実行中にdockerが何をしているのかについてもっと情報を得るにはどうすればいいのでしょうか。たとえば、これは動作します:

$ docker run image ls
usr bin ...

しかし、これはそうではありません:

$ docker run image ls -l
$

ログには何もありませんし、インタラクティブなシェルも呼び出すことはできません。私はstraceを使用して何が起こっているのかを見ることができますが、そこにもっと良い方法があることを望んでいました。

dockerをより詳細に設定できる方法はありますか?

編集:アンドリューDのおかげで、私は今、上記のコードの何が問題なのかを知っています(彼の答えが理解できるように残しました)。問題は、このようなデバッグや、ls -lが失敗した理由、lsが失敗しなかった理由などをデバッグする方法です。

編集:-D = trueはより多くの出力を与えるかもしれませんが、私の場合はそうではありません...


回答の1つを「承認済み」としてマークしてください、ありがとうございます。
ブライアントッピング

回答:


95

Docker eventsコマンドが役立つ場合があり、Dockerログコマンドは、イメージの起動に失敗した後でもログを取得できます。

まずdocker events、バックグラウンドで開始して、何が起こっているのかを確認します。

docker events&

次に、失敗したdocker run ...コマンドを実行します。次に、画面に次のようなものが表示されます。

2015-12-22T15:13:05.503402713+02:00 xxxxxxxacd8ca86df9eac5fd5466884c0b42a06293ccff0b5101b5987f5da07d: (from xxx/xxx:latest) die

次に、前のメッセージまたはrunコマンドの出力から起動16進IDを取得できます。その後、logsコマンドで使用できます。

docker logs <copy the instance id from docker events messages on screen>

これで、失敗したイメージの起動からの出力が表示されます。

コメントで@alexkbが示唆したdocker events&ように、AWS ECSサービスのようなものからコンテナーが絶えず再起動されている場合、面倒になる可能性があります。このシナリオでは、ログインからコンテナの16進数IDを取得する方が簡単な場合があります/var/log/ecs/ecs-agent.log.<DATE>。次に、dockerを使用しますlogs <hex id>


非常に役立ちます!Dockerの新機能であり、portainerを実行しようとしていました。これらのデバッグ手順で解決しました。同じ問題を持つMedium.comで誰かを見つけました:medium.com/@jameson_37151/…–
Jameson

「コンテナが見つかりません」と表示されます!?
ハリネズミの痴呆

奇妙な。念のため、@ dementedhedgehogでは、「(from xxx/xxx:latest) die」で終わるログメッセージから16進数のIDをコピーしようとしましたか?
ピーターラン

1
この答えありがとうございます、それは命の恩人です。docker events&コンテナをAWS ECSサービスなどから常に再起動している場合、追加するのは面倒なことだけです。したがって、このシナリオでは、ログインからコンテナの16進数IDを取得する方が簡単かもしれません/var/log/ecs/ecs-agent.log.<DATE>。次にdocker logs <hex id>、この回答で提案されているとおりに使用して、起動しない理由を確認します。
alexkb

1
@alexkbありがとう!他の人がより簡単に見つけられるように、答えの最後にあなたの提案を追加しました。
ピーターラン

18

まあ私がこれまでに発見した最高のものは:

#stop the current demon and start it in debug modus
sudo service docker stop
dockerd -D # --debug

新しいシェルからクライアントを起動します。誤解は、クライアントが実際には何もしないと考えることでした...それはデーモンと通信しているだけなので、クライアントではなくデーモン自体をデバッグする必要があります(通常)。


13

私の場合、-a(STDOUT / STDERRにアタッチ)フラグで十分でした:

user@machine:~$ docker start -a server_name
Error: The directory named as part of the path /log/log_path/app.log does not exist.
For help, use /usr/bin/supervisord -h

起動エラー(この場合、で使用されているログパスがありませんsupervisord)が表示されました。ほとんどのコンテナ起動エラーもここに表示されると思います。


3

ドッカー出力をより完全にする方法に関するあなたの質問に答えることはできませんが、.soファイル内の文字列を置き換えるインプレース正規表現は少し狂っていることを伝えることができます:文字列には割り当てられたスペースしかありません他のエントリのファイルオフセットを変更すると、elfファイルが破損します。コンテナの外でperlコマンドを実行した後(LD_LIBRARY_PATHを変更する前に)、. soファイルでobjdumpまたはreadelfを実行してみてください。ドーナツのドルは破損しています。

この悲しいことに必要なハックで機能する理由は、「tmp」と「etc」が同じ文字列長であるため、オフセットが変更されないためです。/ tmpを使用しない場合は、ディレクトリ/ dkrなどを検討してください。

このアプローチを取る必要があり、目的のパスが変更できない場合は、ライブラリを再構築し、ソース内の/ etc / hostsのデフォルトパスを変更します。または、変更したlibnss_files.so名前を変更して、ドッカーコンテナーの起動時に使用するようlibnss_altfiles.soに変更nsswitch.confし、名前を変更することhosts: altfilesもできます(dockerがnsswitch.confをマウントしている場合を除き、変更できません)。これにより、ベースシステムの通常のライブラリと並行してlibnss_altfiles.soを使用できます。dockerがnsswitch.confをバインドマウントする場合、再構築したlibnss_files.soのコピーを/ lib-overrideディレクトリに残し、LD_LIBRARY_PATHでロードできるようにします。

ヘッドアップとして、suid / sgidバイナリはLD_LIBRARY_PATHとLD_PRELOADを無視するため、これらの変数を使用すると、いくつかのものが壊れます(読み取り:デフォルトの/ etc / hostsの使用に戻ります)。


素晴らしい洞察に感謝します...私は速すぎて、今何が起こっているのかを確認します。STATを得ることがホストを解決する必要がなぜ私はまだ...、単純なファイルリスト(LS)ながら(LS -l)しませんかわからない
estani

0

時々、dockerデーモンを実行しているノードに入れてから実行することで、有用なエラーメッセージを見つけることができます。

$ tail -f /var/log/containers/* /var/log/docker.log 2>&1

Mac OSの「Dockerコミュニティエディション」では、次のようにしてdocker vmに接続できます。

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