スーパーヒーローのようにDockerコンテナを修正およびデバッグする方法

コンテナは、開発者がクロスプラットフォームアプリケーションを迅速に構築して実行するのに役立ちますが、エラーのないアプリを作成することは常に課題です。 また、コンテナエラーがどのように発生するかは必ずしも明らかではありませんが、この謎は新しい開発者が解明するのがさらに困難です。Dockerコンテナをデバッグする方法を理解することは、気が遠くなるように思えるかもしれません。

このコミュニティ全員参加セッションでは、Ákos Takácsがこれらの厄介な問題の多くを解決し、 コンテナを固定する超能力を獲得する方法を示しました。

各問題は、イメージのビルドと最終的なアプリケーションに影響を与える可能性があります。 一部のバグでは、明確なエラーメッセージがトリガーされない場合があります。 さらに複雑なことに、ソースコードの検査は必ずしも役立つとは限りません。 

しかし、一般的なコンテナの問題はあなたのクリプトナイトである必要はありません! Ákosのお気に入りのヒントを共有し、これらの開発の課題を克服する方法を紹介します。

このチュートリアルの内容:

コンテナの一般的な間違いを見つけて修正する

誰もが時折愚かな間違いを犯しがちです。 疲れているとき、時折キーボードがずれているとき、またはステップ間でテキストを正しくコピーできないときにコーディングします。 これらの失敗は、あるコマンドから次のコマンドに持ち越される可能性があります。 また、スペルミスや文字の脱落など、見逃しやすいものがレーダーの下を飛ぶ可能性があるため、基本的な問題を解決するために多くの掘り下げを行う必要があります。 誰もそれを望んでいないので、どのようなツールを自由に使用できますか? 

コンテナの可視性を高めるためのCLIの使用

Docker Hubからダウンロードしたイメージ(任意のイメージ)があり、 docker run コマンドのバリエーションを使用して実行するとします。 結果のコンテナーでは、既定のコマンドが実行されます。 そのコマンドを表示したい場合は、入力 docker container ls --all すると、それぞれのコマンドを含むコンテナのリストが取得されます。 

多くの場合、ユーザーはこれらのコマンドをコピーして、他の長いCLIコマンド内で再利用します。 ご想像のとおり、誤って強調表示したり、不完全なフレーズをコピーしたり、それを使用する誤ったコマンドを実行したりするのは非常に簡単です。

新しいコンテナを回転させている間、あなたは引っ掛かりにぶつかるでしょう。 このインスタンスのランタイムは、Docker が実行可能ファイルを見つけることができないため失敗します。 にはありません PATH、これは問題を示します。

ドッカー実行

コマンドを実行すると、 docker container ls --all いくつかのヒントも提供されます。 コンテナー コマンドと httpd-foregroun 、作成された (ただし実行されていない) コンテナーとペアになっていることに注意してください。 逆に、実行されているコンテナーは v0 、有効で完全なコマンドを正常に利用します。

Docker container ls

さらに調査するにはどうすればよいですか? docker run --rm -it --name MYCONTAINER [IMAGE] bash コマンドを使用して、コンテナ内のインタラクティブターミナルを開きます。コンテナーの既定のコマンドを取得し、もう一度実行してみてください。 「コマンドが見つかりません」というエラーメッセージが表示されます。

これははるかに簡潔であり、間違ったコマンドを入力した可能性が高いことを示しています—この場合は文字を忘れることによって。 Ákosの例ではhttpdを使用していますが、ほとんどすべてのコンテナイメージに適用できます。 

可視性と読みやすさのためにCLI出力形式を変更する

コンテナコマンドは、ターミナル出力で特定の長さを超えるとクリップされます。 これにより、コマンド全体を検査できなくなります。 

幸いなことに、Ákosは、フラグが --format ‘{{ json . }}’ | jq -C 端末の出力の表示方法をどのように改善できるかを示しました。 テキストの一部を切り取る代わりに、 docker container ls --all 結果は次のようになります。

Json jq c フォーマット

任意のパラメータを完全に読み取って比較できます。 何も隠されていません。 jq インストールしていない場合は、代わりに次のコマンドを入力して、構文の強調表示を除いた出力を同様に表示できます。これは、トラブルシューティング用のデフォルトの表形式レイアウトよりも優れています。

docker container ls --all --format ‘{{ json . }}’ | python3 -m json.tool --json-lines

最後に、関連情報のみを表示しながら、元のテーブルビューを展開してみませんか? フラグを指定して --no-trunc 次のコマンドを実行して、これらのテーブル行を展開し、各セルの内容を完全に表示します。

docker container ls --all --format ‘table {{ .Names }}/t{{ .Status }}/t{{ .Command }}’ --no-trunc

これらの例は、トラブルシューティングにおける可視性と透明性の重要性を強調しています。 必要な情報を明らかにして簡単に消化できる場合、修正ははるかに簡単になります。      

ログを活用することを忘れないでください

ベスト プラクティスに従うことで、Docker コンテナー内で実行されているアクティブなアプリケーションはログ出力を生成します。 ログ記録は問題を回避するメカニズムと見なすかもしれませんが、実行中のコンテナーの多くは問題を経験しません。

Ákosは、通常のログエントリがどのように見えるかを理解することが重要だと考えています。 その結果、異常なログエントリの特定がはるかに簡単になります。 このコマンドにより docker logs 、これが可能になります。

ドッカーログ

ログを調整するプロセスは、ツールと言語によって異なります。 たとえば、Ákos は httpd を含むメソッド (詳細なトレースレベルのメッセージや LogLevel エラーメッセージのフィルタリングなど trace) から引き出しましたが、これらのプラクティスは広く適用できます。ほとんどの問題を診断するために、起動エラーとランタイムエラーに焦点を合わせたいと思うでしょう。 

ログ処理は構成可能です。 コンテナーの問題にドリルダウンする (およびノイズを減らす) のに役立つ一般的なコマンドを次に示します。

コンテナーの最後の 100 個のログを取得します。

ドッカーログ - テール100 [コンテナID]

特定のコンテナーのすべてのログを取得します。

ドッカー ログ [コンテナー ID]

実行中のコンテナ内のすべてのアクティブなプロセスを表示します(ログにアクセスできない場合)。

ドッカートップ [コンテナID]

セキュリティログ監視により、修復が容易になります。 Ákosと並んで、コンテナの変更や修正を行った後に確認する必要があることに同意します。 これは、あなたが正しいステップを踏み、先に進むことができることを意味します。

Dockerデスクトップ内ですべてのログをまとめて表示したいですか? ログ エクスプローラー拡張機能をダウンロードすると、フィルターと高度な検索機能を使用してログを参照できます。 新しいログが入力されたときに表示することもできます。

ログエクスプローラー

エントリポイントで問題に取り組む

アプリケーションを実行するときは、コンテナー内で実行可能ファイルを実行する必要があります。 ENTRYPOINT Dockerfile の部分は、コンテナ内のメインコマンドを設定し、基本的にタスクを割り当てます。これらの ENTRYPOINT 手順は、コンテナー内にある実行可能ファイルに依存します。 

Ákosの例では、不適切な権限がDockerの実行可能ファイルの正常なマウントと実行 entrypoint.sh を妨げる可能性があるシナリオに取り組んでいます。 彼のアプローチをコピーするには、次の手順を実行します。 

  1. ls -l $PWD/examples/v6/entrypoint.sh コマンドを使用してファイルのアクセス許可を表示しますが、これは不十分な場合があります。
  2. アクセス許可が正しくないことを確認します。 
  3. chmod 774 コマンドを実行して、このファイルをすべてのユーザーに対して読み取り、書き込み、および実行できるようにします。
  4. 元の entrypoint コンテナからコンテナ v7 をスピンアップするために使用します docker run。これは一時的には機能しますが、すぐに実行を停止します。 
  5. ファイルを調べて、 entrypoint.sh 目的のコマンドが存在することを確認します。 

これを再度確認するには、次のように入力 docker container inspect v7-exiting してコンテナー定義とパラメーターを表示します。 が指定され Entrypoint ている間、その Cmd 定義は nullです。 それが問題の原因です:

設定ファイル

なぜこれが起こるのですか? 多くの人は、設定 --entrypointすることによって、デフォルトのコマンドを持つ画像がそのコマンドを自動的に空にすることを知りません。 コンテナーが正しく機能するには、コマンドを再定義する必要があります。 この CLI コマンドは次のようになります。

docker run -d -v $PWD/examples/v7/entrypoint.sh:/entrypoint.sh --entrypoint /entrypoint.sh --name v7-running httpd:2.4 httpd-foreground

これはどのコンテナイメージでも機能しますが、前の例から描画しているだけです。 これを実行してコンテナを再度一覧表示すると、 v7 アクティブになります。 ログ内で、すべてが良好に見えることを確認します。 

コンテナーの内容にアクセスして検査する

ローカル開発では、ファイルとシステム リソースを慎重に管理することが重要です。 これは、複数のイメージ、コンテナー、またはリソースの制約を操作する場合に二重に当てはまります。 時間の経過とともに内容が蓄積されるにつれて、コンテナーが肥大化するシナリオがあります。 

ファイルを整理しておくことは1つのことです。 ただし、コンテナからファイルをコピーして一時フォルダに移動することもできます — docker cp 指定したディレクトリでコマンドを使用します。 の ls -la ./var/v8バリエーションを使用すると、 Ákosの例から借用して、すべてのファイルを含むリストを生成します。 

これは、コンテナの内容を可視化して確認するのに最適です。 また、問題をさらに一歩 docker container diff v8 診断して、変更、追加、または削除されたファイルを表示できます。 奇妙なコンテナの動作が発生している場合は、これらのファイルを掘り下げると役立つ場合があります。 


手記: また、リソース使用量拡張機能 を利用して、ディスク容量の消費量、ネットワークアクティビティ、CPU使用率、およびメモリ使用量をリアルタイムで監視することもできます。

ファイルやフォルダを深く掘り下げる

綿密な検査が役立つところ hexdump です。 この hexdump 関数は、ファイルをバイナリよりもはるかに読みやすい16進コードに変換します。 Ákosは次のコマンドを使用しました。

docker cp v8:/usr/local/apache2/bin/httpd ./var/v8-httpd`
`hexdump -C -n 100 ./var/v8-httpd

この -n 数を調整して、読み取り先頭バイト数を増やしたり減らしたりできます。 ファイルにテキストが含まれている場合、このコンテンツは目立ち、ファイルの主な目的を明らかにします。 しかし、フォルダにアクセスしたいとします。 ディレクトリの変更と実行 docker container inspect … は標準ですが、この方法はDockerデスクトップユーザーには機能しません。 デスクトップはVM内で物事を実行するため、ホストは内部のフォルダにアクセスできません。 

Ákosは GitHubで CTOのJustin Cormack自身の nsenter1 イメージを紹介し、Dockerデスクトップ環境で実行されているコンテナを活用できるようにしました。Docker の Captain Bret Fisher は、便利なコマンドを追加しながら、 のドキュメントを拡張 nsenter1しました。 これらの要素を配置したら、次のコマンドを実行します。

docker run --rm --privileged --pid=host alpine:3.16.2 nsenter -t 1 -m -u -i -n -p -- sh -c “ cd \”$(docker container inspect v8 --format ‘{{ .GraphDriver.Data.UpperDir }}’}\” \&& find .”

このコマンドの出力は、前の docker container diff コマンドの出力を反映しています。 上記と同じイメージを使用して を実行する hexdump こともできるため、環境に関係なく同じトラブルシューティング機能を利用できます。 また、重要な変更を加えるために検査 entrypoint.sh することもできます。  

ドッカービルドエラーを解決する 

Docker BuildKit は迅速で回復性がありますが、イメージのビルドの完了を妨げるエラーが発生する可能性があります。 理由を確認するには、次のコマンドを実行して、各順次ビルド ステージを表示します。

docker build $PWD/[MY SOURCE] --tag “MY TAG” --progress plain

BuildKit は、各ステップの読み取り可能なコンテキストを提供し、発生したエラーを表示します。

ドッカービルドの進行状況

上記のようなファイルまたはディレクトリの欠落エラーが表示されても、心配する必要はありません。 この cat $PWD/[MY SOURCE]/[MY DOCKERFILE] コマンドを使用して、 Dockerfile. どこでミスしたかをより明確に確認できるだけでなく、失敗したコマンドの前に新しい命令を追加して、フォルダーの内容を一覧表示することもできます。 

たぶん、それらのコンテンツは更新する必要があります。 たぶんあなたのフォルダは空です! その場合、すべてを更新する必要があるため docker build 、活用できるものがあります。 

次に、フラグを追加した状態で --no-cache ビルド コマンドを再度実行します。 このフラグは、キャッシュに依存せずに毎回最初からクリーンにビルドするようにDockerに指示します。

ドッカーはキャッシュを構築しません

更新されたバージョン Dockerfile を段階的にビルドし、命令のカスケードの性質を考慮して、それらの変更をテストできます。 最後の作業命令の後に新しい命令を書くか、ファイルの早い段階で変更を加えると、これらの厄介なビルドの問題を排除できます。 のような unlink cp メカニズムや役立つメカニズム。1つ目は、1つの引数のみを受け入れるときのように rm 動作し cp 、重要なファイルとフォルダーをソースから画像にコピーします。  

ドッカー作成エラーを解決する

Docker Compose を使用して、コマンドを使用して複数のサービスを同時に docker compose --project-directory $PWD/[MY SOURCE] up -d スピンアップします。 

ただし、これらのコンテナーの 1 つ以上が予期せず終了する可能性があります。 実行 docker compose --project-directory $PWD/[MY SOURCE] ps してサービスを一覧表示することで、どのコンテナーが実行中または終了しているかを確認できます。

問題を特定するには、通常、コマンドを使用してログ docker compose logs を取得します。 ほとんどの場合、プロジェクト ディレクトリを指定する必要はありません。 ただし、コンテナーは実行されていないため、ログは生成されません。 

次に、コマンドを実行して、 cat $PWD/[MY SOURCE]/docker-compose.yml Docker 作成ファイルの内容を表示します。 サービス定義を修正する必要がある可能性が高いため、CLI 内で行ごとに掘り下げると便利です。 次のコマンドを入力して、この出力をさらに明確にします。

docker compose --project-directory $PWD/[MY SOURCE] config

コンテナは、前述したように、中に含まれるコマンドが無効になると終了します。 コマンドを間違って入力したかどうか、またはそのコマンドが空かどうかを確認できます。 そこから、作成ファイルを更新して再実行できます docker compose --project-directory $PWD/[MY SOURCE] up -d。 これで、サービスを再度一覧表示することで、すべてが機能していることを確認できます。 あなたの端末もログを出力します! 

オプション: 実行中のコンテナー内でファイルを直接編集する

最後に、コンテナ内のファイルを直接編集することが可能です(そして魅力的です)。 これは、新しい変更をテストし、コンテナーを検査するときに実行可能です。 ただし、通常は、代わりに新しいイメージとコンテナーを作成することをお勧めします。 

実行中のコンテナー内で編集を行う場合、VS Code のようなエディターではこれが可能ですが、IntelliJ では比較できません。 VS Code 用の Docker 拡張機能をインストールします。 次に、左側のサイドバーでコンテナを参照し、リソースのコレクションを拡張して、重要なファイルに直接アクセスできます。 たとえば、Web開発者はファイルを直接編集 index.html して、ユーザーコンテンツの構造を変更できます。 

調査を減らし、開発を増やす

全体として、表面的にはコンテナを修正するプロセスは、新しいDockerユーザーにとっては気が遠くなるように思えるかもしれません。 上記で強調した方法は、トラブルシューティングの複雑さを大幅に軽減し、時間と労力を節約できます。 問題の調査に費やす時間を減らし、ユーザーが好むアプリケーションの作成により多くの時間を費やすことができます。 そして、それらのスキルはかなり英雄的だと思います。 

詳細については、 YouTubeでÁkos Takácsの完全なプレゼンテーションを表示 して、各手順を注意深く実行することができます。 もっと深く掘り下げたいですか? Docker エキスパートになるには、次の追加リソースを確認してください。 

フィードバック

「スーパーヒーローのようにDockerコンテナを修正およびデバッグする方法」に関する0の考え