Einführung
Docker-Container werden weit verbreitet für das Ausführen verschiedener Anwendungen und Dienste eingesetzt. Die Verwaltung des Lebenszyklus von langlaufenden Containern kann jedoch eine Herausforderung sein. In diesem Tutorial werden Sie durch den Prozess des kontrollierten Herunterfahrens eines langlaufenden Docker-Containers geführt, um einen reibungslosen Übergang sicherzustellen und potenzielle Datenverluste oder Anwendungsfehler zu vermeiden.
Das Verständnis des Docker-Container-Lebenszyklus
Docker-Container haben einen genau definierten Lebenszyklus, den Entwickler verstehen müssen, um ihre Anwendungen effektiv zu verwalten. Dieser Abschnitt bietet einen Überblick über den Docker-Container-Lebenszyklus, einschließlich der verschiedenen Zustände, durch die ein Container übergehen kann, und der Schlüsselkonzepte, die diesem Lebenszyklus zugrunde liegen.
Docker-Container-Zustände
Docker-Container können während ihrer Lebensdauer in mehreren verschiedenen Zuständen existieren:
- Erstellt (Created): Ein Container wurde erstellt, aber noch nicht gestartet.
- Läuft (Running): Der Container führt derzeit seinen Hauptprozess aus.
- Angehalten (Paused): Der Hauptprozess des Containers wurde angehalten, aber der Container läuft weiterhin.
- Gestoppt (Stopped): Der Hauptprozess des Containers wurde beendet.
- Wird neu gestartet (Restarting): Der Container wird derzeit neu gestartet.
- Beendet (Exited): Der Container hat gestoppt und sein Hauptprozess ist beendet.
Das Verständnis dieser Zustände ist wichtig, da sie die Aktionen bestimmen, die Sie an einem Container ausführen können, und das Verhalten, das Sie erwarten können.
graph LR
Created --> Running
Running --> Paused
Paused --> Running
Running --> Stopped
Stopped --> Running
Stopped --> Exited
Docker-Container-Lebenszyklus-Ereignisse
Neben den Container-Zuständen gibt es mehrere Schlüsselereignisse, die während des Lebenszyklus eines Docker-Containers auftreten:
- Erstellen (Create): Ein neuer Container wird erstellt.
- Starten (Start): Der Hauptprozess des Containers wird gestartet.
- Stoppen (Stop): Der Hauptprozess des Containers wird beendet.
- Neustarten (Restart): Der Container wird entweder manuell oder automatisch neu gestartet.
- Anhalten/Wiederaufnehmen (Pause/Unpause): Der Hauptprozess des Containers wird angehalten oder wieder fortgesetzt.
- Zwingendes Beenden (Kill): Der Hauptprozess des Containers wird zwangsweise beendet.
- Löschen (Delete): Der Container wird aus dem System entfernt.
Das Verständnis dieser Lebenszyklus-Ereignisse ist entscheidend für die Verwaltung und Automatisierung des Verhaltens Ihrer Docker-Container.
Umgang mit dem Container-Lebenszyklus über die Docker CLI
Die Docker CLI bietet mehrere Befehle für die Interaktion mit dem Container-Lebenszyklus:
docker create: Erstellt einen neuen Container.docker start: Startet einen gestoppten Container.docker stop: Stoppt einen laufenden Container.docker restart: Startet einen Container neu.docker pause: Pausiert einen laufenden Container.docker unpause: Setzt einen angehaltenen Container fort.docker kill: Stoppt einen laufenden Container zwangsweise.docker rm: Entfernt einen Container.
Diese Befehle ermöglichen es Ihnen, den Lebenszyklus Ihrer Docker-Container programmgesteuert zu verwalten und verschiedene Aufgaben im Zusammenhang mit der Containerverwaltung zu automatisieren.
Kontrolliertes Stoppen von langlaufenden Containern
Beim Umgang mit langlaufenden Docker-Containern ist es wichtig sicherzustellen, dass sie kontrolliert gestoppt werden. Dadurch kann der Hauptprozess des Containers alle erforderlichen Bereinigungs- oder Herunterfahrungsaufgaben ausführen, bevor der Container beendet wird. Dieser Abschnitt untersucht Strategien für das kontrollierte Stoppen von langlaufenden Docker-Containern.
Das Verständnis des SIGTERM-Signals
Der primäre Mechanismus für das kontrollierte Stoppen eines Docker-Containers besteht darin, das SIGTERM-Signal an den Hauptprozess des Containers zu senden. Dieses Signal informiert den Prozess, dass er den Herunterfahrungsvorgang beginnen und alle erforderlichen Bereinigungsaufgaben ausführen sollte.
Standardmäßig sendet Docker, wenn Sie den Befehl docker stop ausführen, das SIGTERM-Signal an den Hauptprozess des Containers und wartet für eine Standard-Timeout-Zeit (typischerweise 10 Sekunden), bis der Prozess beendet wird. Wenn der Prozess innerhalb der Timeout-Zeit nicht beendet wird, sendet Docker dann ein SIGKILL-Signal, das den Prozess zwangsweise beendet.
Anpassen des Herunterfahrungsverhaltens
Um das Herunterfahrungsverhalten eines langlaufenden Docker-Containers anzupassen, können Sie die folgenden Optionen verwenden:
--stop-signal: Geben Sie ein alternatives Signal an, das während desdocker stop-Befehls an den Hauptprozess des Containers gesendet werden soll. Beispielsweise würde--stop-signal=SIGINTdasSIGINT-Signal anstelle des Standard-SignalsSIGTERMsenden.--stop-timeout: Geben Sie die Anzahl der Sekunden an, die gewartet werden soll, bis der Hauptprozess des Containers beendet wird, bevor dasSIGKILL-Signal gesendet wird. Beispielsweise würde--stop-timeout=30dem Prozess 30 Sekunden Zeit geben, um sich zu beenden, bevor er zwangsweise beendet wird.
Hier ist ein Beispiel dafür, wie Sie diese Optionen beim Starten eines langlaufenden Containers verwenden können:
docker run -d --name my-app --stop-signal=SIGINT --stop-timeout=60 my-app:latest
Dieser Befehl würde einen langlaufenden Container namens my-app starten. Wenn der Befehl docker stop ausgegeben wird, würde er das SIGINT-Signal an den Hauptprozess des Containers senden und bis zu 60 Sekunden warten, bis er sich beendet, bevor er das SIGKILL-Signal sendet.
Implementieren des kontrollierten Herunterfahrens in Ihrer Anwendung
Um sicherzustellen, dass Ihre langlaufenden Docker-Container kontrolliert gestoppt werden, ist es wichtig, Ihre Anwendung so zu gestalten, dass sie das SIGTERM-Signal (oder ein alternatives Signal) verarbeitet und alle erforderlichen Bereinigungsaufgaben ausführt, bevor sie beendet wird. Dies kann Aufgaben wie die folgenden umfassen:
- Speichern von in-memory-Daten in einem dauerhaften Speicher
- Schließen von Netzwerkverbindungen oder Datenbankverbindungen
- Leeren von Protokollen oder anderen Ausgaben
- Ausführen anderer anwendungs-spezifischer Bereinigungsaufgaben
Durch die Implementierung dieser Signalverarbeitung in Ihrer Anwendung können Sie sicherstellen, dass Ihre Container auf eine kontrollierte und vorhersehbare Weise gestoppt werden, wodurch das Risiko von Datenverlusten oder anderen Problemen minimiert wird.
Strategien für ein kontrolliertes Herunterfahren
Wenn es darum geht, langlaufende Docker-Container kontrolliert herunterzufahren, gibt es mehrere Strategien, die Sie einsetzen können, um einen reibungslosen und kontrollierten Herunterfahrprozess sicherzustellen. Dieser Abschnitt untersucht einige der Schlüsselstrategien und bewährten Praktiken für ein kontrolliertes Herunterfahren.
Signalverarbeitung in Ihrer Anwendung
Eine der wichtigsten Strategien für ein kontrolliertes Herunterfahren besteht darin, die Signalverarbeitung in Ihrer Anwendung zu implementieren. Dies umfasst das Schreiben von Code, der auf das SIGTERM-Signal (oder ein alternatives Signal) lauscht und die erforderlichen Bereinigungsaufgaben ausführt, bevor die Anwendung beendet wird.
Hier ist ein Beispiel, wie Sie die Signalverarbeitung in einer Node.js-Anwendung implementieren können:
process.on("SIGTERM", () => {
console.log("Received SIGTERM signal, starting graceful shutdown...");
// Perform cleanup tasks, such as:
// - Saving in-memory data to persistent storage
// - Closing network connections or database connections
// - Flushing logs or other output
// - Performing any other application-specific cleanup tasks
console.log("Graceful shutdown complete, exiting process.");
process.exit(0);
});
Durch die Implementierung dieser Signalverarbeitung kann Ihre Anwendung sicherstellen, dass sie einen kontrollierten Herunterfahrvorgang durchführt und das Risiko von Datenverlusten oder anderen Problemen minimiert.
Die Verwendung von Healthchecks und Liveness Probes
Eine weitere Strategie für ein kontrolliertes Herunterfahren ist die Verwendung der integrierten Healthcheck- und Liveness Probe-Funktionen von Docker. Diese Funktionen ermöglichen es Ihnen, Prüfungen zu definieren, die Docker verwenden kann, um die Gesundheit und Bereitschaft Ihres Containers zu bestimmen.
Während des Herunterfahrprozesses können Sie diese Prüfungen nutzen, um Docker zu signalisieren, dass Ihr Container sich im Herunterfahrvorgang befindet. Dadurch kann Docker warten, bis der Herunterfahrvorgang abgeschlossen ist, bevor es den Container entfernt.
Hier ist ein Beispiel, wie Sie einen Healthcheck und eine Liveness Probe in Ihrem Docker-Container konfigurieren können:
## Dockerfile
FROM node:14-alpine
COPY. /app
WORKDIR /app
CMD ["node", "server.js"]
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -f http://localhost:3000/healthz || exit 1
LABEL com.labex.shutdown.signal=SIGINT
LABEL com.labex.shutdown.timeout=60
In diesem Beispiel definiert die HEALTHCHECK-Anweisung einen Healthcheck, der den /healthz-Endpunkt auf dem Webserver des Containers prüft. Die LABEL-Anweisungen definieren das Signal für das kontrollierte Herunterfahren (SIGINT) und die Timeout-Zeit (60 Sekunden).
Während des Herunterfahrprozesses kann Ihre Anwendung den Healthcheck-Endpunkt aktualisieren, um zu signalisieren, dass der Herunterfahrvorgang im Gange ist. Dadurch kann Docker warten, bis der Herunterfahrvorgang abgeschlossen ist, bevor es den Container entfernt.
Die Nutzung von Orchestrierungsframeworks
Wenn Sie Ihre Docker-Container in einem Orchestrierungsframework wie Kubernetes oder Docker Swarm ausführen, können Sie die integrierten Funktionen dieser Frameworks nutzen, um das kontrollierte Herunterfahren zu unterstützen.
Beispielsweise können Sie in Kubernetes den preStop-Hook verwenden, um einen Befehl oder ein Skript auszuführen, das Bereinigungsaufgaben durchführt, bevor der Container beendet wird. Sie können auch das Feld terminationGracePeriodSeconds verwenden, um die Zeitdauer anzugeben, die der Container für ein kontrolliertes Herunterfahren haben soll.
Hier ist ein Beispiel, wie Sie eine Kubernetes-Deployment mit einem preStop-Hook und einer Zeitspanne für ein kontrolliertes Herunterfahren konfigurieren können:
## kubernetes-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 3000
lifecycle:
preStop:
exec:
command: ["/app/shutdown.sh"]
terminationGracePeriodSeconds: 60
In diesem Beispiel führt der preStop-Hook ein Skript (/app/shutdown.sh) aus, das alle erforderlichen Bereinigungsaufgaben durchführt, bevor der Container beendet wird. Das Feld terminationGracePeriodSeconds gibt dem Container 60 Sekunden Zeit, um sich kontrolliert herunterzufahren, bevor er zwangsweise beendet wird.
Durch die Nutzung dieser Funktionen von Orchestrierungsframeworks können Sie die Zuverlässigkeit und Vorhersagbarkeit Ihres Container-Herunterfahrprozesses weiter verbessern.
Zusammenfassung
In diesem Tutorial haben Sie gelernt, wie wichtig es ist, den Lebenszyklus von Docker-Containern zu verstehen und welche Strategien es gibt, um langlaufende Container kontrolliert herunterzufahren. Indem Sie die hier aufgeführten bewährten Praktiken befolgen, können Sie einen reibungslosen und zuverlässigen Herunterfahrprozess gewährleisten und das Risiko von Datenverlusten oder Anwendungsausfällen minimieren. Das Beherrschen der Kunst des kontrollierten Herunterfahrens von Containern ist eine entscheidende Fähigkeit für jeden Docker-Entwickler oder -Administrator.



