Frage Wie kann ich eine Docker-Container-Initialisierung debuggen?


Ich hatte ein Problem mit einem Container, obwohl es perfekt baut, startet es nicht richtig. Die Ursache ist eine Problemumgehung, die ich der Dockerdatei hinzugefügt habe (um ein selbst konfiguriertes / etc / hosts-Routing zu haben)

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

Offensichtlich gibt es da einen Fehler, aber ich frage mich, wie ich mehr Informationen darüber bekommen kann, was Docker macht, während er läuft. Zum Beispiel funktioniert das:

$ docker run image ls
usr bin ...

Aber das ist nicht:

$ docker run image ls -l
$

Es gibt nichts in den Logs und ich kann auch keine interaktive Shell nennen. Ich kann Strace benutzen, um zu sehen, was passiert, aber ich hatte gehofft, es gibt einen besseren Weg.

Gibt es eine Möglichkeit, docker zu setzen, um ausführlicher zu sein?

BEARBEITEN: Dank Andrew D. Ich weiß jetzt, was mit dem Code oben falsch ist (ich habe es so gelassen, dass seine Antwort verstanden werden kann). Jetzt ist das Problem immer noch, wie könnte ich etwas wie das debuggen oder ein paar Gründe warum ls -l gescheitert warum ls nicht.

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


61
2018-05-19 15:28


Ursprung


Bitte bemühen Sie sich, eine der Antworten als "akzeptiert" zu markieren, danke! - Brian Topping


Antworten:


Docker events Befehl kann helfen und Docker Protokolle 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&

Dann führe deinen Fehler aus docker run ... Befehl. Dann sollten Sie 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 run 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: 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-ID aus den Protokollen zu entfernen /var/log/ecs/ecs-agent.log.<DATE>. Dann benutze Docker logs <hex id>.


61
2017-12-22 13:24



Sehr hilfreich! Neu bei docker und wollte Portainer laufen lassen. Gelöst es mit diesen Debugging-Schritten. Jemand auf Medium.com mit demselben Problem gefunden: medium.com/@jameson_37151/ ... - Jameson
Ich bekomme "Container nicht gefunden" !? - demented hedgehog
Seltsam. Nur um sicherzustellen, @demededhedgehog hast du versucht, die hex-id aus der Log-Nachricht zu kopieren, die auf "(from xxx/xxx:latest) die"? - Peter Lamberg
Vielen Dank diese Antwort, es ist ein Lebensretter. Nur etwas hinzuzufügen ist das docker events& kann problematisch sein, wenn Ihr Container ständig von einem AWS ECS-Dienst neu gestartet wird. In diesem Fall ist es möglicherweise einfacher, die Container-ID aus den Protokollen zu entfernen /var/log/ecs/ecs-agent.log.<DATE>. Dann benutze docker logs <hex id> wie in dieser Antwort vorgeschlagen, um zu sehen, warum die Dinge nicht booten. - alexkb
@alexkb Danke! Ich habe Ihren Vorschlag am Ende der Antwort hinzugefügt, damit andere ihn leichter finden. - Peter Lamberg


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

#stop the current demon and start it in debug modus
sudo service docker stop
dockerd -D # --debug

Sie starten den Client einfach von einer neuen Shell. Das Missverständnis war, zu denken, dass der Client tatsächlich überhaupt etwas tut ... nun, es kommuniziert nur mit dem Daemon, also willst du nicht debuggen der Client aber der Daemon selbst (normalerweise).


15
2018-05-26 09:07





In meinem Fall, der -a (an STDOUT / STDERR anhängen) Flagge war genug:

user@machine:~$ docker start -a server_name
Error: 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 ein fehlender Protokollpfad, der von supervisord). Ich nehme an, dass die meisten Container-Startfehler auch hier auftauchen würden.


7
2018-03-29 13:27





Ich kann Ihre Frage nicht beantworten, wie man Docker-Ausgabe vollständiger machen kann, aber ich kann Ihnen sagen, dass In-Place-Regex einen String in einer .so-Datei ersetzen ist ein bisschen verrückt: der Zeichenfolge hat nur so viel Platz zugewiesen, und Wenn Sie die Dateioffsets anderer Einträge ändern, wird die Elf-Datei beschädigt. Versuchen Sie, objdump oder readelf in Ihrer .so-Datei auszuführen, nachdem Sie den Perl-Befehl ausgeführt haben (vor LD_LIBRARY_PATH ändern) Außerhalb eines Containers - Dollars zu Donuts ist es jetzt korrupt.

Der Grund, warum es funktioniert in diesem leider notwendigen Hack ist, weil "tmp" und "etc" dieselbe Stringlänge haben, so dass sich keine Offsets ändern. Betrachten Sie das Verzeichnis / dkr oder ähnliches, wenn Sie / tmp nicht verwenden möchten.

Wenn Sie diese Methode verwenden müssen und die gewünschten Pfade nicht änderbar sind, erstellen Sie die Bibliothek neu und ändern Sie den Standardpfad für / etc / hosts in der Quelle. Oder besser, wenn Sie Ihre modifizierte bauen libnss_files.so Benenne es in etwas um libnss_altfiles.so und ändern nsswitch.conf benutzen hosts: altfiles Wenn Sie den Andock-Container starten (es sei denn, Docker hat ebenfalls die Bind-Datei nsswitch.conf installiert, können Sie sie nicht ändern). Dadurch haben Sie die Bibliothek libnss_altfiles.so parallel zu Ihren normalen Bibliotheken im Basissystem. Wenn docker binder-mount nsswitch.conf bereitstellt, lassen Sie eine Kopie Ihrer neu erstellten libnss_files.so in Ihrem Verzeichnis / lib-override bereit, um von LD_LIBRARY_PATH geladen zu werden.

Als eine Kopfzeile ignorieren suid / sgid-Binärdateien LD_LIBRARY_PATH und LD_PRELOAD, so dass einige Dinge kaputt gehen (lesen Sie: Gehen Sie zurück zur Verwendung des Standards / etc / hosts), wenn Sie diese Variablen verwenden.


2
2018-05-19 21:01



Vielen Dank für die tolle Erkenntnis ... Ich war zu schnell und sehe jetzt, was passiert. Ich weiß immer noch nicht, warum die Statistik einen Host (ls -l) auflösen muss, während die einfache Dateiliste (ls) nicht ... - estani