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?.
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
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
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 .
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.
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
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
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.
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.
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
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.
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
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.
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
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.
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.
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.
Meine bevorzugte Methode, um zu verstehen, was im Container vor sich geht, ist:
expose -p 8000
docker run -it -p 8000:8000 image
Starten Sie den Server darin
python -m SimpleHTTPServer
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.
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.
Ermitteln Sie die Prozess-ID (PID) des Containers und speichern Sie sie in einer Variablen
PID = $ (Docker inspizieren -f '{{.State.Pid}}' Ihren-Containernamen-hier)
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
Mit diesem Befehl können Sie eine Bash im Container ausführen: $ docker run -it ubuntu /bin/bash
Dies startet eine Bash-Sitzung für das Bild:
docker run --rm -it --entrypoint =/bin/bash
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