Exploration du système de fichiers du conteneur Docker
J'ai remarqué avec docker que j'ai besoin de comprendre ce qui se passe dans un conteneur ou quels fichiers existent là-dedans. Un exemple est le téléchargement d'images à partir de l'index docker - vous n'avez pas la moindre idée de ce que l'image Contient, il est donc impossible de démarrer l'application.
Ce qui serait idéal est de pouvoir ssh en eux ou équivalent. Existe-t-il un outil pour le faire, ou ma conceptualisation de docker est-elle fausse en pensant que je devrais être capable de le faire?
21 réponses
Méthode 1: snapshoting
Vous pouvez évaluer le système de fichiers conteneur de cette façon:
# 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
De cette façon, vous pouvez évaluer le système de fichiers du conteneur en cours d'exécution dans le moment précis. Le conteneur est toujours en cours d'exécution, aucun changement futur n'est inclus.
Vous pouvez ensuite supprimer l'instantané en utilisant (le système de fichiers du conteneur en cours d'exécution n'est pas affecté!):
docker rmi mysnapshot
Méthode 2: ssh
Si vous avez besoin d'un accès continu, vous pouvez installer sshd conteneur et exécuter le démon sshd:
docker run -d -p 22 mysnapshot /usr/sbin/sshd -D
# you need to find out which port to connect:
docker ps
De cette façon, vous pouvez exécuter votre application en utilisant ssh (connectez-vous et exécutez ce que vous voulez).
Mise à jour-Méthode 3: nsenter
Utiliser nsenter
, voir http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/
La version courte est: avec nsenter, vous pouvez obtenir un shell dans un conteneur existant, même si ce conteneur n'exécute pas SSH ou n'importe quel type de but spécial démon
Mise à jour-méthode 4: Docker exec
Docker version 1.3 (dernière, vous devrez peut-être utiliser Docker apt repo pour installer la dernière version à partir de novembre 2014) prend en charge la nouvelle commande exec
qui se comportent comme nsenter
. Cette commande peut exécuter un nouveau processus dans un conteneur déjà en cours d'exécution (le conteneur doit avoir un processus PID 1 déjà en cours d'exécution). Vous pouvez exécuter /bin/bash
pour explorer l'état du conteneur:
docker exec -t -i mycontainer /bin/bash
MISE À JOUR: EXPLORER!
Cette commande devrait vous permettre d'explorer un conteneur Docker en cours d'exécution :
docker exec -it name-of-container bash
Une fois à l'intérieur faire:
ls -lsa
Ou toute autre commande bash comme:
cd ..
Cette commande devrait vous permettre d'explorer une image docker :
docker run --rm -it --entrypoint=/bin/bash name-of-image
Une fois à l'intérieur faire:
ls -lsa
Ou toute autre commande bash comme:
cd ..
Le {[6] } signifie interactif... et ats
Vous pouvez archiver le système de fichiers de votre conteneur dans le fichier tar:
docker export adoring_kowalevski > contents.tar
Cette façon fonctionne même si votre conteneur est arrêté et n'a aucun programme shell comme /bin/bash
. Je veux dire des images comme hello-world de documentation Docker .
Le système de fichiers du conteneur est dans le dossier de données de docker, normalement dans /var/lib/menu fixe. Pour démarrer et inspecter un système de fichiers containers en cours d'exécution, procédez comme suit:
hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash
Et maintenant, le répertoire de travail actuel est la racine du conteneur.
Sur Ubuntu 14.04 exécutant docker 1.3.1 , j'ai trouvé le système de fichiers racine du conteneur sur la machine hôte dans le répertoire suivant:
/var/lib/docker/devicemapper/mnt/<container id>/rootfs/
Informations complètes sur la version du 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
Avant La Création Du Conteneur:
Si vous explorez la structure de l'image qui est montée à l'intérieur du conteneur, vous pouvez faire
sudo docker image save image_name > image.tar
tar -xvf image.tar
Cela vous donnerait la visibilité de toutes les couches d'une image et de sa configuration qui est présente dans les fichiers json.
Après la création du conteneur:
Pour cela, il y a déjà beaucoup de réponses ci-dessus. ma façon préférée de faire ce serait -
docker exec -t -i container /bin/bash
J'utilise un autre truc sale qui est agnostique aufs / devicemapper.
Je regarde la commande que le conteneur est en cours d'exécution par exemple docker ps
et si c'est un apache ou java
je fais juste ce qui suit:
sudo -s
cd /proc/$(pgrep java)/root/
Et voilà, vous êtes à l'intérieur du conteneur.
Fondamentalement, vous pouvez en tant que CD racine dans le dossier /proc/<PID>/root/
tant que ce processus est exécuté par le conteneur. Méfiez-vous des liens symboliques n'auront pas de sens en utilisant ce mode.
Essayez d'utiliser
docker exec -it <container-name> /bin/bash
Il pourrait y avoir une possibilité que bash ne soit pas implémenté. pour cela, vous pouvez utiliser
docker exec -it <container-name> sh
La réponse la plus upvoted fonctionne pour moi lorsque le conteneur est réellement démarré, mais quand il n'est pas possible de s'exécuter et que vous voulez par exemple copier des fichiers du conteneur, cela m'a déjà sauvé:
docker cp <container-name>:<path/inside/container> <path/on/host/>
Grâce à Docker cp (link), Vous pouvez copier directement à partir du conteneur comme c'était n'importe quelle autre partie de votre système de fichiers. Par exemple, récupérer tous les fichiers à l'intérieur d'un conteneur:
mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/
Notez que vous n'avez pas besoin de spécifier que vous souhaitez copier récursivement.
La réponse la plus votée est bonne sauf si votre conteneur n'est pas un système Linux réel.
De nombreux conteneurs (en particulier ceux basés sur go) n'ont aucun binaire standard (no / bin / bash, / bin / sh). Dans ce cas, vous devrez accéder directement au fichier containers:
Fonctionne comme un charme:
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
Remarque: Vous devez l'exécuter en tant que root.
Pour moi, celui-ci fonctionne bien (merci pour les derniers commentaires pour préciser le répertoire /var/lib/menu fixe/):
chroot /var/lib/docker/containers/2465790aa2c4*/root/
Ici, 2465790aa2c4 {[3] } est l'identifiant court du conteneur en cours d'exécution (tel qu'affiché par docker ps), suivi d'une étoile.
Pour le pilote Docker aufs:
Le script trouvera le répertoire racine du conteneur (Test sur Docker 1.7.1 et 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
Dans mon cas, aucun shell n'a été pris en charge dans le conteneur sauf sh
. Donc, cela a fonctionné comme un charme
docker exec -it <container-name> sh
Sur les nouvelles versions de Docker, vous pouvez exécuter {[0] } qui exécute un shell dans votre conteneur
Donc, pour obtenir une liste de tous les fichiers dans un conteneur, il suffit d'exécuter docker exec [container_name] ls
Pour un conteneur déjà en cours d'exécution, vous pouvez faire:
dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])
cd /var/lib/docker/btrfs/subvolumes/$dockerId
Vous devez être root afin de cd dans ce répertoire. Si vous n'êtes pas root, essayez 'sudo su' avant d'exécuter la commande.
Edit: après v1. 3, voir la réponse de Jiri - c'est mieux.
Une autre astuce consiste à utiliser l'outil atomic pour faire quelque chose comme:
mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt
L'image Docker sera montée sur / path / to / mnt pour que vous puissiez l'inspecter.
Ma façon préférée de comprendre ce qui se passe à l'intérieur du conteneur est:
-
Exposer-p 8000
docker run -it -p 8000:8000 image
-
Démarrer le serveur à l'intérieur
python -m SimpleHTTPServer
Cette réponse aidera ceux (comme moi) qui veulent explorer le système de fichiers de volume Docker même si le conteneur n'est pas en cours d'exécution.
Liste des conteneurs Docker en cours d'exécution:
docker ps
= > identifiant du conteneur "4c721f1985bd"
Regardez les points de montage du volume docker sur votre machine physique locale ( https://docs.docker.com/engine/tutorials/dockervolumes/):
docker inspect -f {{.Mounts}} 4c721f1985bd
=> [{ /tmp/conteneur-garren /tmp vrai rprivate}]
Cela me dit que le répertoire physique local de la machine / tmp / container-garren est mappé sur la destination du volume docker / tmp.
Connaître le répertoire physique local de la machine (/tmp / container-garren) signifie que je peux explorer le système de fichiers si le conteneur docker est en cours d'exécution ou non. Cela était essentiel pour m'aider à comprendre qu'il y avait des données résiduelles qui n'auraient pas dû persister même après que le conteneur ne fonctionnait pas.
Vous pouvez exécuter un bash à l'intérieur du conteneur avec ceci:
$ docker run -it ubuntu /bin/bash
La commande docker exec
pour exécuter une commande dans un conteneur en cours d'exécution peut aider dans plusieurs cas.
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
Par exemple :
1) accès dans bash au système de fichiers conteneur en cours d'exécution:
docker exec -it containerId bash
2) accéder dans bash au système de fichiers conteneur en cours d'exécution en tant que root pour pouvoir avoir les droits requis:
docker exec -it -u root containerId bash
Ceci est particulièrement utile pour pouvoir effectuer un traitement en tant que root dans un conteneur.
3) accès dans bash au système de fichiers conteneur en cours d'exécution avec un répertoire de travail spécifique:
docker exec -it -w /var/lib containerId bash
Si vous utilisez le pilote de stockage AUFS, vous pouvez utiliser mon script Docker-layer pour trouver la racine du système de fichiers (mnt) et la couche readwrite d'un conteneur:
# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
Modifier 2018-03-28:
docker-couche a été remplacé par panneau-sauvegarde