Dockerコンテナのファイルシステムの調査
1. 概要
Dockerを使用する場合、コンテナー内の構成またはログファイルを確認する必要がある場合があります。
このクイックチュートリアルでは、Dockerコンテナのファイルシステムを検査してこのような状況に対処する方法を説明します。
2. インタラクティブな探索
シェルアクセスを取得すれば、ほとんどのコンテナのファイルシステムをインタラクティブに探索できます。
2.1. シェルアクセスでコンテナを実行する
-itオプションを指定してdockerrunコマンドを使用し、シェルアクセスでコンテナを直接起動してみましょう。
$ docker run -it alpine
/# ls -all
...
-rwxr-xr-x 1 root root 0 Mar 5 13:21 .dockerenv
drwxr-xr-x 1 root root 850 Jan 16 21:52 bin
drwxr-xr-x 5 root root 360 Mar 5 13:21 dev
drwxr-xr-x 1 root root 508 Mar 5 13:21 etc
drwxr-xr-x 1 root root 0 Jan 16 21:52 home
....
ここでは、Alpine Linuxコンテナをインタラクティブモードで起動し、そのシェルに接続しました。
しかし、直接Linuxディストリビューションではないものを探索したい場合はどうなりますか?
$ docker run -it cassandra
...
INFO [MigrationStage:1] 2020-03-05 13:44:36,734 - Initializing system_auth.resource_role_permissons_index
INFO [MigrationStage:1] 2020-03-05 13:44:36,739 - Initializing system_auth.role_members
INFO [MigrationStage:1] 2020-03-05 13:44:36,743 - Initializing system_auth.role_permissions
INFO [MigrationStage:1] 2020-03-05 13:44:36,747 - Initializing system_auth.roles
INFO [main] 2020-03-05 13:44:36,764 - Waiting for gossip to settle...
...
Cassandra dockerコンテナには、Cassandraを実行するデフォルトの起動コマンドが付属しています。 その結果、シェルに接続されなくなりました。
代わりに、アプリケーションのログメッセージが入力された標準出力が表示されます。
ただし、デフォルトの起動コマンドをバイパスできます。
dockerrunコマンドに/bin/bash追加引数を渡してみましょう:
$ docker run -it cassandra /bin/bash
root@a71f71e98598:/# ls -all
total 4
...
-rwxr-xr-x 1 root root 0 Mar 5 13:30 .dockerenv
drwxr-xr-x 1 root root 920 Aug 14 2019 bin
drwxr-xr-x 1 root root 0 Mar 28 2019 boot
drwxr-xr-x 5 root root 360 Mar 5 13:30 dev
lrwxrwxrwx 1 root root 34 Aug 14 2019 docker-entrypoint.sh -> usr/local/bin/docker-entrypoint.sh
drwxr-xr-x 1 root root 1690 Mar 5 13:30 etc
...
残念ながら、これには厄介な副作用があります。 実際のCassandraアプリケーションは起動されなくなったため、シェルから手動でこれを実行する必要があります。
このアプローチを使用する場合、コンテナーの起動を制御できると想定しています。 実稼働環境では、これは不可能な場合があります。
2.2. 実行中のコンテナでシェルを生成する
幸い、 dockerexecコマンドを使用できます。を使用すると、実行中のコンテナーに接続できます。
まず、探索したいコンテナを開始しましょう。
$ docker run cassandra
...
INFO [MigrationStage:1] 2020-03-05 13:44:36,734 - Initializing system_auth.resource_role_permissons_index
INFO [MigrationStage:1] 2020-03-05 13:44:36,739 - Initializing system_auth.role_members
INFO [MigrationStage:1] 2020-03-05 13:44:36,743 - Initializing system_auth.role_permissions
INFO [MigrationStage:1] 2020-03-05 13:44:36,747 - Initializing system_auth.roles
INFO [main] 2020-03-05 13:44:36,764 - Waiting for gossip to settle...
...
次に、コンテナIDを dockerpsで識別します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
00622c0645fb cassandra "docker-entrypoint.s…" 2 minutes ago
次に、dockerexecに-itオプションを指定して引数として/bin/bashを渡します。
$ docker exec -it 00622c0645fb /bin/bash
root@00622c0645fb:/# ls -all
...
-rwxr-xr-x 1 root root 0 Mar 5 13:44 .dockerenv
drwxr-xr-x 1 root root 920 Aug 14 2019 bin
drwxr-xr-x 1 root root 0 Mar 28 2019 boot
drwxr-xr-x 5 root root 340 Mar 5 13:44 dev
lrwxrwxrwx 1 root root 34 Aug 14 2019 docker-entrypoint.sh -> usr/local/bin/docker-entrypoint.sh
drwxr-xr-x 1 root root 1690 Mar 5 13:44 etc
...
ここでは、選択したシェルとしてBashを使用しました。 これは、コンテナーが基づいているLinuxディストリビューションによって異なる場合があります。
対照的に、最初の例では、デフォルトでBourneShellに付属しているAlpineLinuxを使用しています。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
8408c85b3c57 alpine "/bin/sh" 3 seconds ago
Bashは使用できないため、 dockerexecの引数として/bin /shを渡します。
$ docker exec -it 8408c85b3c57 /bin/sh
/ # ls -all
...
-rwxr-xr-x 1 root root 0 Mar 5 14:19 .dockerenv
drwxr-xr-x 1 root root 850 Jan 16 21:52 bin
drwxr-xr-x 5 root root 340 Mar 5 14:19 dev
drwxr-xr-x 1 root root 508 Mar 5 14:19 etc
drwxr-xr-x 1 root root 0 Jan 16 21:52 home
...
3. 非対話型探索
時々、コンテナが停止し、インタラクティブに実行できない、、または単にシェルがない。
たとえば、 hello-world は、が最初から開始する最小コンテナーです。 その結果、シェルアクセスはできません。
幸運なことに、どちらの状況でも、ファイルシステムをホストマシンにダンプして、さらに調査することができます。
これをどのように行うことができるか見てみましょう。
3.1. ファイルシステムのエクスポート
docker export コマンドを使用して、コンテナーのファイルシステムをtarファイルにエクスポートできます。
まず、hello-worldコンテナーを実行してみましょう。
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
....
同様に、最初にをdocker ps :に-aフラグを渡して、停止したコンテナーのコンテナーIDを取得します。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED
a0af60c72d93 hello-world "/hello" 3 minutes ago
...
次に、 docker export の-oオプションを使用して、ファイルシステムをhello.tarファイルにダンプします。
$ docker export -o hello.tar a0af60c72d93
最後に、-tvfフラグを指定したtarユーティリティを使用してアーカイブの内容を印刷します。
$ tar -tvf hello.tar
-rwxr-xr-x root/0 0 2020-03-05 16:55 .dockerenv
....
drwxr-xr-x root/0 0 2020-03-05 16:55 dev/pts/
drwxr-xr-x root/0 0 2020-03-05 16:55 dev/shm/
....
-rwxr-xr-x root/0 0 2020-03-05 16:55 etc/resolv.conf
-rwxrwxr-x root/0 1840 2019-01-01 03:27 hello
...
または、アーカイブエクスプローラーを使用して、中身を確認することもできます。
3.2. ファイルシステムのコピー
dockercpコマンドを使用してファイルシステム全体をコピーすることもできます。
これも試してみましょう。
最初に、ルート(/)から始まる完全なファイルシステムをコンテナからtestディレクトリにコピーします。
$ docker cp a0af60c72d93:/ ./test
次に、testディレクトリの内容を出力してみましょう。
$ ls -all test/
total 28
..
drwxr-xr-x 4 baeldung users 4096 Mar 5 16:55 dev
-rwxr-xr-x 1 baeldung users 0 Mar 5 16:55 .dockerenv
drwxr-xr-x 2 baeldung users 4096 Mar 5 16:55 etc
-rwxrwxr-x 1 baeldung users 1840 Jan 1 2019 hello
4. 結論
このクイックチュートリアルでは、Dockerコンテナのファイルシステムを探索する方法について説明しました。
docker run コマンドを使用して、シェルアクセスを使用してほとんどのコンテナーを直接起動できます。 さらに、 dockerexec。を使用して、コンテナーを実行するためのシェルを生成できます。
停止したコンテナーまたは最小限のコンテナーに関しては、ファイルシステム全体をローカルにエクスポートまたはコピーすることもできます。