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。を使用して、コンテナーを実行するためのシェルを生成できます。

停止したコンテナーまたは最小限のコンテナーに関しては、ファイルシステム全体をローカルにエクスポートまたはコピーすることもできます。