J'ai remarqué avec docker que j'ai besoin de comprendre ce qui se passe dans un conteneur ou quels fichiers existent dans ce conteneur. Un exemple est le téléchargement d'images à partir de l'index de docker - vous ne savez pas ce que l'image contient, il est donc impossible de démarrer l'application.
Ce qui serait idéal, c’est de pouvoir y entrer ou un équivalent. Existe-t-il un outil pour ce faire ou ma conception du docker est-elle erronée en pensant que je devrais pouvoir le faire?.
Méthode 1: instantané
Vous pouvez évaluer le système de fichiers du conteneur de cette manière:
# 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 à un moment précis. Le conteneur est toujours en cours d'exécution, aucune modification future n'est incluse.
Vous pouvez ultérieurement supprimer un 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 dans votre 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).
UPDATE - Méthode 3: nsenter
Utilisez nsenter
, voir http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/
La version abrégée est la suivante: avec nsenter, vous pouvez obtenir un shell dans un conteneur existant, même si ce conteneur n’exécute pas SSH ni aucun type de démon spécial
UPDATE - Méthode 4: exécution du menu fixe
La version 1.3 de Docker (la dernière version, vous devrez peut-être utiliser docker apt repo pour installer la dernière version à compter de novembre 2014) prend en charge la nouvelle commande exec
dont le comportement est similaire à nsenter
. Cette commande peut exécuter un nouveau processus dans un conteneur en cours d'exécution (le processus PID 1 doit déjà être en cours d'exécution). Vous pouvez exécuter /bin/bash
pour explorer l'état du conteneur:
docker exec -t -i mycontainer /bin/bash
UPDATE: EXPLORING!
Cette commande devrait vous laisser explorer un conteneur de menu fixe en cours d'exécution :
docker exec -it name-of-container bash
L'équivalent pour cela dans docker-compose serait:
docker-compose exec web bash
(web est le nom du service dans ce cas et il a tty par défaut.)
Une fois à l'intérieur, faites:
ls -lsa
ou toute autre commande bash comme:
cd ..
Cette commande devrait vous permettre d'explorer une image de menu fixe :
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 -it
signifie interactif ... et tty.
Cette commande devrait vous permettre d'inspecter un conteneur ou une image de menu fixe en cours d'exécution :
docker inspect name-of-container-or-image
Vous voudrez peut-être faire cela et vérifier s'il y a des bash
ou sh
là-dedans. Recherchez entrypoint ou cmd dans la déclaration json.
voir documentation de docker exec
Vous pouvez archiver le système de fichiers de votre conteneur dans un fichier tar:
docker export adoring_kowalevski > contents.tar
Cette méthode fonctionne même si votre conteneur est arrêté et ne dispose d'aucun programme Shell comme /bin/bash
. Je veux dire des images comme hello-world from documentation de Docker .
Le système de fichiers du conteneur se trouve dans le dossier de données de docker, normalement dans/var/lib/docker. Pour démarrer et inspecter un système de fichiers de conteneurs 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.
Avant la création du conteneur:
Si vous souhaitez explorer la structure de l'image montée à l'intérieur du conteneur, vous pouvez effectuer
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 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 le faire serait -
docker exec -t -i container /bin/bash
Sur buntu 14.04 en cours d'exécution 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 de 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
La réponse la plus votée marche pour moi lorsque le conteneur est réellement démarré, mais lorsqu'il est impossible de l'exécuter et que vous souhaitez par exemple copier des fichiers à partir du conteneur, cela m'a déjà enregistré:
docker cp <container-name>:<path/inside/container> <path/on/Host/>
Grâce à docker cp ( lien ), vous pouvez copier directement depuis le conteneur, comme il s’agissait de toute autre partie de votre système de fichiers. Par exemple, récupérer tous les fichiers dans un conteneur:
mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/
Notez qu'il n'est pas nécessaire de spécifier que vous souhaitez copier de manière récursive.
J'utilise un autre truc sale qui est agnostique aufs/devicemapper.
Je regarde la commande que le conteneur exécute, par exemple. docker ps
et s'il s'agit d'un Apache ou Java
, procédez comme suit:
Sudo -s
cd /proc/$(pgrep Java)/root/
et voila tu es dans le conteneur.
Fondamentalement, vous pouvez en tant que racine cd dans le dossier /proc/<PID>/root/
tant que ce processus est exécuté par le conteneur. Attention, les liens symboliques n'auront aucun sens si vous utilisez ce mode.
Essayez d'utiliser
docker exec -it <container-name> /bin/bash
Il est possible que bash ne soit pas implémenté. pour ça tu peux utiliser
docker exec -it <container-name> sh
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 pas de binaire standard (pas de /bin/bash
ou /bin/sh
). Dans ce cas, vous devrez accéder directement au fichier de conteneurs actuel:
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.
Dans mon cas, aucun shell n'était pris en charge dans le conteneur, à l'exception de sh
. Donc, cela a fonctionné comme un charme
docker exec -it <container-name> sh
Pour moi, celui-ci fonctionne bien (merci aux derniers commentaires pour avoir souligné le répertoire / var/lib/docker /):
chroot /var/lib/docker/containers/2465790aa2c4*/root/
Ici, 2465790aa2c4 est l'ID court du conteneur en cours d'exécution (affiché par du menu fixe ps ), suivi d'une étoile.
Pour le pilote docker aufs:
Le script trouvera le répertoire racine du conteneur (test sur le menu fixe 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
Sur les versions plus récentes de Docker, vous pouvez exécuter docker exec [container_name]
, qui exécute un shell à l'intérieur de votre conteneur.
Donc, pour obtenir la liste de tous les fichiers d’un conteneur, lancez simplement docker exec [container_name] ls
une autre astuce consiste à utiliser l'outil atomique pour faire quelque chose comme:
mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt
L'image de Docker sera montée sur /chemin/sur/mnt pour que vous puissiez l'inspecter.
Cette réponse aidera ceux (comme moi) qui souhaitent explorer le système de fichiers de volume du menu fixe, même si le conteneur n'est pas en cours d'exécution.
Liste des conteneurs docker en cours d'exécution:
docker ps
=> ID CONTENANT "4c721f1985bd"
Examinez les points de montage du volume du menu fixe 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 de la machine physique locale/tmp/container-garren est mappé sur la destination du volume du menu fixe/tmp.
Connaître le répertoire de la machine physique locale (/ tmp/container-garren) signifie que je peux explorer le système de fichiers, que le conteneur docker soit en cours d’exécution ou non. Cela était essentiel pour m'aider à comprendre qu'il existait des données résiduelles qui n'auraient pas dû être conservées même après la fermeture du conteneur.
Ma manière préférée de comprendre ce qui se passe à l'intérieur du conteneur est la suivante:
expose -p 8000
docker run -it -p 8000:8000 image
Démarrer le serveur à l'intérieur
python -m SimpleHTTPServer
vous pouvez utiliser dive pour afficher le contenu de l'image de manière interactive avec TUI
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 pour pouvoir écrire dans ce répertoire. Si vous n'êtes pas root, essayez 'Sudo su' avant d'exécuter la commande.
Edit: Après la v1.3, voir la réponse de Jiri - c'est mieux.
niquement pour LINUX
Le moyen le plus simple que j'utilise est d'utiliser proc dir, c'est-à-dire le conteneur, il doit être en cours d'exécution afin d'inspecter les fichiers du conteneur docker.
Connaître l'identifiant du processus (PID) du conteneur et le stocker dans une variable
PID = $ (docker inspect -f '{{.State.Pid}}' votre-conteneur-nom-ici)
Assurez-vous que le processus de conteneur est en cours d'exécution et utilisez la variable namto pour accéder au dossier du conteneur.
cd/proc/$ PID/root
Si vous voulez parcourir le répertoire sans connaître le numéro du PID simplement en utilisant cette longue commande
cd /proc/$(docker inspect -f '{{.State.Pid}}' your-container-name-here)/root
Conseils:
Une fois à l'intérieur du conteneur, tout ce que vous ferez aura une incidence sur le processus réel du conteneur, tel que l'arrêt du service ou la modification du numéro de port.
J'espère que ça aide
Note:
Cette méthode ne fonctionne que si le conteneur est toujours en cours d'exécution, sinon le répertoire n'existerait plus si le conteneur s'était arrêté ou avait été supprimé.
Si vous utilisez le pilote de stockage AUFS, vous pouvez utiliser mon script docker-layer pour rechercher la racine du système de fichiers du conteneur (mnt) et la couche readwrite:
# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
Modifier le 2018-03-28:
docker-layer a été remplacé par docker-backup
Vous pouvez exécuter une bash à l'intérieur du conteneur avec ceci: $ docker run -it ubuntu /bin/bash
Cela lancera une session bash pour l'image:
docker run --rm -it --entrypoint =/bin/bash
La commande docker exec
permettant d'exécuter une commande dans un conteneur en cours d'exécution peut être utile dans plusieurs cas.
Utilisation: docker exec [OPTIONS] COMMANDER CONTENEUR [ARG ...] Exécuter une commande dans un conteneur en cours d'exécution. Options: -D, --detach Mode détaché: commande d'exécution en arrière-plan --Detach-keys chaîne Remplacer la séquence de touches permettant de détacher un conteneur -e, --env list Définir les variables d'environnement -i, --interactive Conserver STDIN ouvert même s'il n'est pas attaché --privileged Donner des privilèges étendus à la commande - t, --tty Alloue un pseudo-TTY -u, --user string Nom d'utilisateur ou UID (format: [:]) -w, --workdir string Working répertoire à l'intérieur du conteneur
Par exemple :
1) Accéder en bash au système de fichiers conteneur en cours d’exécution:
docker exec -it containerId bash
2) Accéder en bash au système de fichiers du conteneur en cours d’exécution en tant que root pour pouvoir disposer des droits requis:
docker exec -it -u root containerId bash
Ceci est particulièrement utile pour pouvoir effectuer certains traitements en tant que racine dans un conteneur.
3) Accéder en 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