Изучение файловой системы контейнера Docker

Я заметил с докером, что мне нужно понять, что происходит внутри контейнера или какие файлы существуют там. Одним из примеров является загрузка изображений из индекса докеров - вы не знаете, что изображение содержит, поэтому невозможно запустить приложение.

Что было бы идеальным, это иметь возможность ssh в них или эквивалентно. Есть ли инструмент для этого, или моя концептуализация докера неправильно в мышлении, что я должен это сделать.

Ответ 1

Метод 1: снимок

Вы можете оценить файловую систему контейнера следующим образом:

# find ID of your running container:
docker ps

# create image (snapshot) from container filesystem
docker commit 12345678904b5 mysnapshot

# explore this filesystem using bash (for example)
docker run -t -i mysnapshot /bin/bash

Таким образом, вы можете оценить файловую систему работающего контейнера в точный момент времени. Контейнер все еще работает, никакие будущие изменения не включены.

Позже вы можете удалить снимок, используя (файловая система работающего контейнера не затронута!):

docker rmi mysnapshot

Метод 2: ssh

Если вам нужен постоянный доступ, вы можете установить sshd в свой контейнер и запустить демон sshd:

 docker run -d -p 22 mysnapshot /usr/sbin/sshd -D

 # you need to find out which port to connect:
 docker ps

Таким образом, вы можете запустить свое приложение, используя ssh (подключитесь и выполните то, что вы хотите).

ОБНОВЛЕНИЕ - Метод 3: nsenter

Используйте nsenter, см. http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/

Короткая версия: с помощью nsenter вы можете получить оболочку в существующий контейнер, даже если этот контейнер не запускает SSH или любой другой специального демона

ОБНОВЛЕНИЕ - Метод 4: Docker Exec

Docker версии 1.3 или новее поддерживает команду exec, которая ведет себя подобно nsenter. Эта команда может запустить новый процесс в уже запущенном контейнере (в контейнере должен быть запущен процесс PID 1). Вы можете запустить /bin/bash, чтобы изучить состояние контейнера:

docker exec -t -i mycontainer /bin/bash

см. документацию командной строки Docker.

Ответ 2

ОБНОВЛЕНИЕ: ИЗУЧЕНИЕ!

Эта команда должна позволить вам исследовать работающий докер-контейнер:

docker exec -it name-of-container bash

Эквивалентом этого в docker-compose будет:

docker-compose exec web bash

(в данном случае web - это имя службы, и по умолчанию оно имеет tty.)

Как только вы внутри, сделайте:

ls -lsa

или любая другая команда bash, например:

cd ..

Эта команда должна позволить вам изучить образ докера:

docker run --rm -it --entrypoint=/bin/bash name-of-image

однажды внутри сделать:

ls -lsa

или любая другая команда bash, например:

cd ..

-it обозначает интерактивный... и tty.


Эта команда должна позволить вам проверить работающий докер-контейнер или изображение:

docker inspect name-of-container-or-image

Вы можете сделать это и выяснить, есть ли там bash или sh. Ищите точку входа или cmd в возвращении json.

см. документацию по Docker Exec

см. документацию exec для docker-compose

см докер проверяет документацию

Ответ 3

Вы можете архивировать файловую систему вашего контейнера в файл tar:

docker export adoring_kowalevski > contents.tar

Этот способ работает, даже если ваш контейнер остановлен и не имеет какой-либо программы оболочки, например /bin/bash. Я имею в виду изображения, подобные hello-world из Документация докеров.

Ответ 4

Файловая система контейнера находится в папке данных докера, обычно в /var/lib/docker. Чтобы запустить и проверить запущенную файловую систему контейнеров, выполните следующие действия:

hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash

И теперь текущий рабочий каталог является корнем контейнера.

Ответ 5

Перед созданием контейнера:

Если вы изучите структуру изображения, смонтированного внутри контейнера, вы можете сделать

sudo docker image save image_name > image.tar
tar -xvf image.tar

Это даст вам видимость всех слоев изображения и его конфигурации, которая присутствует в json файлах.

После создания контейнера:

Для этого уже много ответов выше. мой предпочтительный способ сделать это будет -

docker exec -t -i container /bin/bash

Ответ 6

В Ubuntu 14.04 работает Docker 1.3.1, я нашел корневую файловую систему контейнера на главной машине в следующем каталоге:

/var/lib/docker/devicemapper/mnt/<container id>/rootfs/

Информация о полной версии Docker:

Client version: 1.3.1
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 4e9bbfa
OS/Arch (client): linux/amd64
Server version: 1.3.1
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 4e9bbfa

Ответ 7

Ответ с наибольшим количеством голосов работает для меня, когда контейнер действительно запущен, но когда невозможно запустить и, например, вы хотите скопировать файлы из контейнера, это спасло меня раньше:

docker cp <container-name>:<path/inside/container> <path/on/host/>

Благодаря Docker CP (ссылка) вы можете копировать непосредственно из контейнера, как это было в любой другой части вашей файловой системы. Например, восстановление всех файлов внутри контейнера:

mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/

Обратите внимание, что вам не нужно указывать, что вы хотите копировать рекурсивно.

Ответ 8

Я использую другой грязный трюк, который является агностиком aufs/devicemapper.

Я смотрю на команду, что контейнер работает, например. docker ps и если это apache или java, я просто сделаю следующее:

sudo -s
cd /proc/$(pgrep java)/root/

и вы войдете в контейнер.

В основном вы можете использовать root cd в папке /proc/<PID>/root/, пока этот процесс запускается контейнером. Остерегайтесь символических ссылок не будет иметь смысла, используя этот режим.

Ответ 9

Ответ с наибольшим количеством голосов хороший, за исключением случаев, когда ваш контейнер не является реальной системой Linux.

Во многих контейнерах (особенно в go) нет стандартного двоичного файла (нет /bin/bash или /bin/sh). В этом случае вам необходимо получить непосредственный доступ к файлу фактических контейнеров:

Работает как шарм:

name=<name>
dockerId=$(docker inspect -f {{.Id}} $name)
mountId=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$dockerId/mount-id)
cd /var/lib/docker/aufs/mnt/$mountId

Примечание. Вам необходимо запустить его как root.

Ответ 10

Попробуйте использовать

docker exec -it <container-name> /bin/bash

Возможно, существует вероятность того, что bash не будет реализован. для этого вы можете использовать

docker exec -it <container-name> sh

Ответ 11

В моем случае никакая оболочка не поддерживалась в контейнере, кроме sh. Итак, это сработало как шарм

docker exec -it <container-name> sh

Ответ 12

Для меня это хорошо работает (благодаря последним комментариям для указания каталога /var/lib/docker/):

chroot /var/lib/docker/containers/2465790aa2c4*/root/

Здесь 2465790aa2c4 - это короткий идентификатор запущенного контейнера (как показано докерером ps), за которым следует звезда.

Ответ 13

Для драйвера docker aufs:

script найдет корневой каталог контейнера (Test on docker 1.7.1 и 1.10.3)

if [ -z "$1" ] ; then
 echo 'docker-find-root $container_id_or_name '
 exit 1
fi
CID=$(docker inspect   --format {{.Id}} $1)
if [ -n "$CID" ] ; then
    if [ -f  /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id ] ; then
        F1=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id)
       d1=/var/lib/docker/aufs/mnt/$F1
    fi
    if [ ! -d "$d1" ] ; then
        d1=/var/lib/docker/aufs/diff/$CID
    fi
    echo $d1
fi

Ответ 14

Вы можете использовать погружение для интерактивного просмотра содержимого изображения с помощью TUI

https://github.com/wagoodman/dive

enter image description here

Ответ 15

В более новых версиях Docker вы можете запустить docker exec [container_name], который запускает оболочку внутри вашего контейнера

Итак, чтобы получить список всех файлов в контейнере, просто запустите docker exec [container_name] ls

Ответ 16

Мой предпочтительный способ понять, что происходит внутри контейнера:

  • expose -p 8000

    docker run -it -p 8000:8000 image
    
  • Запустите сервер внутри него

    python -m SimpleHTTPServer
    

Ответ 17

Этот ответ поможет тем, кто хочет изучить файловую систему тонера, даже если контейнер не запущен.

Список контейнеров докеров:

docker ps

= > КОНТЕЙНЕР ID "4c721f1985bd"

Посмотрите точки монтирования тонера на локальную физическую машину (https://docs.docker.com/engine/tutorials/dockervolumes/):

docker inspect -f {{.Mounts}} 4c721f1985bd

= > [{/tmp/container-garren/tmp true rprivate}]

Это говорит мне, что локальный каталог физического компьютера /tmp/container -garren сопоставляется с пунктом назначения тонера dmper/tmp.

Знание локального каталога физического компьютера (/tmp/container-garren) означает, что я могу исследовать файловую систему независимо от того, запущен ли контейнер докеров. Это было важно для того, чтобы помочь мне понять, что существуют некоторые остаточные данные, которые не должны сохраняться даже после того, как контейнер не работал.

Ответ 18

Другим трюком является использование atomic, чтобы сделать что-то вроде:
mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt

Изображение Docker будет смонтировано в /path/to/mnt, чтобы вы его осмотрели.

Ответ 19

Только для LINUX

Самым простым способом, который я использовал, было использование proc dir, который должен быть запущен для проверки файлов контейнера докера.

  1. Узнайте идентификатор процесса (PID) контейнера и сохраните в некоторую переменную

    PID=$(docker inspect -f '{{.State.Pid}}' your-container-name-here)

  2. Убедитесь, что процесс контейнера запущен, и используйте переменную name, чтобы попасть в папку контейнера

    cd/proc/$PID/root

Если вы хотите пройти через каталог, не узнавая номер PID, просто с помощью этой длинной команды

cd /proc/$(docker inspect -f '{{.State.Pid}}' your-container-name-here)/root

Советы:

После того, как вы попадете внутрь контейнера, все, что вы сделаете, повлияет на фактический процесс контейнера, такой как остановка службы или изменение номера порта.

Надеюсь, это поможет

Примечание:

Этот метод работает, только если контейнер все еще работает, иначе каталог больше не будет существовать, если контейнер остановлен или удален

Ответ 20

Для уже запущенного контейнера вы можете:

dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])

cd /var/lib/docker/btrfs/subvolumes/$dockerId

Вам нужно быть root, чтобы cd в этот каталог. Если вы не root, попробуйте выполнить 'sudo su' перед запуском команды.

Изменить: Следуя v1.3, см. ответ Jiri - это лучше.

Ответ 21

Вы можете запустить bash внутри контейнера с помощью этого: $ docker run -it ubuntu /bin/bash

Ответ 22

Если вы используете драйвер хранилища AUFS, вы можете использовать мой сценарий docker-layer, чтобы найти любую корневую файловую систему контейнера (mnt) и слой readwrite:

# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt      : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f

Изменить 2018-03-28:
слой docker был заменен на docker-backup

Ответ 23

Команда docker exec для запуска команды в работающем контейнере может помочь в нескольких случаях.

Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Run a command in a running container

Options:
  -d, --detach               Detached mode: run command in the background
      --detach-keys string   Override the key sequence for detaching a
                             container
  -e, --env list             Set environment variables
  -i, --interactive          Keep STDIN open even if not attached
      --privileged           Give extended privileges to the command
  -t, --tty                  Allocate a pseudo-TTY
  -u, --user string          Username or UID (format:
                             [:])
  -w, --workdir string       Working directory inside the container

Например:

1) Доступ в bash к работающей файловой системе контейнера:

docker exec -it containerId bash 

2) Доступ в bash к работающей файловой системе контейнера от имени root для получения необходимых прав:

docker exec -it -u root containerId bash  

Это особенно полезно, чтобы иметь возможность выполнять некоторую обработку от имени root в контейнере.

3) Доступ в bash к работающей контейнерной файловой системе с определенным рабочим каталогом:

docker exec -it -w /var/lib containerId bash 

Ответ 24

Это запустит bash-сессию для изображения:

запуск докера --rm -it --entrypoint =/bin/bash