Fehlerbehebung bei sofortiger Beendigung von Docker-Containern

DockerBeginner
Jetzt üben

Einführung

In diesem praktischen Lab werden Sie lernen, wie Sie ein häufiges Docker-Problem identifizieren und beheben können: Container, die unmittelbar nach dem Start beendet werden. Dieses Problem verwirrt oft Anfänger und kann aus verschiedenen Gründen auftreten, von Konfigurationsfehlern bis hin zu Anwendungsproblemen.

Durch die Durchführung dieses Labs werden Sie den Docker-Container-Lebenszyklus verstehen, lernen, sofortige Container-Beendigungen zu diagnostizieren, Debugging-Techniken beherrschen und Best Practices implementieren, um sicherzustellen, dass Ihre Container zuverlässig laufen. Diese Fähigkeiten sind für jeden unerlässlich, der mit Docker in Entwicklungs- oder Produktionsumgebungen arbeitet.

Grundlagen von Docker-Containern verstehen

Beginnen wir mit der Erforschung der Docker-Container-Grundlagen und machen uns mit den grundlegenden Befehlen zur Verwaltung von Containern vertraut.

Was ist ein Docker-Container?

Ein Docker-Container ist ein leichtgewichtiges, eigenständiges und ausführbares Softwarepaket, das alles enthält, was zum Ausführen einer Anwendung benötigt wird:

  • Code
  • Laufzeitumgebung (Runtime)
  • Systemwerkzeuge
  • Bibliotheken
  • Einstellungen

Container werden isoliert vom Host-System und von anderen Containern ausgeführt und bieten so Konsistenz in verschiedenen Umgebungen.

Docker auf Ihrem System erkunden

Zuerst wollen wir überprüfen, ob Docker korrekt installiert ist und auf Ihrem System läuft:

docker --version

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Docker version 20.10.21, build baeda1f

Als Nächstes wollen wir prüfen, ob derzeit Container laufen:

docker ps

Dieser Befehl listet laufende Container auf. Da wir noch keine gestartet haben, sollten Sie nur die Spaltenüberschriften sehen:

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Um alle Container anzuzeigen, einschließlich der gestoppten:

docker ps -a

Den Container-Lebenszyklus verstehen

Der Docker-Container-Lebenszyklus besteht aus mehreren Zuständen:

  1. Created (Erstellt): Ein Container wird erstellt, aber noch nicht gestartet
  2. Running (Läuft): Der Container führt seine definierten Prozesse aus
  3. Paused (Pausiert): Containerprozesse werden vorübergehend angehalten
  4. Stopped (Gestoppt): Der Container wurde beendet oder gestoppt
  5. Deleted (Gelöscht): Der Container wurde aus dem System entfernt

Lassen Sie uns einen einfachen Container ausführen und seinen Lebenszyklus beobachten:

docker run hello-world

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
...

Beachten Sie, dass dieser Container sofort nach der Anzeige der Nachricht ausgeführt und beendet wurde. Dies ist tatsächlich das normale Verhalten für den hello-world-Container, da er so konzipiert ist, dass er einfach eine Nachricht anzeigt und beendet wird.

Überprüfen Sie den Container in der Liste aller Container:

docker ps -a

Sie sollten Ihren hello-world-Container in der Liste mit dem Status "Exited" (Beendet) sehen:

CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
a1b2c3d4e5f6   hello-world   "/hello"   30 seconds ago   Exited (0) 30 seconds ago             peaceful_hopper

Der Exit-Code (0) gibt an, dass der Container erfolgreich und ohne Fehler beendet wurde.

Wichtige Docker-Befehle für die Containerverwaltung

Hier sind einige wichtige Docker-Befehle, die Sie in diesem Lab verwenden werden:

  • docker run [OPTIONS] IMAGE [COMMAND]: Erstellen und Starten eines Containers
  • docker ps: Liste der laufenden Container
  • docker ps -a: Liste aller Container (einschließlich der gestoppten)
  • docker logs [CONTAINER_ID]: Container-Logs anzeigen
  • docker inspect [CONTAINER_ID]: Detaillierte Containerinformationen abrufen
  • docker exec -it [CONTAINER_ID] [COMMAND]: Einen Befehl in einem laufenden Container ausführen
  • docker stop [CONTAINER_ID]: Einen laufenden Container stoppen
  • docker rm [CONTAINER_ID]: Einen Container entfernen

Nachdem Sie die Grundlagen von Docker-Containern und ihrem Lebenszyklus verstanden haben, werden wir uns mit der Fehlerbehebung bei Containern befassen, die unerwartet beendet werden.

Identifizierung von Container-Beendigungsproblemen

In diesem Schritt erstellen wir einen Docker-Container, der sich sofort beendet, und lernen, wie man das Problem diagnostiziert.

Ausführen eines Containers, der sich sofort beendet

Versuchen wir zunächst, einen Ubuntu-Container auszuführen:

docker run ubuntu

Sie werden etwas Interessantes bemerken – der Befehl wird sofort ausgeführt und kehrt zu Ihrer Eingabeaufforderung zurück. Wo ist unser Ubuntu-Container? Überprüfen wir das:

docker ps

Es werden keine Container ausgeführt. Überprüfen Sie nun alle Container, einschließlich der gestoppten:

docker ps -a

Sie sehen eine Ausgabe ähnlich der folgenden:

CONTAINER ID   IMAGE         COMMAND       CREATED          STATUS                      PORTS     NAMES
f7d9e7f6543d   ubuntu        "/bin/bash"   10 seconds ago   Exited (0) 10 seconds ago             focused_galileo
a1b2c3d4e5f6   hello-world   "/hello"      10 minutes ago   Exited (0) 10 minutes ago             peaceful_hopper

Der Ubuntu-Container startete und beendete sich dann sofort mit einem Statuscode von 0, was darauf hindeutet, dass er ohne Fehler beendet wurde. Dies ist das erwartete Verhalten, kann aber für Anfänger verwirrend sein.

Verstehen, warum Container beendet werden

Container sind so konzipiert, dass sie einen bestimmten Befehl oder Prozess ausführen. Wenn dieser Prozess abgeschlossen ist oder beendet wird, stoppt der Container. Dies ist ein grundlegendes Prinzip des Docker-Designs.

Der Ubuntu-Container wurde sofort beendet, weil:

  1. Der Standardbefehl für das Ubuntu-Image ist /bin/bash
  2. Wenn ohne die Flags -it (interaktiv, Terminal) ausgeführt, gibt es keine Eingabe für die Bash-Shell
  3. Ohne Eingabe und ohne einen auszuführenden Befehl beendet sich Bash sofort
  4. Wenn der Hauptprozess (Bash) beendet wird, stoppt der Container

Anzeigen von Container-Logs und -Informationen

Untersuchen wir die Logs unseres beendeten Ubuntu-Containers, um zu verstehen, was passiert ist. Suchen Sie zuerst die Container-ID aus Ihrer docker ps -a-Ausgabe, dann:

docker logs CONTAINER_ID

Ersetzen Sie CONTAINER_ID durch Ihre tatsächliche Container-ID. Sie werden wahrscheinlich keine Ausgabe sehen, da der Container vor dem Beenden keine Logs erzeugt hat.

Für detailliertere Informationen über den Container:

docker inspect CONTAINER_ID

Dadurch wird ein großes JSON-Objekt mit Containerkonfigurations- und Statusinformationen angezeigt.

Konzentrieren wir uns auf den Exit-Code:

docker inspect CONTAINER_ID --format='{{.State.ExitCode}}'

Sie sollten Folgendes sehen:

0

Dies bestätigt, dass der Container normal beendet wurde, nicht aufgrund eines Fehlers.

Einen Container am Laufen halten

Um den Ubuntu-Container am Laufen zu halten, müssen wir entweder:

  1. Eine interaktive Sitzung bereitstellen oder
  2. Den Standardbefehl durch einen langlaufenden Prozess überschreiben

Versuchen wir den interaktiven Ansatz:

docker run -it ubuntu

Jetzt befinden Sie sich im Container mit einer Bash-Eingabeaufforderung:

root@3a4b5c6d7e8f:/#

Der Container bleibt so lange in Betrieb, wie diese Bash-Sitzung aktiv ist. Geben Sie exit ein oder drücken Sie Strg+D, um den Container zu verlassen.

exit

Alternativ können wir einen Container am Laufen halten, indem wir einen Befehl bereitstellen, der nicht sofort abgeschlossen wird:

docker run -d ubuntu sleep 300

Dies führt den Ubuntu-Container aus und führt den Befehl sleep 300 aus, wodurch der Container für 300 Sekunden (5 Minuten) am Laufen gehalten wird.

Überprüfen Sie, ob der Container läuft:

docker ps

Sie sollten Ihren Container im laufenden Zustand sehen:

CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
9a8b7c6d5e4f   ubuntu    "sleep 300"   10 seconds ago   Up 10 seconds             hopeful_hopper

Denken Sie bei der Diagnose von Containern, die sich sofort beenden, an diese wichtigen Punkte:

  1. Container beenden sich, wenn ihr Hauptprozess abgeschlossen ist
  2. Überprüfen Sie Logs und Exit-Codes, um zu verstehen, warum sie gestoppt wurden
  3. Wenn ein Container weiterlaufen soll, stellen Sie sicher, dass sein Hauptprozess nicht beendet wird

Fehlerbehebung bei häufigen Container-Beendigungsproblemen

Nachdem wir nun verstanden haben, warum Container sich sofort beenden, wollen wir uns mit den häufigsten Ursachen für unerwartete Container-Beendigungen und deren Fehlerbehebung befassen.

Erstellen eines Containers mit einem Problem

Erstellen wir eine einfache Situation, in der sich ein Container unerwartet beendet. Erstellen Sie zuerst ein Verzeichnis für unsere Testdateien:

mkdir -p ~/project/docker-exit-test
cd ~/project/docker-exit-test

Erstellen Sie nun ein einfaches Python-Skript mit einem Fehler:

nano app.py

Fügen Sie den folgenden Code hinzu:

import os

## Attempt to read a required environment variable
database_url = os.environ['DATABASE_URL']

print(f"Connecting to database: {database_url}")
print("Application running...")

## Rest of the application code would go here

Speichern und beenden Sie die Datei (drücken Sie Strg+O, Eingabetaste und dann Strg+X).

Erstellen Sie nun ein Dockerfile, um ein Image mit dieser Anwendung zu erstellen:

nano Dockerfile

Fügen Sie den folgenden Inhalt hinzu:

FROM python:3.9-slim

WORKDIR /app

COPY app.py .

CMD ["python", "app.py"]

Speichern und beenden Sie die Datei.

Erstellen Sie das Docker-Image:

docker build -t exit-test-app .

Sie sollten eine Ausgabe sehen, die anzeigt, dass das Image erfolgreich erstellt wurde:

Successfully built a1b2c3d4e5f6
Successfully tagged exit-test-app:latest

Führen Sie nun den Container aus:

docker run exit-test-app

Sie sollten sehen, wie sich der Container sofort mit einem Fehler beendet:

Traceback (most recent call last):
  File "/app/app.py", line 4, in <module>
    database_url = os.environ['DATABASE_URL']
  File "/usr/local/lib/python3.9/os.py", line 679, in __getitem__
    raise KeyError(key) from None
KeyError: 'DATABASE_URL'

Der Container wurde beendet, weil unser Python-Skript eine Umgebungsvariable erwartete, die nicht bereitgestellt wurde.

Diagnostizieren des Problems

Wenn sich ein Container unerwartet beendet, gehen Sie wie folgt vor:

  1. Überprüfen Sie den Exit-Code, um festzustellen, ob es sich um einen Fehler handelt:
docker ps -a

Suchen Sie nach Ihrem Container und notieren Sie sich den Exit-Code. Er sollte ungleich Null sein, was auf einen Fehler hindeutet:

CONTAINER ID   IMAGE           COMMAND            CREATED          STATUS                     PORTS     NAMES
b1c2d3e4f5g6   exit-test-app   "python app.py"   20 seconds ago   Exited (1) 19 seconds ago           vigilant_galileo
  1. Untersuchen Sie die Container-Logs:
docker logs $(docker ps -a -q --filter ancestor=exit-test-app --latest)

Dies ruft die Logs vom neuesten Container ab, der von unserem Image erstellt wurde.

Die Fehlermeldung zeigt das Problem deutlich: Das Python-Skript versucht, auf eine Umgebungsvariable namens DATABASE_URL zuzugreifen, die nicht existiert.

Beheben des Problems

Beheben wir nun das Problem, indem wir die fehlende Umgebungsvariable bereitstellen:

docker run -e DATABASE_URL=postgresql://user:password@db:5432/mydatabase exit-test-app

Sie sollten jetzt sehen, dass der Container erfolgreich ausgeführt wird:

Connecting to database: postgresql://user:password@db:5432/mydatabase
Application running...

Der Container beendet sich immer noch, aber diesmal liegt es daran, dass unser Skript das Ende erreicht und normal beendet wird. Wenn wir wollten, dass der Container weiterläuft, müssten wir unser Skript so ändern, dass es eine Endlosschleife oder einen langlaufenden Prozess enthält.

Häufige Ursachen für Container-Beendigungen

Hier sind einige häufige Gründe, warum sich Container unerwartet beenden könnten:

  1. Fehlende Umgebungsvariablen: Wie wir gerade gezeigt haben
  2. Fehlende Abhängigkeiten: Fehlende Bibliotheken oder Systempakete
  3. Verbindungsfehler: Kann keine Datenbank oder einen anderen Dienst erreichen
  4. Berechtigungsprobleme: Unzureichende Berechtigungen für den Zugriff auf Dateien oder Ressourcen
  5. Ressourcenbeschränkungen: Container geht der Speicher oder die CPU aus
  6. Anwendungsabstürze: Fehler im Anwendungscode

Techniken zur Fehlerbehebung

Für jedes dieser Probleme gibt es effektive Ansätze zur Fehlerbehebung:

  1. Logs überprüfen: Überprüfen Sie immer zuerst die Container-Logs mit docker logs
  2. Entrypoint überschreiben: Verwenden Sie docker run --entrypoint /bin/sh -it my-image, um den Container zu betreten und zu untersuchen
  3. Debugging-Anweisungen hinzufügen: Ändern Sie Ihre Anwendung, um mehr Logging hinzuzufügen
  4. Ressourcenauslastung überprüfen: Verwenden Sie docker stats, um die Ressourcenauslastung des Containers zu überwachen
  5. Umgebung untersuchen: Führen Sie docker exec -it CONTAINER_ID env aus, um Umgebungsvariablen zu überprüfen

Versuchen wir die Technik der Entrypoint-Überschreibung mit unserem Image:

docker run --entrypoint /bin/sh -it exit-test-app

Jetzt befinden Sie sich mit einer Shell im Container. Sie können die Umgebung erkunden:

ls -la
cat app.py
echo $DATABASE_URL

Sie werden sehen, dass DATABASE_URL nicht gesetzt ist. Beenden Sie den Container, wenn Sie fertig sind:

exit

Indem Sie verstehen, warum sich Container beenden, und diese Techniken zur Fehlerbehebung anwenden, können Sie die meisten Container-Beendigungsprobleme schnell diagnostizieren und beheben.

Implementierung von Best Practices für die Container-Zuverlässigkeit

Nachdem wir nun wissen, wie man Container-Beendigungen behebt, wollen wir Best Practices implementieren, um unsere Container zuverlässiger und robuster zu machen. Wir werden unsere Beispielanwendung mit ordnungsgemäßer Fehlerbehandlung, Integritätsprüfungen und Protokollierung erweitern.

1. Verbesserung der Fehlerbehandlung

Ändern wir unsere Python-Anwendung, um fehlende Umgebungsvariablen ordnungsgemäß zu behandeln:

cd ~/project/docker-exit-test
nano app.py

Aktualisieren Sie den Inhalt auf:

import os
import time
import sys

## Get environment variables with defaults
database_url = os.environ.get('DATABASE_URL', 'sqlite:///default.db')

print(f"Connecting to database: {database_url}")

## Simulate a long-running process
try:
    print("Application running... Press Ctrl+C to exit")
    counter = 0
    while True:
        counter += 1
        print(f"Application heartbeat: {counter}")
        time.sleep(10)
except KeyboardInterrupt:
    print("Application shutting down gracefully...")
    sys.exit(0)

Speichern und beenden Sie die Datei.

Diese verbesserte Version:

  • Verwendet os.environ.get() mit einem Standardwert, anstatt eine Ausnahme auszulösen
  • Implementiert eine langlaufende Schleife, um den Container am Leben zu erhalten
  • Behandelt das ordnungsgemäße Herunterfahren bei Beendigung

Bauen wir das Image neu:

docker build -t exit-test-app:v2 .

Und führen Sie den verbesserten Container aus:

docker run -d --name improved-app exit-test-app:v2

Überprüfen Sie, ob der Container läuft:

docker ps

Sie sollten sehen, dass Ihr Container läuft:

CONTAINER ID   IMAGE              COMMAND            CREATED          STATUS          PORTS     NAMES
c1d2e3f4g5h6   exit-test-app:v2   "python app.py"   10 seconds ago   Up 10 seconds             improved-app

Zeigen Sie die Logs an, um zu bestätigen, dass es funktioniert:

docker logs improved-app

Sie sollten eine Ausgabe wie diese sehen:

Connecting to database: sqlite:///default.db
Application running... Press Ctrl+C to exit
Application heartbeat: 1
Application heartbeat: 2

2. Implementierung einer Integritätsprüfung im Dockerfile

Integritätsprüfungen ermöglichen es Docker, die Integrität Ihres Containers zu überwachen. Aktualisieren wir unser Dockerfile, um eine Integritätsprüfung einzuschließen:

nano Dockerfile

Aktualisieren Sie es auf:

FROM python:3.9-slim

WORKDIR /app

## Install curl for health checks
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

COPY app.py .

## Add a health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

## Expose port for the health check endpoint
EXPOSE 8080

CMD ["python", "app.py"]

Nun müssen wir unserer Anwendung einen Integritätsprüfungs-Endpunkt hinzufügen:

nano app.py

Ersetzen Sie den Inhalt durch:

import os
import time
import sys
import threading
from http.server import HTTPServer, BaseHTTPRequestHandler

## Get environment variables with defaults
database_url = os.environ.get('DATABASE_URL', 'sqlite:///default.db')

## Simple HTTP server for health checks
class HealthRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/health':
            self.send_response(200)
            self.send_header('Content-type', 'text/plain')
            self.end_headers()
            self.wfile.write(b'OK')
        else:
            self.send_response(404)
            self.end_headers()

def run_health_server():
    server = HTTPServer(('0.0.0.0', 8080), HealthRequestHandler)
    print("Starting health check server on port 8080")
    server.serve_forever()

## Start health check server in a separate thread
health_thread = threading.Thread(target=run_health_server, daemon=True)
health_thread.start()

print(f"Connecting to database: {database_url}")

## Main application loop
try:
    print("Application running... Press Ctrl+C to exit")
    counter = 0
    while True:
        counter += 1
        print(f"Application heartbeat: {counter}")
        time.sleep(10)
except KeyboardInterrupt:
    print("Application shutting down gracefully...")
    sys.exit(0)

Speichern und beenden Sie die Datei.

Bauen Sie das Image mit unserer Integritätsprüfung neu:

docker build -t exit-test-app:v3 .

Führen Sie den Container mit der neuen Version aus:

docker run -d --name healthcheck-app -p 8080:8080 exit-test-app:v3

Überprüfen Sie nach etwa 30 Sekunden den Integritätsstatus:

docker inspect --format='{{.State.Health.Status}}' healthcheck-app

Sie sollten Folgendes sehen:

healthy

Sie können den Integritätsendpunkt auch direkt testen:

curl http://localhost:8080/health

Dies sollte OK zurückgeben.

3. Verwenden von Docker-Neustartrichtlinien

Docker bietet Neustartrichtlinien, um Container automatisch neu zu starten, wenn sie sich beenden oder Fehler auftreten:

docker run -d --restart=on-failure:5 --name restart-app exit-test-app:v3

Diese Richtlinie startet den Container bis zu 5 Mal neu, wenn er mit einem Wert ungleich Null beendet wird.

Verfügbare Neustartrichtlinien:

  • no: Nie neu starten (Standard)
  • always: Immer neu starten, unabhängig vom Exit-Status
  • unless-stopped: Immer neu starten, es sei denn, es wird manuell gestoppt
  • on-failure[:max-retries]: Nur bei Beendigung mit einem Wert ungleich Null neu starten

4. Festlegen von Ressourcenbeschränkungen

Um Containerabstürze aufgrund von Ressourcenerschöpfung zu verhindern, legen Sie geeignete Ressourcenbeschränkungen fest:

docker run -d --name resource-limited-app \
  --memory=256m \
  --cpus=0.5 \
  exit-test-app:v3

Dies beschränkt den Container auf 256 MB Speicher und die Hälfte eines CPU-Kerns.

5. Richtige Protokollierungskonfiguration

Konfigurieren Sie Ihre Anwendung für eine bessere Fehlerbehebung so, dass strukturierte Logs ausgegeben werden:

docker run -d --name logging-app \
  --log-driver=json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  exit-test-app:v3

Dies konfiguriert den Container so, dass der JSON-Log-Treiber mit Log-Rotation verwendet wird (maximal 3 Dateien mit je 10 MB).

Zusammenfassung der Best Practices

Durch die Implementierung dieser Best Practices haben Sie die Zuverlässigkeit Ihrer Docker-Container erheblich verbessert:

  1. Ordnungsgemäße Fehlerbehandlung mit Standardwerten
  2. Container-Integritätsprüfungen zur Überwachung
  3. Geeignete Neustartrichtlinien für die automatische Wiederherstellung
  4. Ressourcenbeschränkungen zur Verhinderung von Ressourcenerschöpfung
  5. Richtige Protokollierungskonfiguration für einfachere Fehlerbehebung

Diese Techniken helfen Ihnen dabei, widerstandsfähige Container zu erstellen, die sich von Fehlern erholen können und eine bessere Beobachtbarkeit bieten, wenn Probleme auftreten.

Zusammenfassung

In diesem Lab haben Sie wichtige Fähigkeiten zur Fehlerbehebung und Lösung von Problemen mit dem Beenden von Docker-Containern erlernt:

  • Verstehen des Docker-Container-Lebenszyklus und warum Container sich beenden, wenn ihr Hauptprozess abgeschlossen ist
  • Identifizieren häufiger Ursachen für sofortige Container-Beendigungen durch Logs und Exit-Codes
  • Implementierung einer robusten Fehlerbehandlung in containerisierten Anwendungen
  • Hinzufügen von Container-Integritätsprüfungen zur Überwachung des Anwendungsstatus
  • Konfigurieren von Neustartrichtlinien für die automatische Wiederherstellung nach Fehlern
  • Festlegen geeigneter Ressourcenbeschränkungen, um Containerabstürze zu verhindern
  • Implementierung geeigneter Protokollierungsstrategien für eine einfachere Fehlerbehebung

Diese Fähigkeiten bilden die Grundlage für zuverlässige Docker-Container-Deployments. Wenn Sie weiterhin mit Docker in realen Szenarien arbeiten, werden Sie feststellen, dass diese Fehlerbehebungstechniken von unschätzbarem Wert für die Aufrechterhaltung stabiler und widerstandsfähiger containerisierter Anwendungen sind.

Denken Sie daran, dass die häufigsten Ursachen für sofortige Container-Beendigungen sind:

  1. Der Hauptprozess schließt seine Aufgabe ab (by design)
  2. Fehlende Umgebungsvariablen oder -konfiguration
  3. Anwendungsfehler oder Ausnahmen
  4. Ressourcenbeschränkungen oder Konnektivitätsprobleme

Durch die Anwendung der in diesem Lab behandelten Diagnosetechniken und Best Practices können Sie diese Probleme schnell identifizieren und beheben und so sicherstellen, dass Ihre Docker-Container in jeder Umgebung zuverlässig ausgeführt werden.