Изучение файловой системы контейнера 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 для вас, чтобы осмотреть его.
мой предпочтительный способ понять, что происходит внутри контейнера:
-
expose-p 8000
docker run -it -p 8000:8000 image
-
запустить сервер внутри
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. Это было важно, чтобы помочь мне понять, что есть некоторые остаточные данные, которые не должны были сохраняться даже после того, как контейнер не работал.
на 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-резервное копирование