«1. Обзор
Когда мы работаем с Docker, иногда нам нужно проверить файлы конфигурации или журналы внутри контейнера.
В этом кратком руководстве мы увидим, как проверить файловую систему контейнера Docker, чтобы помочь нам в таких ситуациях.
2. Интерактивное исследование
Мы можем исследовать файловую систему в интерактивном режиме для большинства контейнеров, если мы получим к ним доступ из оболочки.
2.1. Запуск контейнера с доступом к оболочке
Давайте запустим контейнер напрямую с доступом к оболочке, используя команду запуска docker с параметром -it:
$ 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 поставляется с командой запуска по умолчанию, которая запускает Cassandra. В результате мы больше не связаны с оболочкой.
Вместо этого мы просто видим стандартный вывод, заполненный сообщениями журнала приложения.
Однако мы можем обойти команду запуска по умолчанию.
Давайте передадим дополнительный аргумент /bin/bash команде запуска docker:
$ docker run -it cassandra /bin/bash
[email protected]:/# 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. Создание оболочки в работающем контейнере
К счастью, мы можем использовать команду docker exec, которая позволяет нам подключаться к запущенным контейнерам.
Давайте сначала запустим контейнер, который мы хотим исследовать:
$ 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...
...
Затем мы идентифицируем идентификатор контейнера с помощью docker ps:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
00622c0645fb cassandra "docker-entrypoint.s…" 2 minutes ago
Затем мы передаем /bin/bash в качестве аргумента с -it option для docker exec:
$ docker exec -it 00622c0645fb /bin/bash
[email protected]:/# 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 основан контейнер.
Напротив, в нашем первом примере используется Alpine Linux, который по умолчанию поставляется с Bourne Shell:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
8408c85b3c57 alpine "/bin/sh" 3 seconds ago
Поскольку Bash недоступен, мы передаем /bin/sh в качестве аргумента для docker exec: ~~ ~
$ 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. Экспорт файловой системы
Мы можем экспортировать файловую систему контейнера в файл tar с помощью команды экспорта docker.
Давайте сначала запустим контейнер hello-world:
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
....
Аналогично, мы сначала получим идентификатор контейнера остановленного контейнера, передав флаг -a в docker ps:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED
a0af60c72d93 hello-world "/hello" 3 minutes ago
...
Затем мы дампируем файловой системы в файл hello.tar с помощью опции экспорта docker -o:
$ docker export -o hello.tar a0af60c72d93
Наконец, мы печатаем содержимое архива с помощью утилиты tar с флагами -tvf:
$ 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. Копирование файловой системы
Мы также можем скопировать всю файловую систему с помощью команды docker cp.
Давайте попробуем и это.
Сначала мы скопируем всю файловую систему, начиная с корня (/), из нашего контейнера в тестовый каталог:
$ docker cp a0af60c72d93:/ ./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. Кроме того, мы можем создать оболочку для запуска контейнеров с помощью docker exec.
Когда дело доходит до остановленных контейнеров или минимальных контейнеров, мы можем просто экспортировать или даже локально скопировать всю файловую систему.