Изучение файловой системы контейнера 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, который должен быть запущен для проверки файлов контейнера докера.
Узнайте идентификатор процесса (PID) контейнера и сохраните в некоторую переменную
PID=$(docker inspect -f '{{.State.Pid}}' your-container-name-here)
Убедитесь, что процесс контейнера запущен, и используйте переменную 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