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
Offensichtlich ist da ein Fehler, aber ich frage mich, wie ich mehr Informationen darüber bekommen kann, was Docker während des Betriebs macht. Das funktioniert zum Beispiel:
$ docker run image ls
usr bin ...
Das tut es aber nicht:
$ docker run image ls -l
$
Die Protokolle enthalten nichts und ich kann auch keine interaktive Shell aufrufen. Ich kann strace benutzen, um zu sehen, was passiert, aber ich hatte gehofft, dass es einen besseren Weg gibt.
Kann ich den Docker so einstellen, dass er ausführlicher ist?
EDIT : Dank Andrew D. weiß ich jetzt, was mit dem obigen Code falsch ist (ich habe ihn verlassen, damit seine Antwort verstanden werden kann). Jetzt ist die Frage noch, wie ich so etwas debuggen oder ein paar Einblicke in die Gründe bekommen kann, warum ls -l versagt hat, warum ls nicht.
EDIT : Die -D = true könnte mehr Ausgabe geben, aber nicht in meinem Fall ...
Antworten:
Der Docker-
events
Befehl kann hilfreich sein, und der Docker-Protokollbefehl kann Protokolle auch dann abrufen, wenn das Image nicht gestartet werden konnte.Beginnen Sie zuerst
docker events
im Hintergrund, um zu sehen, was los ist.Führen Sie dann Ihren fehlgeschlagenen
docker run ...
Befehl aus. Dann sollte auf dem Bildschirm etwa Folgendes angezeigt werden:Anschließend können Sie die Start-Hex-ID aus der vorherigen Nachricht oder der Ausgabe des Ausführungsbefehls abrufen. Dann können Sie es mit dem Befehl logs verwenden:
Sie sollten nun eine Ausgabe des fehlgeschlagenen Abbildstarts sehen.
Wie @alexkb in einem Kommentar vorgeschlagen hat:
docker events&
Kann problematisch sein, wenn Ihr Container ständig von so etwas wie dem AWS ECS-Service aus neu gestartet wird. In diesem Szenario ist es möglicherweise einfacher, die Container-Hex-ID aus den Anmeldungen abzurufen/var/log/ecs/ecs-agent.log.<DATE>
. Dann benutze Dockerlogs <hex id>
.quelle
(from xxx/xxx:latest) die
" endet .docker events&
dies problematisch sein kann, wenn Ihr Container ständig von so etwas wie dem AWS ECS-Service neu gestartet wird. In diesem Szenario ist es möglicherweise einfacher, die Container-Hex-ID aus den Anmeldungen zu entfernen/var/log/ecs/ecs-agent.log.<DATE>
. Verwenden Sie dann,docker logs <hex id>
wie in dieser Antwort vorgeschlagen, um festzustellen, warum die Dinge nicht gestartet werden.Das Beste, was ich bisher herausgefunden habe, ist:
Starten Sie den Client einfach von einer neuen Shell aus. Die falsche Vorstellung war, dass der Client überhaupt irgendetwas tut ... nun, er kommuniziert nur mit dem Dämon, also möchten Sie nicht den Client debuggen, sondern den Dämon selbst (normalerweise).
quelle
In meinem Fall war das
-a
Flag (an STDOUT / STDERR anhängen) ausreichend:Es wurde der Startfehler angezeigt (in unserem Fall ein fehlender Protokollpfad von
supervisord
). Ich gehe davon aus, dass die meisten Container-Startfehler auch hier auftreten würden.quelle
Ich kann Ihre Frage zur Vervollständigung der Docker-Ausgabe nicht beantworten, aber ich kann Ihnen sagen, dass das direkte Ersetzen 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 für Ihre .so-Datei auszuführen, nachdem Sie den Perl-Befehl ( vor der Änderung von LD_LIBRARY_PATH ) außerhalb eines Containers ausgeführt haben. Dollar zu Donuts sind jetzt beschädigt.
Der Grund, warum es in diesem leider notwendigen Hack funktioniert, ist, dass "tmp" und "etc" dieselbe String-Lä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 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 den Aufbau Ihrer modifizierten
libnss_files.so
es um etwas umbenennen wielibnss_altfiles.so
und ändernnsswitch.conf
zu verwenden ,hosts: altfiles
wenn Ihr Docker Container beginnen (es sei denn , Docker binden als auch montiert nsswitch.conf, dann können Sie es nicht ändern). Auf diese Weise können Sie die Datei libnss_altfiles.so parallel zu Ihren normalen Bibliotheken im Basissystem verwenden. Wenn Docker die Datei nsswitch.conf bindet, belassen Sie eine Kopie der neu erstellten Datei libnss_files.so in Ihrem Verzeichnis / lib-override, damit sie von LD_LIBRARY_PATH geladen werden kann.Als Heads-up ignorieren suid / sgid-Binärdateien LD_LIBRARY_PATH und LD_PRELOAD, so dass einige Dinge kaputt gehen (lesen Sie: Verwenden Sie wieder die Standarddatei / etc / hosts), wenn Sie diese Variablen verwenden.
quelle
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 ausführen:
Unter 'Docker Community Edition' unter Mac OS können Sie eine Verbindung zum Docker VM herstellen, indem Sie folgende Schritte ausführen:
quelle