it-swarm.com.de

Erkundung des Dateisystems des Docker-Containers

Bei Docker ist mir aufgefallen, dass ich verstehen muss, was in einem Container passiert oder welche Dateien darin vorhanden sind. Ein Beispiel ist das Herunterladen von Bildern aus dem Docker-Index. Sie haben keine Ahnung, was das Bild enthält, und können die Anwendung daher nicht starten.

Ideal wäre es, in sie hineinschießen zu können oder etwas Ähnliches. Gibt es ein Werkzeug, um dies zu tun, oder ist meine Konzeptualisierung von Docker falsch, wenn ich denke, dass ich dazu in der Lage sein sollte?.

518
user2668128

Methode 1: Schnappschuss

Sie können das Container-Dateisystem folgendermaßen auswerten:

# 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

Auf diese Weise können Sie das Dateisystem des laufenden Containers im genauen Zeitpunkt auswerten. Container läuft noch, zukünftige Änderungen sind nicht enthalten.

Sie können den Schnappschuss später mit löschen (Dateisystem des laufenden Containers ist nicht betroffen!):

docker rmi mysnapshot

Methode 2: ssh

Wenn Sie kontinuierlichen Zugriff benötigen, können Sie sshd in Ihrem Container installieren und den sshd-Daemon ausführen:

 docker run -d -p 22 mysnapshot /usr/sbin/sshd -D

 # you need to find out which port to connect:
 docker ps

Auf diese Weise können Sie Ihre App mit ssh ausführen (verbinden und ausführen, was Sie wollen).

UPDATE - Methode 3: nsenter

Verwenden Sie nsenter, siehe http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/

Die Kurzversion lautet: Mit nsenter können Sie eine Shell in einen vorhandenen Container einbinden, selbst wenn dieser Container kein SSH oder keinen speziellen Daemon ausführt.

UPDATE - Methode 4: docker exec

Docker Version 1.3 (die neueste Version muss möglicherweise mit docker apt repo installiert werden, um die neueste Version ab November 2014 zu installieren) unterstützt den neuen Befehl exec, der sich ähnlich wie nsenter verhält. Dieser Befehl kann einen neuen Prozess in einem bereits laufenden Container ausführen (in dem Container muss bereits ein PID 1-Prozess ausgeführt werden). Sie können /bin/bash ausführen, um den Container-Status zu ermitteln:

docker exec -t -i mycontainer /bin/bash

siehe Docker-Befehlszeilendokumentation

612
Jiri

UPDATE: EXPLORING!

Mit diesem Befehl können Sie einen laufenden Docker-Container untersuchen :

docker exec -it name-of-container bash

Das Äquivalent dazu in docker-compose wäre:

docker-compose exec web bash

(web ist in diesem Fall der Name des Dienstes und hat standardmäßig tty.)

Sobald Sie drinnen sind, machen Sie:

ls -lsa

oder ein anderer bash Befehl wie:

cd ..

Mit diesem Befehl können Sie ein Docker-Image durchsuchen :

docker run --rm -it --entrypoint=/bin/bash name-of-image

einmal drinnen tun:

ls -lsa

oder ein anderer bash Befehl wie:

cd ..

Der -it steht für interaktiv ... und tty.


Mit diesem Befehl können Sie einen laufenden Docker-Container oder ein laufendes Docker-Image überprüfen :

docker inspect name-of-container-or-image

Möglicherweise möchten Sie dies tun und herausfinden, ob sich bash oder sh darin befindet. Suchen Sie in json return nach entrypoint oder cmd.

siehe Docker Exec-Dokumentation

siehe Dokumentation von docker-compose exec

siehe Docker inspizieren Dokumentation

201

Sie können das Dateisystem Ihres Containers in einer TAR-Datei archivieren:

docker export adoring_kowalevski > contents.tar

Dieser Weg funktioniert auch, wenn Ihr Container gestoppt ist und kein Shell-Programm wie /bin/bash hat. Ich meine Bilder wie Hallo-Welt aus Docker-Dokumentation .

140
Ilya Murav'jov

Das Dateisystem des Containers befindet sich im Datenordner von docker, normalerweise in/var/lib/docker. Gehen Sie wie folgt vor, um ein laufendes Containerdateisystem zu starten und zu überprüfen:

hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash

Und jetzt ist das aktuelle Arbeitsverzeichnis das Stammverzeichnis des Containers.

41
Rovanion

Vor der Containererstellung:

Wenn Sie die Struktur des im Container eingebundenen Bildes untersuchen möchten, können Sie dies tun

Sudo docker image save image_name > image.tar
tar -xvf image.tar

Dies gibt Ihnen die Sichtbarkeit aller Ebenen eines Bildes und seiner Konfiguration, die in JSON-Dateien vorhanden sind.

Nach der Containererstellung:

Hierzu gibt es oben schon viele Antworten. Mein bevorzugter Weg dies zu tun wäre -

docker exec -t -i container /bin/bash
24
Gaurav24

Unter buntu 14.04 running Docker 1.3.1 fand ich das Container-Root-Dateisystem auf dem Host-Rechner im folgenden Verzeichnis:

/var/lib/docker/devicemapper/mnt/<container id>/rootfs/

Vollständige Docker-Versionsinformationen:

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

Die am besten bewertete Antwort funktioniert für mich, wenn der Container tatsächlich gestartet wird, aber wenn es nicht möglich ist, ausgeführt zu werden und Sie zum Beispiel Dateien aus dem Container kopieren möchten, hat mich das zuvor gerettet:

docker cp <container-name>:<path/inside/container> <path/on/Host/>

Dank docker cp ( link ) können Sie direkt aus dem Container kopieren, wie es jeder andere Teil Ihres Dateisystems war. So stellen Sie beispielsweise alle Dateien in einem Container wieder her:

mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/

Beachten Sie, dass Sie nicht angeben müssen, dass Sie rekursiv kopieren möchten.

16
Julius Printz

Ich benutze einen anderen schmutzigen Trick, der auf/devicemapper agnostisch ist.

Ich schaue auf den Befehl, dass der Container ausgeführt wird, z. docker ps und wenn es ein Apache oder Java ist, mache ich einfach Folgendes:

Sudo -s
cd /proc/$(pgrep Java)/root/

und voilá du bist im container.

Grundsätzlich können Sie als Root-CD in /proc/<PID>/root/ Ordner, solange dieser Prozess vom Container ausgeführt wird. Beachten Sie, dass Symlinks in diesem Modus keinen Sinn ergeben.

11
telamon

Versuchen Sie es mit

docker exec -it <container-name> /bin/bash

Möglicherweise ist bash nicht implementiert. dafür kannst du verwenden

docker exec -it <container-name> sh
11
Gaurav Sharma

Die am häufigsten gewählte Antwort ist gut, es sei denn, Ihr Container ist kein tatsächliches Linux-System.

Viele Container (insbesondere die auf Go basierenden) haben keine Standard-Binärdatei (kein /bin/bash oder /bin/sh). In diesem Fall müssen Sie direkt auf die eigentliche Containerdatei zugreifen:

Klappt wunderbar:

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

Hinweis: Sie müssen es als root ausführen.

10
Florent

In meinem Fall wurde keine Shell im Container unterstützt außer sh. Das funktionierte also wie ein Zauber

docker exec -it <container-name> sh
6
shx

Für mich funktioniert dies gut (dank der letzten Kommentare für den Hinweis auf das Verzeichnis / var/lib/docker /):

chroot /var/lib/docker/containers/2465790aa2c4*/root/

Hier ist 2465790aa2c4 die Kurz-ID des ausgeführten Containers (angezeigt durch docker ps ), gefolgt von einem Stern.

4
dashohoxha

Für Docker aufs Fahrer:

Das Skript findet das Container-Stammverzeichnis (Test auf Docker 1.7.1 und 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

In neueren Docker-Versionen können Sie docker exec [container_name] ausführen, wodurch eine Shell in Ihrem Container ausgeführt wird

Um eine Liste aller Dateien in einem Container zu erhalten, führen Sie einfach docker exec [container_name] ls aus.

3
xoher

ein weiterer Trick ist die Verwendung des atomar Tools, um etwas zu tun wie:

mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt

Das Docker-Image wird an /path/to/mnt angehängt, damit Sie es überprüfen können.

3

Diese Antwort hilft jenen (wie mir), die das Docker-Volume-Dateisystem erkunden möchten, auch wenn der Container nicht ausgeführt wird.

Liste laufender Docker-Container:

docker ps

=> CONTAINER ID "4c721f1985bd"

Überprüfen Sie die Docker-Volume-Bereitstellungspunkte auf Ihrem lokalen physischen Computer ( https://docs.docker.com/engine/tutorials/dockervolumes/ ):

docker inspect -f {{.Mounts}} 4c721f1985bd

=> [{/ tmp/container-garren/tmp true rprivate}]

Dies sagt mir, dass das lokale physische Maschinenverzeichnis/tmp/container-garren dem Docker-Volume-Ziel/tmp zugeordnet ist.

Wenn ich das lokale physische Maschinenverzeichnis (/ tmp/container-garren) kenne, kann ich das Dateisystem durchsuchen, unabhängig davon, ob der Docker-Container ausgeführt wird oder nicht. Dies war von entscheidender Bedeutung, um herauszufinden, dass es einige Restdaten gab, die nicht hätten bestehen dürfen, auch wenn der Container nicht lief.

3
Garren S

Meine bevorzugte Methode, um zu verstehen, was im Container vor sich geht, ist:

  1. expose -p 8000

    docker run -it -p 8000:8000 image
    
  2. Starten Sie den Server darin

    python -m SimpleHTTPServer
    
3
kgnete

mit dive können Sie den Bildinhalt interaktiv mit TUI anzeigen

https://github.com/wagoodman/dive

enter image description here

3
Andy Wong

Für einen bereits laufenden Container können Sie Folgendes tun:

dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])

cd /var/lib/docker/btrfs/subvolumes/$dockerId

Sie müssen root sein, um in dieses Verzeichnis zu wechseln. Wenn Sie nicht root sind, versuchen Sie es mit 'Sudo su', bevor Sie den Befehl ausführen.

Bearbeiten: Nach Version 1.3 finden Sie die Antwort von Jiri - es ist besser.

2
AlonL

Nur für LINUX

Die einfachste Methode, die ich benutzte, war die Verwendung von proc dir, das heißt, der Container muss ausgeführt werden, um die Docker-Containerdateien zu überprüfen.

  1. Ermitteln Sie die Prozess-ID (PID) des Containers und speichern Sie sie in einer Variablen

    PID = $ (Docker inspizieren -f '{{.State.Pid}}' Ihren-Containernamen-hier)

  2. Stellen Sie sicher, dass der Containerprozess ausgeführt wird, und verwenden Sie den Variablennamen, um in den Containerordner zu gelangen

    cd/proc/$ PID/root

Wenn Sie mit diesem langen Befehl durch das Verzeichnis gelangen möchten, ohne die PID-Nummer herauszufinden

cd /proc/$(docker inspect -f '{{.State.Pid}}' your-container-name-here)/root

Tips:

Nachdem Sie in den Container gelangt sind, wirkt sich alles, was Sie tun, auf den tatsächlichen Prozess des Containers aus, z. B. das Beenden des Dienstes oder das Ändern der Portnummer.

Ich hoffe es hilft

Anmerkung:

Diese Methode funktioniert nur, wenn der Container noch ausgeführt wird. Andernfalls würde das Verzeichnis nicht mehr existieren, wenn der Container angehalten oder entfernt wurde

Wenn Sie den AUFS-Speichertreiber verwenden, können Sie mein Docker-Layer Skript verwenden, um den Dateisystemstamm (mnt) und den Readwrite-Layer eines beliebigen Containers zu finden:

# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt      : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f

Edit 2018-03-28:
Docker-Layer wurde ersetzt durch Docker-Backup

1
Vince

Mit diesem Befehl können Sie eine Bash im Container ausführen: $ docker run -it ubuntu /bin/bash

1
Yang Yu

Dies startet eine Bash-Sitzung für das Bild:

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

1
LeYAUable

Der Befehl docker exec zum Ausführen eines Befehls in einem laufenden Container kann in mehreren Fällen hilfreich sein.

 
 Verwendung: docker exec [OPTIONEN] CONTAINER BEFEHL [ARG ...] 
 
 Führen Sie einen Befehl in einem laufenden Container aus 
 
 Optionen: 
 -D, --detach Detached Mode: Befehl im Hintergrund ausführen. 
 --Detach-keys string Die Tastenfolge zum Entfernen eines 
 Containers überschreiben. 
 -e, --env Liste Setze Umgebungsvariablen 
 -i, --interactive Lasse STDIN offen, auch wenn es nicht angehängt ist 
 --privilegiert Erteile erweiterte Rechte für den Befehl 
 - t, --tty Pseudo-TTY zuweisen 
 -u, --user string Benutzername oder UID (Format: 
 [:]) 
 -w, --workdir string Working Verzeichnis im Container 
 

Beispielsweise :

1) Zugriff in Bash auf das laufende Container-Dateisystem:

docker exec -it containerId bash 

2) Zugriff in Bash auf das laufende Container-Dateisystem als root, um die erforderlichen Rechte zu haben:

docker exec -it -u root containerId bash  

Dies ist besonders nützlich, um als Root in einem Container etwas verarbeiten zu können.

3) Zugriff in Bash auf das laufende Container-Dateisystem mit einem bestimmten Arbeitsverzeichnis:

docker exec -it -w /var/lib containerId bash 
1
davidxxx