Was ist Docker?

Ein Docker-Container ist ein Packaging-Format, das den gesamten Code und die Abhängigkeiten einer Anwendung in einem Standardformat verpackt und eine schnelle und zuverlässige Ausführung über Compute-Umgebungen hinweg ermöglicht. Bei einem Docker-Container handelt es sich um einen beliebten, leichten und eigenständigen ausführbaren Container, der alles erforderliche zur Ausführung einer Anwendung enthält, einschließlich von Bibliotheken, Systemtools, Code und Laufzeit. Docker ist auch eine Softwareplattform, mit der Entwickler Containeranwendungen schnell erstellen, testen und bereitstellen können.

Containers as a Service (CaaS) oder Container-Services sind verwaltete Cloud-Services, die den Lebenszyklus von Containern managen. Container-Services unterstützen die Orchestrierung der Laufzeit von Containern (starten, anhalten, skalieren). Mithilfe von Containerservices können Sie Ihre Anwendungsentwicklung und den Bereitstellungslebenszyklus vereinfachen, automatisieren und beschleunigen.

Docker und Container-Services haben sich schnell durchgesetzt und waren im Laufe der letzten Jahre ein enormer Erfolg. Aus einer fast unbekannten und eher technischen Open-Source-Technologie im Jahr 2013 hat sich Docker zu einer standardisierten Laufzeitumgebung entwickelt, die jetzt offiziell von vielen Unternehmensprodukten von Oracle unterstützt wird.

Docker-Terminologie definieren

Docker:

Eine Software-Container-Plattform für die Entwicklung, den Versand und die Ausführung von Anwendungen mithilfe der Containertechnologie. Docker umfasst zwei Versionen: Enterprise Edition und Community Edition

Container:

Im Gegensatz zu einer VM, die Hardwarevirtualisierung bereitstellt, bietet ein Container eine einfache Virtualisierung auf Betriebssystemebene, indem der „Benutzerbereich“ abstrahiert wird. Container verwenden den Kernel des Hostsystems für andere Container gemeinsam. Ein auf dem Hostbetriebssystem ausgeführter Container ist eine Standardsoftwareeinheit, mit der Code und alle zugehörigen Abhängigkeiten gepackt werden, sodass Anwendungen schnell und zuverlässig von einer Umgebung zur anderen ausgeführt werden können. Container sind nicht persistent und nicht an Images angepasst.

Docker-Engine:

Die Open-Source-Hostsoftware, mit der die Container erstellt und ausgeführt werden. Docker Engines fungieren als Client-Server-Anwendung zur Unterstützung von Containern auf verschiedenen Windows-Servern und Linux-Betriebssystemen, einschließlich Oracle Linux, CentOS, Debian, Fedora, RHEL, SUSE und Ubuntu.

Docker-Images:

Sammlung von Software, die als Container ausgeführt werden soll, der eine Reihe von Anweisungen zum Erstellen eines Containers enthält, der auf der Docker-Plattform ausgeführt werden kann. Bilder können nicht geändert werden, und Änderungen an einem Image erfordern die Erstellung eines neuen Images.

Docker-Registry:

Platz zum Speichern und Herunterladen von Bildern. Die Registry ist eine zustandslose und skalierbare serverseitige Anwendung, in der Docker-Images gespeichert und verteilt werden.

Wer verwendet Docker?

Docker ist ein offenes Framework für die Anwendungsentwicklung, das für DevOps und Entwickler konzipiert wurde. Mit Docker können Entwickler problemlos Anwendungen als leichte, portable und autarke Container erstellen, verpacken, versenden und ausführen. Diese Container können dabei praktisch überall ausgeführt werden. Container ermöglichen Entwicklern, eine Anwendung mit all ihren Abhängigkeiten zu verpacken und als Einheit bereitzustellen. Die Bereitstellung vorgefertigter und autarker Anwendungscontainer erlaubt Entwicklern, sich auf den Anwendungscode und dessen Verwendung zu konzentrieren, ohne sich Gedanken um das zugrunde liegende Betriebssystem oder das Bereitstellungssystem machen zu müssen.

Darüber hinaus können Entwickler Tausende von Open Source-Containeranwendungen nutzen, die bereits für die Ausführung in einem Docker-Container entwickelt wurden. Für DevOps-Teams eignet sich Docker als kontinuierliche Integrations- und Entwicklungs-Toolkette. Es reduziert die Einschränkungen und die erforderliche Komplexität in der Systemarchitektur, um die Anwendungen bereitzustellen und zu verwalten. Mit der Einführung von Cloud-Services zur Container-Orchestrierung kann jeder Entwickler containerisierte Anwendungen lokal in seiner Entwicklungsumgebung erstellen. Diese containerisierten Anwendungen können dann in der Produktion in Cloud-Services wie z. B. verwaltete Kubernetes-Dienste verschoben und dort ausgeführt werden.

Docker und Entwickler

Container können von beliebigen Entwicklern verpackt werden. Einzelpersonen in der Softwarebranche unterscheiden Entwickler oft nach Spezialisierungen – Frontend, Backend oder irgendwo dazwischen. Obwohl man meist Backend-Entwickler sieht, die Container paketieren, kann jeder, der mit den grundlegenden CaaS-Konzepten vertraut ist, in diesem speziellen Bereich des Softwareentwicklungszyklus erfolgreich sein. Bevor Sie die Abhängigkeiten Ihrer Anwendung verpacken können, besuchen Sie developer.oracle.com und machen Sie sich mit Tools vertraut, mit denen Sie Ihre Anwendung oder Ihr Programm erstellen können.

Docker im Vergleich zu Kubernetes

Linux-Container existieren zwar seit 2008, sie wurden jedoch bis zum Aufkommen von Docker-Containern im Jahr 2013 nicht bekannt. Zu Beginn von Docker-Containern nahm das Interesse an der Entwicklung und dem Deployment von containerisierten Anwendungen stark zu. Als die Anzahl der containerisierten Anwendungen auf Hunderte von Containern anwuchs, die über mehrere Server hinweg bereitgestellt wurden, wurde deren Betrieb immer komplexer. Wie koordiniert, skaliert, verwaltet und terminiert man also Hunderte von Containern? Hier kann Kubernetes helfen. Kubernetes ist ein Open Source-Orchestrierungssystem, mit dem Sie Ihre Docker-Container und Workloads ausführen können. Es hilft Ihnen bei der Bewältigung der Ausführungskomplexität, wenn Sie mehrere Container, die über verschiedene Server hinweg bereitgestellt sind, skalieren wollen. Die Kubernetes-Engine koordiniert automatisch den Container-Lebenszyklus und verteilt die Anwendungscontainer über die Hosting-Infrastruktur hinweg. Kubernetes kann schnell je nach Bedarf Ressourcen ausweiten oder verkleinern. Es sorgt kontinuierlich für Bereitstellungen, Planungen und Löschungen und überwacht den Zustand der Container.

Grundlagen zu Docker

Die Kernkonzepte von Docker sind Images und Container. Ein Docker-Image enthält alles, was für die Ausführung Ihrer Software erforderlich ist: den Code, eine Laufzeit (z. B. Java Virtual Machine (JVM), Treiber, Tools, Skripte, Bibliotheken, Deployments und vieles mehr.

Ein Docker-Container ist eine ausgeführte Instanz eines Docker-Images. Im Gegensatz zu einer herkömmlichen Virtualisierung mit einem Hypervisor vom Typ 1 oder Typ 2 wird ein Docker-Container jedoch auf dem Kernel des Host-Betriebssystems ausgeführt. Innerhalb eines Docker-Images gibt es kein separates Betriebssystem, wie Sie in Abbildung 1 sehen können.

Image zu Docker-Grundlagen
Abbildung 1

Isolation im Vergleich zu Virtualisierung

Jeder Docker-Container verfügt über ein eigenes Dateisystem, einen eigenen Netzwerkstapel (und damit eine eigene IP-Adresse), einen eigenen Prozessraum und definierte Ressourcenbeschränkungen für CPU und Speicher. Da ein Docker-Container kein Betriebssystem hochfahren muss, startet er sofort. Das grundlegende Konzept von Docker ist die Isolation, d. h. die Trennung der Ressourcen eines Host-Betriebssystems. Im Gegensatz dazu steht die Virtualisierung, bei der ein Gast-Betriebssystem über dem Host-Betriebssystem bereitgestellt wird.

Inkrementelles Dateiensystem

Image zu Inkrementellen Dateiensystemen
Abbildung 2

Das Dateisystem eines Docker-Images ist mit einer Copy-on-Write-Semantik überlagert. Dies erlaubt eine Vererbung und Wiederverwendung, spart Festplattenressourcen und ermöglicht das inkrementelle Herunterladen von Images.

Wie in Abbildung 2 dargestellt, könnte ein Docker-Image mit einer Weblogic-Bereitstellung auf einem Image mit einer Oracle WebLogic Server-Domäne basieren. Dieses könnte wiederum auf einem Weblogic-Image beruhen, dessen Basis ein Java Development Kit-(JDK-)Image ist. Letzteres basiert wiederum auf einem Oracle Linux-Image.

Docker-Registry

Docker-Images lassen sich mühelos erstellen und Entwickler schätzen an ihnen die Einfachheit und Portabilität. Allerdings stellte man auch schnell fest, dass die Verwaltung von Tausenden von Docker-Images eine ziemliche Herausforderung darstellt. Die Docker Registry ist die Lösung dieses Problems. Bei der Docker Registry handelt es sich um eine Standardmethode zum Speichern und Verteilen von Docker-Images. Die Registry ist ein Open-Source-basiertes Repository, das unter der permissiven Apache-Lizenz bereitgestellt wird.

Die Docker Registry verbessert auch die Zugriffskontrolle und Sicherheit der in ihrem Repository gespeicherten Docker-Images. Sie verwaltet die Verteilung von Images und lässt sich auch mit Workflows zur Anwendungsentwicklung integrieren. Entwickler können ihre eigene Docker Registry einrichten oder einen gehosteten Docker Registry-Service wie Docker Hub, die Oracle Container Registry oder die Azure Container Registry usw. verwenden.

Bei Docker Hub handelt es sich um eine gehostete Docker Registry, die von Docker verwaltet wird. Docker Hub verfügt über mehr als 100.000 Container-Images von Softwareanbietern, Open Source-Projekten und aus der Community. Docker Hub enthält Software und Anwendungen aus offiziellen Repositorys wie NGINX, Logstash, Apache HTTP, Grafana, MySQL, Ubuntu oder Oracle Linux.

Beim Starten eines Containers greift Docker standardmäßig automatisch auf das entsprechende Image aus dem öffentlichen Docker Hub zurück, wenn dies lokal nicht verfügbar ist. Darüber hinaus können Sie auch eigene Images erstellen und diese in ein öffentliches oder privates Docker Hub-Repository verschieben.

Abbildung 3: Screenshot der Docker Registry
Abbildung 3

Docker als Microservices-Laufzeit

Die Idee, monolithische Anwendungen in kleinere Microservices zu zerlegen, erregt derzeit bei Softwareentwicklern große Aufmerksamkeit.

Microservices werden unabhängig als Prozess bereitgestellt, verwenden leichte Protokolle, um miteinander zu kommunizieren, und jeder Dienst ist Eigentümer seiner Daten. Microservices verfolgen einen dezentralen Governance-Ansatz. Sie erfordern daher ein hohes Maß an Infrastrukturautomatisierung, automatisierte Tests, vollautomatisierte CD-Pipelines sowie kompetente und agile DevOps-Teams.

Über diesen Architekturstil wird immer noch viel diskutiert. Aber es wäre naiv, anzunehmen, dass eine Anwendung, die in Microservices zerlegt wurde, einfach als eine Reihe von Prozessen ausgeführt werden kann. So muss beispielsweise ein Microservice, um nur einige Anforderungen zu nennen, hostunabhängig und auf der Ebene des Betriebssystems isoliert sein. Er muss außerdem innerhalb seiner Ressourcengrenzen ausgeführt, vergrößert oder verkleinert und im Fehlerfall neu gestartet werden. Zudem muss er über eine softwaredefinierte Netzwerkschicht erkannt und mit anderen Microservices vernetzt werden.

Deswegen stellt die Ausführung eines Microservice in einem Docker-Container einen hervorragenden Ausgangspunkt dar, um die meisten dieser Ziele zu erreichen.

Docker – zwei Schlüsseldimensionen

Docker verändert die Art und Weise, wie wir Software erstellen, versenden und ausführen im Hinblick auf zwei verschiedene Dimensionen:

  • Es verbessert den Prozess, um Anwendungen zuverlässig von der Entwicklung in die Produktion zu führen.
  • Es bietet ein Standard-Image-Format für die Verlagerung von On-Premises in die Cloud.

Beide Dimensionen werden in den folgenden Abschnitten näher erläutert.

Docker-Image – von der Entwicklung zur Produktion

Das Erstellen eines Docker-Images mit all seinen Abhängigkeiten löst das Problem, dass Anwendungen manchmal nicht überall so zuverlässig laufen wie auf der Umgebung des Entwicklers. Die Schlüsselidee dabei ist, dass ein Docker-Image automatisch von einer Erstellungs-Pipeline aus einem Quellcode-Repository wie Git erstellt und zunächst in einer Entwicklungsumgebung getestet wird. Dieses unveränderliche Image wird dann in einer Docker Registry gespeichert.

Wie in Abbildung 4 dargestellt, wird dasselbe Image für weitere Belastungs-, Integrations-, Abnahme- oder andere Tests verwendet. In jeder Umgebung wird dasselbe Image verwendet. Kleine aber notwendige umgebungsspezifische Unterschiede, wie z. B. eine JDBC-URL für eine Produktionsdatenbank, können als Umgebungsvariablen oder Dateien in den Container eingegeben werden.

Screenshot eines Docker-Images
Abbildung 4

Statistiken zeigen, dass 65 % aller aktuellen Docker-Anwendungsfälle in der Entwicklung sind und 48 % Docker für kontinuierliche Integration verwenden.

Docker-Cloud

Docker hat die Nutzung von Public Clouds geändert: Auf der einen Seite gibt es mit einem Docker-Image zum ersten Mal in der Geschichte ein gemeinsames Packageformat, das On-Premise und auf jedem großen Cloud-Provider ausgeführt werden kann. Docker-Container laufen auf einem Laptop genauso wie in der Oracle Cloud.

Da Docker-Container auf allen wichtigen Public Clouds ausgeführt werden können, stellen sie andererseits auch einen wichtigen Beitrag dar, um einen seit langem bestehenden Vorbehalt gegenüber Public Clouds zu überwinden: die Anbieterbindung. Jeder größere Cloud-Leistungserbringer bietet jetzt Docker als PaaS an.

Docker-Versionen – Ausgereifte Basistechnologie

Das Veröffentlichungstempo von Docker ist wesentlich schneller als der Veröffentlichungszyklus herkömmlicher Unternehmenssoftware. Manchmal wirft das bloße Tempo der Docker-Veröffentlichungen sowie die Neuartigkeit des Docker-Projekts Bedenken hinsichtlich seiner Sicherheit und Stabilität auf.

Docker und seine Befehlszeile sowie der Docker-Daemon, seine API und Tools wie Docker Swarm, Docker Machine und Docker Compose wurden tatsächlich erst in den letzten drei Jahren entwickelt. Doch die zugrunde liegenden Kernelfunktionen stehen nun seit fast einem Jahrzehnt in jedem Linux-Kernel zu Verfügung.

Ein berühmtes Beispiel für einen frühen Anwender der Containertechnologie ist Google. Google verwendete Linux-Container bereits, bevor es Docker gab. Außerdem führt Google alles in einem Container aus. Es wird geschätzt, dass Google mehrere Milliarden Container pro Woche auf den Markt bringt.

Die Geschichte von Cgroups und Namespaces

Die zugrunde liegenden Linux-Kernelfunktionen, die Docker verwendet, sind Cgroups und Namespaces. Cgroups wurden 2008 in den Linux-Kernel eingeführt und basieren auf der Arbeit von Google-Entwicklern1. Cgroups machen die Ressourcennutzung einer Reihe von Betriebssystemprozessen aus und begrenzen diese.

Der Linux-Kernel verwendet Namespaces, um die Systemressourcen von Prozessen voneinander zu isolieren. Der erste Namespace, also der Mount-Namespace, wurde bereits 2002 eingeführt.2

Container-Cloud-Services

Im ersten Teil dieses Artikels wurden einige wichtige Konzepte von Docker erläutert. In einer Produktionsumgebung reicht es jedoch nicht aus, eine Anwendung einfach in einem Docker-Container auszuführen.

Zum Einrichten und Ausführen einer Produktionsumgebung ist wiederum Hardware erforderlich, um die Container auszuführen. Software wie Docker sowie die Repositorys und Cluster Manager müssen installiert, aktualisiert und gepatcht werden. Wenn mehrere Docker-Container über verschiedene Hosts hinweg kommunizieren sollen, muss ein Netzwerk erstellt werden. Containercluster sollten bei Fehlschlägen neu gestartet werden. Darüber hinaus sollte eine Reihe von miteinander vernetzten Containern so einfach bereitgestellt werden können, als ob es sich dabei um eine einzelne logische Anwendungsinstanz handelt. Ein Beispiel dafür könnten ein Load Balancer, einige Webserver, einige Oracle WebLogic Server-Instanzen mit einem Administrationsserver, ein verwalteter Server und eine Datenbank sein. Zum Verwalten und Skalieren von Containeranwendungen ist ein Orchestrierungssystem für Container wie Kubernetes oder Docker Swarm erforderlich. Das Bereitstellen, Verwalten und Ausführen von Orchestrierungssystemen wie Kubernetes kann jedoch schwierig und zeitaufwändig sein.

Damit Entwickler einfacher und effizienter containerisierte Anwendungen erstellen können, stellen Cloud-Anbieter Container-Cloud-Services oder Containers as a Service (CaaS) zur Verfügung. Mithilfe von Container-Cloud-Services können Entwickler und Betriebsteams den Lebenszyklus von Containern auf automatisierte Weise optimieren und verwalten. Diese Orchestrierungsdienste, die normalerweise mit Kubernetes erstellt werden, erleichtern DevOps-Teams die Verwaltung, Ausführung und Skalierung von Containeranwendungen. Die Oracle Container Engine for Kubernetes und der Azure Kubernetes Service sind zwei Beispiele für beliebte verwaltete Cloud-Services zur Container-Orchestrierung.

Die Oracle Container Engine for Kubernetes ist ein vollständig verwalteter, skalierbarer und hochverfügbarer Dienst, mit dem Sie Ihre containerisierten Anwendungen in der Cloud bereitstellen können. Verwenden Sie die Container Engine for Kubernetes (manchmal einfach als OKE abgekürzt), wenn Ihr Entwicklungsteam native Cloud-Anwendungen zuverlässig erstellen, bereitstellen und verwalten möchte.

Docker-Images von Oracle

Container können von beliebigen Entwicklern verpackt werden. Einzelpersonen in der Softwarebranche unterscheiden Entwickler oft nach Spezialisierungen – Frontend, Backend oder irgendwo dazwischen. Obwohl man meist Backend-Entwickler sieht, die Container paketieren, kann jeder, der mit den grundlegenden CaaS-Konzepten vertraut ist, in diesem speziellen Bereich des Softwareentwicklungszyklus erfolgreich sein. Bevor Sie die Abhängigkeiten Ihrer Anwendung verpacken können, besuchen Sie developer.oracle.com und machen Sie sich mit Tools vertraut, mit denen Sie Ihre Anwendung oder Ihr Programm erstellen können.

Im Folgenden finden Sie einige Quellen zum Abrufen oder Erstellen von Docker-Images für Produkte von Oracle. Das Oracle GitHub-Repository für Docker-Images enthält Docker-Dateien und Beispiele zum Erstellen von Docker-Images für kommerzielle Produkte von Oracle sowie für von Oracle gesponserte Open Source-Projekte.

Praktische Übungen zu Docker – Containerisierte Entwicklung mit Docker

Referenzen

  1. Cgroups (Wikipedia)
  2. Linux Namespaces (Wikipedia)