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?

367
demandé sur dreftymac 2013-12-28 14:29:02

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

Voir documentation en ligne de commande Docker

479
répondu Jiri 2014-11-29 17:18:36

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

119
répondu Khalil Gharbaoui 2018-05-10 16:42:30

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 .

111
répondu Ilya Murav'jov 2015-04-23 20:03:42

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.

38
répondu Rovanion 2014-03-29 12:19:17

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
17
répondu piercebot 2016-01-13 16:39:31

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
13
répondu Gaurav24 2017-03-08 16:52:20

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.

10
répondu telamon 2015-09-10 10:10:48

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
8
répondu Gaurav Sharma 2017-08-31 12:48:14

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.

7
répondu Julius Printz 2017-02-21 13:31:24

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.

6
répondu Florent 2018-08-24 00:08:01

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.

4
répondu dashohoxha 2014-08-15 08:18:36

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
4
répondu qxo 2016-04-14 10:11:23

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
4
répondu shx 2018-07-17 18:24:22

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

3
répondu xoher 2016-03-11 10:56:19

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.

3
répondu AlonL 2016-10-31 19:28:05

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.

3
répondu Giuseppe Scrivano 2017-03-03 14:01:38

Ma façon préférée de comprendre ce qui se passe à l'intérieur du conteneur est:

  1. Exposer-p 8000

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

    python -m SimpleHTTPServer
    
2
répondu kgnete 2016-10-02 12:31:22

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.

2
répondu Garren S 2016-12-21 19:43:24

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

1
répondu Yang Yu 2017-03-03 05:49:36

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 
1
répondu davidxxx 2018-07-08 10:45:28

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

0
répondu Vince 2018-03-28 22:00:38