Funktionsweise von Docker-Containern
- 10 Minuten
Bereits zuvor haben Sie festgestellt, dass der Container die Einheit wird, mit der Sie Ihre Anwendungen verteilen. Sie haben auch gelernt, dass der Container in einem standardisierten Format ist, das sowohl Ihre Entwickler- als auch Ihre Betriebsteams verwenden.
In Ihrem Beispiel soll ein Portal zur Auftragsverfolgung für die verschiedenen Filialen des Unternehmens entwickelt werden. Nachdem das Docker-Image erstellt wurde, ist das Betriebsteam nun für die Bereitstellung, den Rollout von Updates und die Verwaltung des Portals zur Auftragsverfolgung verantwortlich.
In der vorherigen Einheit haben Sie gelernt, wie ein Docker-Image erstellt wird. In dieser Einheit werden der Lebenszyklus eines Docker-Containers und die Verwaltung von Containern beschrieben. Zudem erhalten Sie Informationen zur Konfiguration der Datenspeicher- und Netzwerkoptionen für Ihre Container.
Verwalten von Docker-Containern
Der Lebenszyklus eines Docker-Containers ermöglicht es Ihnen, den Status des Containers zu verwalten und nachzuverfolgen.
Mit dem Befehl run wird ein Container in den Ausführungsstatus versetzt. Sie können auch einen bereits laufenden Container neu starten. Wird ein Container neu gestartet, empfängt er ein Beendigungssignal und fährt alle laufenden Prozesse ordnungsgemäß herunter, bevor der Kernel des Containers beendet wird.
Ein Container befindet sich im Ausführungsstatus, bis er angehalten oder beendet wird. Die Ausführung kann jedoch auch vom Container selbst beendet werden. Wenn der laufende Prozess abgeschlossen wird oder in einen Fehlerzustand gerät, kann der Container automatisch beendet werden.
Mit dem Befehl pause
wird ein Container angehalten. Damit werden alle Prozesse im Container angehalten.
Um einen laufenden Container zu stoppen, verwenden Sie den Befehl stop
. Mit dem Befehl stop
werden laufende Prozesse ordnungsgemäß über ein Beendigungssignal heruntergefahren. Der Kernel des Containers wird beendet, nachdem der Prozess heruntergefahren wurde.
Mit dem Befehl kill
wird ein Abbruchsignal gesendet, um den Container zu beenden. Der Kernel des Containers empfängt das Abbruchsignal, der laufende Prozess jedoch nicht. Mit diesem Befehl wird die Beendigung des laufenden Prozesses im Container erzwungen.
Mit dem Befehl remove
werden schließlich Container entfernt, die sich im Status „Beendet“ befinden. Nach dem Entfernen eines Containers werden alle darin gespeicherten Daten gelöscht.
So können Sie verfügbare Container anzeigen
Um ausgeführte Container aufzulisten, führen Sie den Befehl docker ps
aus. Übergeben Sie das Argument -a
, wenn Sie alle Container mit sämtlichen Status anzeigen möchten.
Ein Beispiel:
docker ps -a
Mit diesem Befehl wird die folgende Ausgabe erzeugt:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d93d40cc1ce9 tmp-ubuntu:latest "dotnet website.dll …" 6 seconds ago Up 5 seconds 8080/tcp happy_wilbur
33a6cf71f7c1 tmp-ubuntu:latest "dotnet website.dll …" 2 hours ago Exited (0) 9 seconds ago adoring_borg
Überprüfen Sie in der vorherigen Ausgabe die folgenden drei Elemente:
Der in der Spalte IMAGE aufgeführte Image-Name; in diesem Beispiel tmp-ubuntu: latest. Wie Sie sehen, können Sie mehr als einen Container aus demselben Image erstellen. Dieses leistungsstarke Verwaltungsfeature ermöglicht die Skalierung innerhalb Ihrer Lösungen.
Der Status des Containers ist in der Spalte STATUS aufgeführt. In diesem Beispiel wird ein Container ausgeführt, und ein anderer wurde beendet. Der Status des Containers ist in der Regel der erste Indikator für seinen Zustand.
Der Namen des Containers in der Spalte NAMES aufgeführt. Zusätzlich zur Container-ID in der ersten Spalte erhalten Container auch einen Namen. In diesem Beispiel haben Sie nicht explizit einen Namen für jeden Container angegeben. Daher wurde dem Container von Docker ein zufälliger Name zugewiesen. Um einem Container mit dem Flag
run
einen expliziten Namen zu geben, verwenden Sie den Befehl--name
.
Wozu erhalten Container einen Namen?
Mit dieser Funktion ist es möglich, mehrere Containerinstanzen desselben Images auszuführen. Containernamen sind eindeutig. Das bedeutet, dass Sie einen bereits angegebenen Namen nicht erneut verwenden können, um einen neuen Container zu erstellen. Die einzige Möglichkeit, einen bestimmten Namen erneut zu verwenden, besteht darin, den vorherigen Container zu entfernen.
Ausführen eines Containers
Verwenden Sie den Befehl docker run
, um einen Container zu starten. Wenn Sie den Container aus dem Image starten möchten, geben Sie das auszuführende Image über dessen Namen oder ID an. Ein Container, der auf diese Weise gestartet wird, bietet interaktive Funktionen.
Fügen Sie hier das Flag -d
hinzu, damit der Container mit der Website im Hintergrund ausgeführt wird.
docker run -d tmp-ubuntu
Der Befehl gibt in diesem Fall nur die ID des neuen Containers zurück.
Nachdem Sie ein Image für die Ausführung angegeben haben, sucht Docker das Image, lädt den Container aus dem Image und führt den als Einstiegspunkt angegebenen Befehl aus. Ab diesem Zeitpunkt kann der Container verwaltet werden.
So pausieren Sie einen Container
Führen Sie den Befehl docker pause
aus, um einen Container anzuhalten. Ein Beispiel:
docker pause happy_wilbur
Durch das Anhalten eines Containers werden alle Prozesse angehalten. Dieser Befehl ermöglicht es dem Container, Prozesse zu einem späteren Zeitpunkt fortzusetzen. Mit dem Befehl docker unpause
werden alle Prozesse in den angegebenen Containern wieder aktiviert.
Wie man einen Container neu startet
Führen Sie den Befehl docker restart
aus, um einen Container neu zu starten. Ein Beispiel:
docker restart happy_wilbur
Der Container erhält einen Befehl zum Beenden, gefolgt von einem Startbefehl. Wenn der Container nicht auf den Befehl zum Beenden antwortet, wird ein Abbruchsignal gesendet.
Wie man einen Container stoppt
Führen Sie den Befehl docker stop
aus, um einen laufenden Container anzuhalten. Ein Beispiel:
docker stop happy_wilbur
Der Befehl zum Beenden sendet ein Beendigungssignal an den Container und den Prozess, der im Container ausgeführt wird.
Entfernen eines Containers
Führen Sie den Befehl docker rm
aus, um einen Container zu entfernen. Ein Beispiel:
docker rm happy_wilbur
Alle Daten im Container werden zerstört, nachdem Sie den Container entfernt haben. Es ist wichtig, Container beim Speichern von Daten immer als temporär zu betrachten.
Speicherkonfiguration für Docker-Container
Wie bereits erwähnt, müssen Container immer als temporär betrachtet werden, wenn die App in einem Container Daten speichern muss.
Nehmen wir an, dass Ihr Überwachungsportal eine Protokolldatei in einem Unterordner des App-Stamms erstellt, also direkt im Dateisystem des Containers. Wenn Ihre App Daten in die Protokolldatei schreibt, schreibt das System die Daten in die beschreibbare Containerschicht.
Obwohl dieser Ansatz funktioniert, hat er leider mehrere Nachteile.
Containerspeicher sind temporär.
Die Protokolldatei wird zwischen den Containerinstanzen nicht beibehalten. Nehmen Sie beispielsweise an, dass Sie den Container beenden und entfernen. Wenn Sie eine neue Containerinstanz starten, basiert die neue Instanz auf dem angegebenen Image, und alle Ihre vorherigen Daten fehlen. Denken Sie daran, dass alle Daten in einem Container zusammen mit dem Container zerstört werden, wenn dieser entfernt wird.
Containerspeicher sind mit dem zugrunde liegenden Hostcomputer gekoppelt.
Vom Container aus auf die Protokolldatei zuzugreifen oder diese zu verschieben ist schwierig, da der Container mit dem zugrunde liegenden Hostcomputer gekoppelt ist. Wir müssen eine Verbindung mit der Containerinstanz herstellen, um auf die Datei zuzugreifen.
Container-Speicherlaufwerke sind weniger leistungsstark.
Container implementieren einen Speichertreiber, damit Ihre Apps Daten schreiben können. Dieser Treiber führt eine zusätzliche Abstraktion ein, um mit dem Kernel des Hostbetriebssystems zu kommunizieren, und ist weniger leistungsfähig als das direkte Schreiben in ein Dateisystem des Hosts.
Container können zwei Optionen zum Speichern von Daten verwenden. Die erste Option besteht darin, Volumes zu verwenden, und die zweite sind Bindungseinbindungen.
Was ist ein Volume?
Ein Volume wird im Dateisystem des Hosts in einem bestimmten Ordner gespeichert. Wählen Sie einen Ordner aus, von dem Sie wissen, dass seine Daten nicht von Nicht-Docker-Prozessen geändert werden.
Docker erstellt und verwaltet das neue Volume, indem der Befehl docker volume create
ausgeführt wird. Dieser Befehl kann einen Teil der Dockerfiledefinition bilden. Das bedeutet, dass Sie bei der Containererstellung auch Volumes erstellen können. Docker erstellt das Volume, wenn es noch nicht existiert, sobald Sie versuchen, es zum ersten Mal in einen Container einzubinden.
Volumes werden in Verzeichnissen auf dem Dateisystem des Hosts gespeichert. Docker bindet die Volumes im Container ein und verwaltet sie. Nach der Einbindung werden diese Volumes vom Hostcomputer isoliert.
Mehrere Container können gleichzeitig dieselben Datenvolumen verwenden. Volumes werden auch nicht automatisch entfernt, wenn ein Container das Volume nicht mehr verwendet.
In diesem Beispiel können Sie auf dem Containerhost ein Verzeichnis erstellen und dieses Volume in den Container einbinden, wenn Sie den Container des Überwachungsportals erstellen. Wenn das Überwachungsportal Daten protokolliert, können Sie über das Dateisystem des Containerhosts auf diese Informationen zugreifen. Sie haben Zugriff auf diese Protokolldatei, auch wenn der Container entfernt wurde.
Docker bietet auch eine Möglichkeit für Drittanbieter, Add-Ons zu erstellen, die als Volumes verwendet werden sollen. Azure Storage umfasst beispielsweise ein Plug-In zum Einbinden von Azure Storage als Volumes in Docker-Containern.
Was ist eine Bindungseinbindung?
Ein Bind Mount ist grundsätzlich dasselbe wie ein Volume. Allerdings können Sie statt eines bestimmten Ordners jede beliebige Datei oder jeden beliebigen Ordner auf dem Host einbinden. Sie erwarten auch, dass der Host die Inhalte dieser Einbindungen ändern kann. Genau wie Volumes wird die Bindungseinbindung erstellt, wenn sie eingebunden wird, und ist noch nicht auf dem Host vorhanden.
Bind-Mounts haben im Vergleich zu Volumes eine eingeschränkte Funktionalität, und obwohl sie leistungsstärker sind, sind sie davon abhängig, dass der Host über eine bestimmte Ordnerstruktur verfügt.
Volumes gelten als die bevorzugte Datenspeicherstrategie für Container.
Für Windows-Container ist eine weitere Option verfügbar: Sie können einen SMB-Pfad als Volume einbinden und für Container verfügbar machen. So können Container auf verschiedenen Hosts denselben persistenten Speicher verwenden.
Netzwerkkonfiguration für Docker-Container
Die standardmäßige Docker-Netzwerkkonfiguration ermöglicht die Isolation von Containern auf dem Docker-Host. Dieses Feature ermöglicht es Ihnen, Apps zu erstellen und zu konfigurieren, die sicher miteinander kommunizieren können.
Docker stellt verschiedene Netzwerkeinstellungen für Linux und Windows zur Verfügung.
Für Linux gibt es sechs vorkonfigurierte Netzwerkoptionen:
- Brücke
- Gastgeber
- Überlagerung
- IPvLan
- MACvLan
- Keine
Für Windows gibt es sechs vorkonfigurierte Netzwerkoptionen:
- Netzwerkadressenübersetzung (NAT)
- Transparent
- Überlagerung
- L2Bridge
- L2Tunnel
- Keine
Abhängig von den Netzwerkanforderungen wählen Sie aus, welche dieser Netzwerkkonfigurationen auf Ihren Containern angewendet werden sollen.
Was ist das Bridge-Netzwerk?
Das Bridge-Netzwerk ist die Standardkonfiguration, die beim Start auf Container angewendet wird, ohne dass weitere Netzwerkkonfigurationen angegeben werden. Dieses Netzwerk ist ein internes, privates Netzwerk, das vom Container verwendet wird und das Containernetzwerk vom Docker-Hostnetzwerk trennt.
Jedem Container im Bridge-Netzwerk wird eine IP-Adresse und Subnetzmaske zugewiesen, wobei der Hostname standardmäßig dem Containernamen entspricht. Container, die mit dem standardmäßigen Bridge-Netzwerk verbunden sind, können über die IP-Adresse auf andere mit Bridge verbundene Container zugreifen. Das Bridge-Netzwerk lässt die Kommunikation zwischen Containern mithilfe von Hostnamen nicht zu.
Standardmäßig werden von Docker keine Containerports veröffentlicht. Verwenden Sie das Flag --publish
für „docker port“, um die Portzuordnung zwischen den Containerports und den Docker-Hostports zu aktivieren.
Das Flag „publish“ konfiguriert effektiv eine Firewallregel, die die Ports zuordnet.
In diesem Beispiel ist das Überwachungsportal für Clients verfügbar, die Port 80 ansteuern. Sie müssen Port 80 aus dem Container einem verfügbaren Port auf dem Host zuordnen. Auf dem Host ist Port 8080 geöffnet, sodass Sie das Flag wie folgt festlegen können:
--publish 8080:80
Alle Clients, die zur Docker-Host-IP und Port 8080 navigieren, können auf das Überwachungsportal zugreifen.
Abgesehen von Linux-spezifischen Konfigurationen funktioniert das NAT-Netzwerk unter Windows genauso wie ein Bridge-Netzwerk. Außerdem ist NAT das Standardnetzwerk unter Windows, und alle Container stellen eine Verbindung mit dem Netzwerk her, sofern nicht anders angegeben.
Was ist das Host-Netzwerk?
Mit dem Hostnetzwerk können Sie den Container direkt im Hostnetzwerk ausführen. Durch diese Konfiguration wird die Isolation zwischen dem Host und dem Container auf Netzwerkebene effektiv entfernt.
Nehmen wir in diesem Beispiel an, Sie entscheiden sich dazu, die Netzwerkkonfiguration auf die Host-Netzwerkoption zu ändern. Das Überwachungsportal ist weiterhin über die Host-IP verfügbar. Nun kann der bekannte Port 80 anstelle eines zugeordneten Ports verwendet werden.
Bedenken Sie dabei, dass der Container nur Ports verwenden kann, die nicht bereits vom Host verwendet werden.
Unter Windows ist das Host-Netzwerk nicht verfügbar. Auf Windows-Hosts gibt es keine Option, dieselbe IP-Adresse (Netzwerkstapel) gemeinsam für Host und Container zu verwenden. Das NAT-Netzwerk funktioniert ähnlich wie ein Bridge-Netzwerk, und die Überlagerungsoption stellt eine IP-Adresse für den Container in demselben Netzwerk wie der Host bereit, aber nicht die gleiche IP-Adresse.
Überlagerung und andere Netzwerkoptionen
Für komplexere Szenarien bieten sowohl Linux als auch Windows zusätzliche Netzwerkoptionen. Beispielsweise erstellt die Überlagerungsoption einen virtuellen Switch aus dem Host-Netzwerk, sodass Container in diesem Netzwerk IP-Adressen von DHCP-Servern abrufen oder mit IP-Adressen aus diesem Netzwerksegment arbeiten können. Darüber hinaus ermöglicht Docker Drittanbietern die Erstellung von Netzwerk-Plug-Ins.
Was ist das none-Netzwerk?
Mit der Netzwerkoption none werden Netzwerke für Container deaktiviert. Dies kann nützlich sein, wenn Sie über eine Anwendung verfügen, die das Netzwerk nicht verwendet oder nur überprüfen möchten, ob eine Anwendung wie erwartet in einem Container ausgeführt wird.
Überlegungen zum Betriebssystem
Beachten Sie, dass es Unterschiede zwischen den Desktopbetriebssystemen für die Docker-Netzwerkkonfigurationsoptionen gibt. Die Netzwerkschnittstelle Docker0 ist beispielsweise nicht für macOS verfügbar, wenn das Bridge-Netzwerk verwendet wird. Ebenso wird die Verwendung der Konfiguration für das Host-Netzwerk für Windows- und macOS-Desktops nicht unterstützt.
Diese Unterschiede können sich auf die Art und Weise auswirken, in der Ihre Entwickler ihren Workflow zum Verwalten der Containerentwicklung konfigurieren. Darüber hinaus können Containerorchestratoren zusätzlich zum Docker-Setup auch andere Netzwerkkonfigurationen bereitstellen.