it-swarm.com.de

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 selbstkonfiguriertes/etc/hosts-Routing).

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

Natürlich gibt es dort einen Fehler, aber ich frage mich, wie ich mehr Informationen darüber erhalten kann, was Docker während des Laufens tut. Das funktioniert zum Beispiel:

$ docker run image ls
usr bin ...

Das geht aber 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.

Kann ich Docker auf irgendeine Weise ausführlicher einstellen?

EDIT : Dank Andrew D. Ich weiß jetzt, was mit dem obigen Code falsch ist (ich habe ihn verlassen, damit seine Antwort verstanden werden kann). Jetzt ist die Frage immer noch, wie ich so etwas debuggen oder ein paar Informationen darüber erhalten kann, warum ls -l fehlgeschlagen ist, warum ls nicht.

EDIT : Das -D = true könnte mehr Ausgabe liefern, wenn auch nicht in meinem Fall ...

104
estani

Der Befehl Docker events kann hilfreich sein und der Befehl Docker-Protokolle kann Protokolle abrufen, auch wenn das Image nicht gestartet werden konnte.

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

docker events&

Führen Sie dann Ihr fehlerhaftes docker run ... Befehl. Dann sollte auf dem Bildschirm Folgendes angezeigt werden:

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

Anschließend 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 einige Ausgaben vom fehlgeschlagenen Image-Start sehen.

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

110
Peter Lamberg

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

Starten Sie den Client einfach von einer neuen Shell aus. Das Missverständnis war zu glauben, dass der Client überhaupt etwas tut ... nun, es kommuniziert nur mit dem Daemon, also möchten Sie nicht debuggen den Client, sondern den Daemon selbst (normalerweise).

18
estani

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

[email protected]:~$ 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 wurde der Startfehler angezeigt (in unserem Fall ein fehlender Protokollpfad, der von supervisord verwendet wird). Ich gehe davon aus, dass die meisten Container-Startfehler auch hier auftreten würden.

15
claytond

Ich kann Ihre Frage zur Vervollständigung der Docker-Ausgabe nicht beantworten, aber ich kann Ihnen sagen, dass die direkte Regex-Ersetzung einer Zeichenfolge in einer .so-Datei etwas 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 Perl-Befehl ( vor der LD_LIBRARY_PATH-Änderung ) außerhalb eines Containers ausgeführt haben korrupt.

Der Grund, warum es funktioniert in diesem leider notwendigen Hack ist, dass "tmp" und "etc" die gleiche Stringlä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, wenn Sie Ihr modifiziertes libnss_files.so benenne es in etwas um wie libnss_altfiles.so und ändern nsswitch.conf benutzen hosts: altfiles beim Starten Ihres Docker-Containers (es sei denn, Docker hat die gemountete Datei nsswitch.conf gebunden, können Sie sie nicht ändern). Auf diese Weise können Sie die Datei libnss_altfiles.so parallel zu Ihren normalen Bibliotheken im Basissystem haben. Wenn Docker die Datei nsswitch.conf bind-mount ausführt, lassen Sie eine Kopie Ihrer neu erstellten libnss_files.so in Ihrem Verzeichnis/lib-override, die von LD_LIBRARY_PATH geladen werden kann.

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

3
Andrew Domaszek

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

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

Unter 'Docker Community Edition' unter Mac OS können Sie eine Verbindung zum Docker VM herstellen, indem Sie folgende Schritte ausführen:

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