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
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. Создание оболочки в работающем контейнере
К счастью, мы можем использовать команду 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 для
docker exec
:
$ 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 основан контейнер.
Напротив, в нашем первом примере используется 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, используя опцию -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 foreach users 4096 Mar 5 16:55 dev
-rwxr-xr-x 1 foreach users 0 Mar 5 16:55 .dockerenv
drwxr-xr-x 2 foreach users 4096 Mar 5 16:55 etc
-rwxrwxr-x 1 foreach users 1840 Jan 1 2019 hello
4. Вывод
В этом кратком руководстве мы обсудили, как исследовать файловую систему контейнера Docker.
Мы можем запускать большинство контейнеров с доступом к оболочке напрямую с помощью команды запуска
docker
. Кроме того, мы можем создать оболочку для запуска контейнеров с помощью docker exec.
Когда дело доходит до остановленных контейнеров или минимальных контейнеров, мы можем просто экспортировать или даже локально скопировать всю файловую систему.