web-dev-qa-db-fra.com

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 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?.

518
user2668128

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

voir documentation en ligne de commande Docker

612
Jiri

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

voir documentation de docker-compose exec

voir docker inspecter la documentation

201
Khalil Gharbaoui

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 .

140
Ilya Murav'jov

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.

41
Rovanion

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
24
Gaurav24

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
17
piercebot

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.

16
Julius Printz

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.

11
telamon

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
11
Gaurav Sharma

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.

10
Florent

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
6
shx

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.

4
dashohoxha

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
4
qxo

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

3
xoher

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.

3

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.

3
Garren S

Ma manière préférée de comprendre ce qui se passe à l'intérieur du conteneur est la suivante:

  1. expose -p 8000

    docker run -it -p 8000:8000 image
    
  2. Démarrer le serveur à l'intérieur

    python -m SimpleHTTPServer
    
3
kgnete

vous pouvez utiliser dive pour afficher le contenu de l'image de manière interactive avec TUI

https://github.com/wagoodman/dive

enter image description here

3
Andy Wong

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.

2
AlonL

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.

  1. 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)

  2. 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é.

2

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

1
Vince

Vous pouvez exécuter une bash à l'intérieur du conteneur avec ceci: $ docker run -it ubuntu /bin/bash

1
Yang Yu

Cela lancera une session bash pour l'image:

docker run --rm -it --entrypoint =/bin/bash

1
LeYAUable

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 
1
davidxxx