Wie kann ich eine Docker-Container-Initialisierung debuggen?

Ich hatte ein Problem mit einem Container, obwohl er perfekt aufgebaut ist, startet er nicht richtig. Die Ursache ist eine Problemumgehung, die ich der Docker-Datei hinzugefügt habe (für ein selbst konfiguriertes / etc / hosts-Routing)

RUN mkdir -p -- /lib-override /etc-override && cp /lib/libnss_files.so.2 /lib-overrideADD hosts.template /etc-override/hostsRUN perl -pi -e 's:/etc/hosts:/etc-override/hosts:g' /lib-override/libnss_files.so.2ENV LD_LIBRARY_PATH /lib-override

Offensichtlich gibt es dort einen Fehler, aber ich frage mich, wie ich mehr Informationen darüber erhalten kann, was Docker während der Ausführung tut. zum Beispiel funktioniert das:

$ docker run image lsusr bin ...

Aber das tut es nicht:

$ docker run image ls -l$

Die Protokolle enthalten nichts und ich kann auch keine interaktive Shell aufrufen. Ich kann strace verwenden, um zu sehen, was passiert, aber ich hatte gehofft, dass es einen besseren Weg gibt.

Gibt es eine Möglichkeit, Docker ausführlicher einzustellen?

BEARBEITEN: Danke an Andrew D. Ich weiß jetzt, was mit dem obigen Code nicht stimmt (ich habe ihn gelassen, damit seine Antwort verstanden werden kann). Jetzt ist das Problem immer noch, wie ich so etwas debuggen oder ein paar Einblicke in das Warum bekommen kann ls -l warum gescheitert ls tat es nicht.

BEARBEITEN: Das -D= true könnte mehr ausgeben, wenn auch nicht in meinem Fall...

Docker events befehl kann helfen und Docker-Protokolle der Befehl kann Protokolle abrufen, auch nachdem das Image nicht gestartet werden konnte.

Erster Start docker events im Hintergrund, um zu sehen, was los ist.

docker events&

Führen Sie dann Ihren Fehler aus docker run ... Befehl. Dann sollten Sie so etwas wie das Folgende auf dem Bildschirm sehen:

2015-12-22T15:13:05.503402713+02:00 xxxxxxxacd8ca86df9eac5fd5466884c0b42a06293ccff0b5101b5987f5da07d: (from xxx/xxx:latest) die

Dann können Sie die Start-Hex-ID aus der vorherigen Nachricht oder der Ausgabe des Befehls Ausführen abrufen. Dann können Sie es mit dem Befehl logs verwenden:

docker logs <copy the instance id from docker events messages on screen>

Sie sollten jetzt eine Ausgabe des fehlgeschlagenen Image-Starts sehen.

Wie @alexkb in einem Kommentar vorgeschlagen hat: docker events& kann problematisch sein, wenn Ihr Container ständig von einem AWS ECS-Dienst neu gestartet wird. In diesem Szenario ist es möglicherweise einfacher, die Container-Hex-ID aus den Protokollen abzurufen /var/log/ecs/ecs-agent.log.<DATE>. Dann benutze Docker logs <hex id>.

Nun, das Beste, was ich bisher herausgefunden habe, ist:

#stop the current demon and start it in debug modussudo service docker stopdockerd -D # --debug

Starten Sie den Client einfach von einer neuen Shell aus. Das Missverständnis war zu glauben, dass der Kunde überhaupt etwas tut... nun, es kommuniziert nur mit dem Dämon, also willst du nicht Debug der Client, aber der Daemon selbst (normalerweise).

In meinem Fall ist das -a (an STDOUT / STDERR anhängen) Flag war genug:

user@machine:~$ docker start -a server_nameError: The directory named as part of the path /log/log_path/app.log does not exist.For help, use /usr/bin/supervisord -h

Es zeigte den Startfehler (in unserem Fall einen fehlenden Protokollpfad, der von verwendet wurde supervisord). Ich gehe davon aus, dass die meisten Container-Startfehler auch hier auftauchen würden.

Ich kann Ihre Frage nicht beantworten, wie Sie die Docker-Ausgabe vollständiger machen können, aber ich kann Ihnen sagen, dass das direkte Ersetzen einer Zeichenfolge durch einen regulären Ausdruck in einer .so-Datei ein bisschen verrückt ist: Der Zeichenfolge ist nur so viel Speicherplatz zugewiesen, und wenn Sie die Datei-Offsets anderer Einträge ändern, wird die ELF-Datei beschädigt. Versuchen Sie, objdump oder readelf in Ihrer .so-Datei auszuführen, nachdem Sie den Befehl perl ausgeführt haben (vor der Änderung von LD_LIBRARY_PATH) außerhalb eines Containers -- Dollars zu Donuts ist es jetzt korrupt.

Der Grund, warum es funktioniert in diesem leider notwendigen Hack liegt daran, dass "tmp" und "etc" die gleiche Zeichenfolgenlänge haben, sodass sich keine Offsets ändern. Betrachten Sie das Verzeichnis /dkr oder ähnliches, wenn Sie / tmp nicht verwenden möchten.

Wenn Sie diesen Ansatz wählen müssen und Ihre gewünschten Pfade unveränderlich sind, erstellen Sie die Bibliothek neu und ändern Sie den Standardpfad für / etc/hosts in der Quelle. Oder besser, beim Bau Ihrer modifizierten libnss_files.so benennen Sie es in etwas um wie libnss_altfiles.so und Veränderung nsswitch.conf verwenden hosts: altfiles beim Starten Ihres Docker-Containers (es sei denn, docker hat bind mounted nsswitch .conf auch, dann kannst du es nicht ändern). Dadurch haben Sie die libnss_altfiles.so parallel zu Ihren normalen Bibliotheken im Basissystem. Wenn Docker bindet, mounten Sie nsswitch.conf, hinterlasse eine Kopie deines Passworts libnss_files.so in Ihrem Verzeichnis /lib-override , das von LD_LIBRARY_PATH geladen werden kann.

Als Hinweis ignorieren suid / sgid-Binärdateien LD_LIBRARY_PATH und LD_PRELOAD , sodass einige Dinge kaputt gehen (sprich: Verwenden Sie wieder die Standard- / etc / hosts), wenn Sie diese Variablen verwenden.

Manchmal können Sie nützliche Fehlermeldungen finden, indem Sie in den Knoten gehen, auf dem der Docker-Dämon ausgeführt wird, und dann Folgendes tun:

$ tail -f /var/log/containers/* /var/log/docker.log 2>&1

In der 'Docker Community Edition' unter Mac OS können Sie eine Verbindung zur Docker-VM herstellen, indem Sie Folgendes tun:

$  screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty

Bitte bemühen Sie sich, eine der Antworten als “akzeptiert” zu markieren, danke!