Dockerコンテナのファイルシステムの変更を確認する方法
Dockerコンテナは初期作成時にそのイメージのファイルシステムを継承します。コンテナの書き込み可能なレイヤーに変更が加えられると、コンテナのファイルシステムはイメージの内容から分岐する可能性があります。
ファイルシステムの変更を検査する能力は、問題のデバッグや欠落データの調査に役立ちます。コンテナのファイルシステムに書き込まれたファイルは、そのコンテナが再起動または破棄されると失われます。場合によっては、永続ボリュームに向けて行うべき書き込みを無意識に行っている可能性があります。
この記事では、コンテナファイルシステムに対する変更を特定するためのいくつかの手法を紹介します。この情報を使用して、コンテナの活動を追跡し、異なる環境間の不一致を調査することができます。
Docker Diffの使用
Docker CLI にはこの目的のための組み込みコマンドがあります。docker diff を実行すると、特定のコンテナ内で行われたファイルおよびディレクトリのすべての変更が列挙されます。検査したいコンテナの ID または名前を受け入れます。
デモ目的でシンプルなコンテナを開始します。
docker run -it --name alpine alpine:latest shこれにより、Alpineイメージを実行する新しいコンテナが起動します。ターミナルウィンドウはコンテナに接続されます。このウィンドウを開いたままにしてください。
次に、別のターミナルセッションでdocker diffを実行します:
docker diff alpine新しいコンテナがAlpineイメージのファイルシステムと完全に一致しているため、出力は生成されません。
コンテナにまだ接続されている最初のターミナルに戻ります。ファイルを追加、削除、または変更するいくつかのコマンドを実行します:
/ # touch demo
/ # touch example
最初のシェルウィンドウに戻ります。docker diffコマンドを再度実行して、行われた変更を確認します:
docker diff alpine
A /example
C /root
C /root/.ash_history
A /demo
現在、2つの新しいファイルがコマンドの出力に表示されています。touchを実行すると、コンテナのシェル履歴にもエントリが追加されました。/root/.ash_historyの変更も報告されており、/rootディレクトリの結果的な変更も含まれています。
Docker Diff出力の解釈
docker diffによって生成される各出力の行は、発生した変更の種類に応じて、A、C、またはDでプレフィックスされています:
A- ファイルまたはディレクトリがコンテナのファイルシステムに追加されました。それは元のイメージには存在しません。C- ファイルまたはディレクトリの内容は、画像にあるバージョンとは異なります。D- 画像に存在するパスがコンテナから削除されました。
この情報は、欠落したデータや予期しない動作を説明できる不一致を迅速に探すことを可能にします。
出力に表示されないファイルシステムの変更は、Dockerボリュームにマッピングされた影響を受けたパスに関連しています。これらのファイルはコンテナの外に保存され、そのファイルシステムとは独立しているため、docker diff では表示されません。
オリジナル画像でコンテンツを視聴する
元のイメージに含まれているファイルバージョンを比較することは有益です。新しいコンテナを作成し、そのファイルをコピーすることでこれを行うことができます。コンテナが作成されるが開始されないように、docker runの代わりにdocker createを使用してください。これにより、イメージのエントリポイントスクリプトによる変更が結果に影響を与えないことが保証されます。
docker create --name temp-container my-image:latest
docker cp temp-container:/path/to/file copied-file
docker rm temp-container
別の方法は、カスタムエントリポイントでコンテナを実行し、ファイルの内容を標準出力ストリームに出力することです。コマンドが完了した後にコンテナが自動的に削除されるように、--rm フラグを含めてください:
docker run --rm --entrypoint cat alpine:latest /path/to/file > copied-file二つのコンテナの違いを比較する
時々、同じイメージを実行している2つの異なるコンテナの違いを比較する必要があるかもしれません。まず、docker diffを使用して、個別の変更リストを取得します:
docker diff first-container > first
docker diff second-container > second
これで、diff コマンドなどの標準的な Unix ツールを使用して、2 つの変更リストの違いを見つけることができます:
diff first second
3c3
< A /a-new-file
---
> A /demo
差分は、/a-new-fileが2番目のコンテナで削除され、/demoが追加されたことを示しています。
コンテナを比較する別の方法は、docker export と tar コマンドを使用して包括的なファイルリストにアクセスすることです:
docker export demo-container | tar tv
-rwxr-xr-x 0/0 0 2022-06-21 14:21 .dockerenv
drwxr-xr-x 0/0 0 2022-05-23 17:51 bin/
lrwxrwxrwx 0/0 0 2022-05-23 17:51 bin/arch -> /bin/busybox
lrwxrwxrwx 0/0 0 2022-05-23 17:51 bin/ash -> /bin/busybox
lrwxrwxrwx 0/0 0 2022-05-23 17:51 bin/base64 -> /bin/busybox
lrwxrwxrwx 0/0 0 2022-05-23 17:51 bin/bbconfig -> /bin/busybox
...
このコマンドを両方のコンテナで繰り返してください。その後、diffを使用して2つのリストを比較できます。tarの強化された出力は、ファイルの変更時期を追跡するのに役立ちます。変更時間や権限が表示されるからです。
要約
Dockerコンテナのファイルシステムは、作成元のイメージに非常に近いものであるべきです。コンテナ内でソフトウェアがファイルシステムに直接コンテンツを書き込むと、違いが生じることがあります。また、docker execのようなメカニズムを使用して実行中のコンテナ内でコマンドを実行する場合、ユーザーも違いの別の源となることがあります。
docker diff ユーティリティは、これらの変更を確認する便利な方法を提供します。ファイルが追加された理由や削除された理由を見ることはできませんが、変更のリストを取得する機能は、特定の挙動が観察される理由を理解するのに非常に重要です。
この記事では、コンテナの実行に対する変更を検証することに焦点を当てています。docker historyやDiveなどのさまざまなツールを使用して、Dockerイメージ内のレイヤーに対して行われた変更を調査することができます。これらの2つのアプローチを組み合わせて使用することで、コンテナのレイヤースタック内でファイルが追加または変更された正確なポイントを特定できます。
