Die Kenntnis der verschiedenen Zustände des Docker-Containers ist für jeden ernsthaften Docker-Benutzer unerlässlich.
Ich erkläre den Container-Lebenszyklus und zeige dann die Docker-Befehle für jede Phase des Lebenszyklus.
Aber bevor Sie all diese Dinge lernen, lassen Sie uns noch einmal auf das Konzept des Containers zurückkommen.
Was sind nochmal Docker-Container?
Die meisten traditionellen Definitionen von Containern lauten wie folgt:
Container sind eine Form der Betriebssystemvirtualisierung. Während herkömmliche Hypervisor-basierte Virtualisierung separate Kernel für separate VMs erfordert, teilen sich Container denselben Host-Kernel und sind daher viel leichter und schneller hochzufahren
Die Definition wird sich von Quelle zu Quelle unterscheiden, aber der Kern ist derselbe.
Ich finde es langweilig und unnötig kompliziert. Ich möchte hier etwas anderes verwenden, um Container zu definieren.
Container sind eine Reihe von Prozessen, die betrogen werden.
Warum sage ich das? Weil Container nur eine Sammlung von Prozessen sind, manchmal nur ein einzelner Prozess. Und diese Prozesse werden über verschiedene Ressourcen ihres Hosts wie Netzwerke, Prozessbaum, Dateisystem, Hostname usw. belogen
Sie können jeden Prozess ausführen, sogar eine Shell wie bash
, und verstecken Sie Ihren eigentlichen Prozessbaum davor, geben Sie ihm einen anderen Satz von Netzwerken, verstecken Sie das eigentliche Root-Dateisystem davor, geben Sie ihm einen anderen Hostnamen und im Wesentlichen erstellen Sie am Ende eine containerisierte Version des Prozesses.
Dies wird durch Namespaces, getrenntes Root-Dateisystem und Cgroups erreicht.
Docker ist nur ein Wrapper um die Tools auf niedrigerer Ebene, die die Container ausführen und verwalten, oder genauer gesagt um den Container-Lebenszyklus .
Abgesehen davon erledigt Docker auch viele andere Dinge, wie z. B. das Vereinfachen der Vernetzung für die Container, das Verwalten von Speichern, das Ziehen und Verschieben von Container-Images usw.
Docker ist hier, um unser Leben einfacher zu machen.
Sehen wir uns nun den Docker-Container-Lebenszyklus an
Der Container-Lebenszyklus besteht im Grunde aus einer Reihe von Phasen, beginnend mit der Erstellung des Containers bis zu seiner Zerstörung.
Das folgende Diagramm wird dies deutlich machen.
Lassen Sie mich jede Phase des Container-Lebenszyklus erläutern.
- Erstellung: Viele Leute denken, dass es sich bei der Ausführung eines Containers um einen einzigen Schritt handelt. Aber das ist nicht der Fall. Es gibt einen Prozess, der zuerst die Container vor allem anderen erstellt. Dazu später mehr.
- Gestartet/Läuft: Sobald ein Container erstellt ist, kann er gestartet werden, woraufhin sich der Status in
Running
ändert . Dies ist der Zeitpunkt, an dem der Container tatsächlich etwas tut. - Pausiert: Traditionell verwenden wir zum Anhalten eines Prozesses (was Container im Grunde sind) das SIGSTOP-Signal und zum Aufheben der Pause das SIGCONT-Signal. Da dieses Signal jedoch von den Prozessen beobachtbar ist, werden anstelle von Signalen Cgroup-Freezer verwendet. Auf diese Weise werden die Prozesse durch Einfrieren der cgroup ausgesetzt.
- Beendet/Gestoppt: Das Gegenteil von
Running
, aber nicht dasselbe wiePaused
. Das Stoppen eines Containers bedeutet das Senden des SIGTERM-Signals an den Container-Hauptprozess, d. h. PID 1 im Container-Namensraum. Es wartet dann 10 Sekunden, um den Prozess ordnungsgemäß beenden zu lassen. Wenn nicht, einSIGKILL
Signal gesendet wird, und wir alle wissen, was das bedeutet, nicht wahr? - Zerstört/Gelöscht: Der Container existiert nicht mehr, alle Ressourcen, die ihm einmal zugewiesen wurden, sind jetzt weg.
Ich hoffe, das hat das Konzept des Container-Lebenszyklus jetzt klarer gemacht. Im folgenden Abschnitt gehe ich alle spezifischen Docker-Befehle durch, die Ihnen bei der Verwaltung all dieser Zustände von Containern helfen.
Docker-Befehle zum Verwalten des Containerlebenszyklus
Alle Befehle (Unterbefehle, wenn sie genauer sind), die den Container-Lebenszyklus steuern, gehören zum Unterbefehl container
.
In einem Terminal, wenn Sie docker container --help
ausführen Sie erhalten eine Liste von Unterbefehlen, die mehreren Operationen zugeordnet sind, die auf Containern ausgeführt werden können.
Aber um alle kümmern wir uns hier nicht. Konzentrieren wir uns nur auf eine bestimmte Teilmenge davon.
Container-Erstellung
Die Containererstellung wird durch die folgenden Befehle gehandhabt:
docker container create
docker create
Die erste ist die Langform, während die zweite, Sie haben es richtig erraten, die Kurzform ist.
Ich empfehle Ihnen, die lange Form zu verwenden, da sie ausführlicher ist und etwas, das ich für eine gute Praxis halte.
Was ist Containererstellung?
Die Containererstellung erstellt die R/W-Schicht über der/den R/O-Schicht(en) des angegebenen Images und bereitet sie für die Ausführung des erforderlichen Programms vor. Das Erstellen eines Containers startet nicht den eigentlichen Prozess, Sie können alle Konfigurationsparameter wie Fähigkeiten, CPU-Limit, Speicherlimit, Container-Image usw. direkt in der Erstellungsphase angeben und den Container dann jederzeit starten, ohne diese Parameter erneut angeben zu müssen .
Lesen Sie docker container create --help
für eine Liste der konfigurierbaren Optionen.
Beispiel
Erstellen Sie zuerst einen Container wie den folgenden (ich habe einen alpine
Bild hier, um den Befehl sleep infinity
auszuführen )
docker container create \
--name alpine alpine:latest sleep infinity
Sobald der Container erstellt ist, sollten Sie die ID davon auf dem Terminalbildschirm erhalten. Jetzt können Sie die Containerliste filtern, um die Container zu finden, die nicht ausgeführt, sondern gerade erstellt werden .
docker container ls --filter=status=created
Hier filtere ich die Liste, sodass ich nur die erstellten Container erhalte. Sehen Sie sich den STATUS
an Spalte, die den Status eines Containers angibt. Sie sollten etwa Folgendes sehen:-
➟ docker container ls --filter=status=created
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f8d56fb3f78 alpine:3.13.4 "sleep infinity" 17 seconds ago Created alpine
Sie können den Container auch inspizieren und sehen, in welchem Zustand er sich befindet.
➟ docker container inspect -f '{{json .State.Status}}' alpine
"created"
Mit docker create
wird Ihnen nichts anderes geben.
Container-Startup
Um einen Container zu starten, verwenden Sie einen der beiden folgenden Befehle:-
docker container start
docker start
Dasselbe hier, eine lange und eine kurze Version. Und ich empfehle Ihnen, den ...container start
zu verwenden Befehl.
Was ist Containerstart?
Sobald ein Container erstellt wurde, können Sie ihn starten. Das Starten des Containers bedeutet, dass die containerisierte Anwendung tatsächlich ausgeführt wird.
Während das Erstellen eines Containers lediglich die gesamte Konfiguration vorbereitet (wie der Container ausgeführt wird, Laufzeitumgebung, Laufzeiteinschränkungen, Containername usw.), werden keine Ressourcen zugewiesen.
Das Starten eines Containers weist die erforderlichen Ressourcen zu und führt die Anwendung aus.
Beispiel
Betrachten Sie den vorherigen Container, den wir erstellt haben. Starten Sie den Befehl einfach mit dem Containernamen oder der ID wie folgt:
docker container start alpine
Sobald der Container gestartet ist, ändert sich sein Status von Created
zu Running
. In der Containerliste können Sie wie bisher nach dem Status filtern:-
docker container ls --filter=status=running
Auf dem STATUS
Spalte anstelle von Running
es zeigt an, wie lange der Container seit seinem Start ausgeführt wurde.
➟ docker container ls --filter=status=running
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f8d56fb3f78 alpine:3.13.4 "sleep infinity" 8 minutes ago Up 18 seconds alpine
Sie können einen Container auch auf seinen Zustand überprüfen. Ich werde Go-Vorlagen verwenden, um die Ausgabe auf das Einzige zu formatieren, was ich brauche, nämlich den Staat.
docker container inspect \
-f '{{json .State.Status}}' alpine
Sie sollten so etwas sehen -
➟ docker container inspect -f '{{json .State.Status}}' alpine
"running"
Um nicht überflüssig zu klingen, aber docker start
wird genau dasselbe tun.
Der spezielle Docker-Run-Befehl
Dies ist ein spezieller Befehl, der die Erstellung und den Start des Containers miteinander verbindet, und das ist der Befehl, den wir alle am häufigsten verwenden.
docker container run
docker run
Diese Befehle erstellen im Wesentlichen (i) den Container und starten dann sofort (ii) denselben Container.
Dies ist nützlich, da wir nicht allzu oft einen Container erstellen und verlassen, um ihn zu einem späteren Zeitpunkt zu starten. Wenn Sie sich an der Befehlszeile befinden, können Sie mit der Docker-CLI ausführen ein Container. Und genau das ist ...container run
Befehl tut.
Beispiel
Beispiel für diesen Befehl ist sehr einfach. Um einen Container auszuführen, statt docker container create
, verwenden Sie docker container run
.
Sie werden müssen alle Optionen übergeben, die Sie an docker container create
übergeben würden zu diesem docker container run
Befehl. Dies liegt daran, dass Docker alle diese Informationen genau in diesem Moment benötigt, da es keine zweiten Schritte mehr gibt.
➟ docker container run --name echo-me alpine:3.13.4 echo "Subscribe to Linux Handbook"
Subscribe to Linux Handbook
Docker Run vs. Start vs. Create:Unterschied erklärtFür einen Docker-Anfänger könnten Begriffe wie Docker-Start, Docker-Run und Docker-Erstellung verwirrend sein. Dieser Artikel erklärt den Unterschied anhand von Beispielen. Linux-HandbuchAbhishek Prakash Container wird angehalten
Das Anhalten eines Containers bedeutet genau, wie es sich anhört. Wir stoppen keine Prozesse, sondern halten sie nur an. Wenn also ein Prozess in einem Container von 1 bis 100 zählt und er bei Zählung 50 angehalten und zu einem späteren Zeitpunkt nicht mehr angehalten wurde, wird die Zählung fortgesetzt ab 50.
Eine Sache, die Sie verstehen sollten, ist, dass während Paused
ist ein aktueller Zustand, Unpaused
ist nicht. Wenn Sie einen angehaltenen Container wieder aufheben, ändern Sie im Wesentlichen den Status von Paused
zu Running
.
Die Befehle zum Anhalten eines Containers lauten wie folgt:-
docker container pause
docker pause
Auf ähnliche Weise können Sie einen Container mit den Gegenstücken zum Aufheben der Pause aufheben:-
docker container unpause
docker unpause
Wie wird ein Container angehalten?
Ein Prozess wird unter Verwendung des SIGSTOP-Signals angehalten, und um die Unterbrechung fortzusetzen, wird das SIGCONT-Signal verwendet. Da diese Signale von den Prozessen beobachtet werden können, werden anstelle von Signalen cgroup Freezer verwendet. Auf diese Weise werden die Prozesse durch Einfrieren der cgroup ausgesetzt. Das Einfrieren einer Kontrollgruppe friert alle ihre Aufgaben und alle ihre untergeordneten Kontrollgruppen ein.
Beispiel:
Für diese Demo habe ich einen speziellen Container erstellt. Ziehen Sie das Bild, indem Sie den folgenden Befehl ausführen:-
docker image pull debdutdeb/pause-demo:v1
Sie können das Dockerfile und den Code hier überprüfen.
Starten Sie nach dem Ziehen auf einem Terminal einen Container mit diesem Bild
docker container run --name pause-demo debdutdeb/pause-demo:v1
Es sollte jetzt das Zählen beginnend bei 0 und weiter anzeigen. Sollte in etwa so aussehen
➟ docker container run --name pause-demo debdutdeb/pause-demo:v1
Count at 30
Halten Sie diesen Container auf einem anderen Terminal an.
docker container pause pause-demo
In dem Moment, in dem Sie den Container anhalten, sollte der Countdown gestoppt werden, aber das Terminal ist noch nicht wieder für Sie da. Dies liegt daran, dass der Container noch nicht gestoppt wurde (darüber werde ich später in diesem Artikel sprechen). Sobald Sie diesen Container wieder anhalten, sollte der Countdown fortgesetzt und nicht neu gestartet werden.
docker container unpause pause-demo
Um das Terminal zurückzubekommen, auf einem separaten Terminal ausführen
docker container stop pause-demo
Hier ist ein kurzes Video, das dies in Aktion zeigt:-
Bevor Sie den Container anhalten, können Sie wie bei den vorherigen den Status des angehaltenen Containers wie folgt überprüfen:
➟ docker container inspect -f '{{json .State.Status}}' pause-demo
"paused"
Container wird gestoppt
Sie können einen Docker-Container mit einem der folgenden beiden Befehle stoppen:-
docker container stop
docker stop
Das Stoppen eines Containers bedeutet das Stoppen aller damit verbundenen Prozesse.
Dies ist nicht dasselbe wie das Anhalten eines Containers. Wenn Sie einen Container anhalten, können Sie ihn neu starten, aber die Prozesse werden nicht in dem Zustand fortgesetzt, in dem sie sich zuvor befanden. Ein Prozess kann seine Zustandsinformationen in einer "Datei" speichern und seinen Zustand aus dieser Datei wiederherstellen, aber das ist ein anderer Fall.
Zum Beispiel, nachdem Sie die vorherige pause-demo
gestoppt haben Container, wenn Sie versuchen, ihn mit ...container start
neu zu starten Befehl, beginnt es von Anfang an zu zählen, im Gegensatz zu seiner pause
Gegenstück, das die Zählung fortsetzt.
Wie funktioniert der Prozess?
Wenn Sie Docker bitten, einen Container zu stoppen, sendet es ein SIGTERM
Signal an PID 1 des Containers. Danach wartet es 10 Sekunden lang, was seine ordnungsgemäße Zeitspanne ist. Dem Prozess wird diese Zeit gegeben, um ordnungsgemäß zu beenden, mit anderen Worten aufzuräumen und zu beenden, was immer er gearbeitet hat. Nach Ablauf der 10 Sekunden sendet Docker ein abschließendes SIGKILL
Signal, ich muss dir nicht sagen, was als nächstes passiert.
Docker sendet das Signal an PID 1 des Containers, da jeder andere Prozess ein untergeordneter Prozess von PID 1 ist, wenn dieser Prozess beendet/beendet wird, werden die untergeordneten Prozesse automatisch aufhören zu existieren.
Dies wird mit dem Beispiel unten deutlicher.
Beispiel:
Sie müssen erneut ein Bild ziehen.
docker image pull debdutdeb/stop-demo:v1
Das Dockerfile und den Quellcode finden Sie in dieser Zusammenfassung.
Starten Sie in einem Terminal einen Container von diesem Image.
docker container run --name stop-demo debdutdeb/stop-demo:v1
Nach der Ausführung sollten Sie einen Bildschirm sehen, der Ihnen die PID mitteilt und dass es wartet.
➟ docker container run --name stop-demo debdutdeb/stop-demo:v1
My PID in this container is 1
Waiting...
Öffnen Sie ein anderes Terminal und führen Sie den Stoppbefehl für diesen Container aus.
docker container stop stop-demo
Nach der Ausführung sollten Sie auf dem Terminal sehen, auf dem der Container ausgeführt wurde, und Ihnen sagen, was IT erlebt, d. h. den SIGTERM
empfängt Signal.
Danach beginnt es, die Sekunden zu zählen, und nach 10 Sekunden hört es einfach auf zu zählen. Das liegt nicht daran, dass ich es so fest codiert habe, sondern ich habe es so fest codiert, dass es unendlich weitergeht.
Aber nach 10 Sekunden sendet Docker ein SIGKILL
Signal, das wir nicht abfangen oder ignorieren können, wird der Prozess zwangsläufig beendet.
Sie können die Zeit ändern, die der Docker wartet, bevor er SIGKILL
sendet Signal mit dem -t
Option mit docker container stop
.
Sobald alles fertig ist, sollten Sie so etwas sehen
➟ docker container run --name stop-demo debdutdeb/stop-demo:v1
My PID in this container is 1
Waiting...
SIGTERM ignored,
Starting count..
10 seconds
Hier ist ein kleines Video, das dies demonstriert:-
Sie können den Zustand dieses Containers jetzt mit ...container inspect
überprüfen etwa so:-
➟ docker container inspect -f '{{json .State.Status}}' stop-demo
"exited"
Containerlöschung
Ein Container wird mit einem der beiden folgenden Befehle gelöscht:-
docker container rm
docker rm
Containerlöschung ist das Gegenteil von Containererstellung. Wenn Sie einen Container löschen, ist er weg, Sie können dieses Spezifische nicht bringen Behälter zurück. Sie können ein neues aus demselben Image mit derselben Konfiguration starten, es identisch machen, aber es wird nicht genau das vorherige sein.
Beispiel:
Entfernen Sie zum Beispiel einfach das vorherige stop-demo
Behälter.
docker container rm stop-demo
Bis jetzt können alle Container, die Sie erstellt und dann gestoppt haben, mit einem einzigen Befehl entfernt werden:-
docker container prune
Dadurch werden alle Container mit dem Status Exited
gelöscht .
Beispielausgabe:
✗ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
ffbdd621c01d0eb3f42d348eeb75c731ddd9bd85674bb90dece32bd70357e541
21b9ed6a6198cd6ee7e162aebd936ae3e93b3b0f738161924a825a27794f2b20
f5f5149866a6ced675ad3bfff0b7386f75ee3fdbddca86be8b8ba341dba4b27f
Total reclaimed space: 0B
Sie haben also das Container-Lebenszykluskonzept kennengelernt. Und Sie haben auch die Docker-Befehle gelernt, um jede Phase des Lebenszyklus der Container zu verwalten. Wenn Sie weitere Docker-Tipps wünschen, können Sie sich über diese weniger bekannten, aber nützlichen Docker-Befehle informieren.
3 Docker-Befehle, die fortgeschrittene Docker-Benutzer kennen solltenHier sind einige Docker-Befehle, die Sie vielleicht nicht kennen, die sich aber beim Verwalten Ihrer Container als nützlich erweisen könnten. Linux-Handbuch Debdut ChakrabortyIch hoffe wirklich, dass dieser Artikel die Theorie des Container-Lebenszyklus leicht verständlich gemacht und auch alle Befehle gelöscht hat, die Sie benötigen, um diese verschiedenen Status zu verwalten.
Wenn Sie Fragen haben, hinterlassen Sie bitte unten einen Kommentar.