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

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

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

21 ответов


метод 1: snapshoting

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

# 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 (последнее, Вам может потребоваться использовать Docker apt repo для установки последней версии с ноября 2014 года) поддерживает новую команду exec которые ведут себя подобно nsenter. Эта команда может запускать новый процесс в уже запущенном контейнере (контейнер должен иметь уже запущенный процесс PID 1). Ты можешь бежать. /bin/bash чтобы исследовать состояние контейнера:

docker exec -t -i mycontainer /bin/bash

посмотреть документация командной строки Docker


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

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

docker exec -it name-of-container bash

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

ls -lsa

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

cd ..

эта команда должна позволить тебе исследуйте изображение docker:

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

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

ls -lsa

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

cd ..

на -it стенды для интерактивных... и телетайп


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

docker export adoring_kowalevski > contents.tar

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


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

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

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


On Ubuntu 14.04 под управлением настройки 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

Перед Созданием Контейнера :

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

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

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

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

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

docker exec -t -i container /bin/bash

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

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

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

и вуаля вы внутри контейнера.

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


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

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

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

docker exec -it <container-name> sh

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

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

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

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

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


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

многие контейнеры (особенно основанные на go) не имеют стандартного двоичного файла (no /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.


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

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

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


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

скрипт найдет корневой каталог контейнера (тест на docker 1.7.1 и 1.10.3 )

if [ -z "" ] ; then
 echo 'docker-find-root $container_id_or_name '
 exit 1
fi
CID=$(docker inspect   --format {{.Id}} )
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

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

docker exec -it <container-name> sh

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

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


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

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

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

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

Edit: после v1.3, см. ответ Иржи-это лучше.


еще один трюк-использовать атомные сделать что-то вроде:

mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt

изображение Docker будет смонтировано в / путь/к / mnt для вас, чтобы осмотреть его.


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

  1. expose-p 8000

    docker run -it -p 8000:8000 image
    
  2. запустить сервер внутри

    python -m SimpleHTTPServer
    

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

список запущенных контейнеров docker:

docker ps

=> контейнер ИД "4c721f1985bd"

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

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

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

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

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


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


на 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 

Если вы используете драйвер хранения AUFS, вы можете использовать my настройки слоя скрипт для поиска корня файловой системы любого контейнера (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-layer был заменен на docker-резервное копирование