Die Softwareentwicklung ist dynamisch und entwickelt sich ständig weiter. Moderne Lösungen sind gefragt, um aufkommenden Herausforderungen zu begegnen. Eine solche Lösung ist Docker – eine Open-Source Technologie, die zur Containerisierung von Anwendungen eingesetzt wird. Einige Anwendungsgebiete sind zum Beispiel:
- CI/CD-Pipelines: Docker kann die Konsistenz in Continuous Integration und Continuous Deployment (CI/CD) Prozessen gewährleisten. Jeder Build läuft in einem sauberen, isolierten Container und nicht in einer potenziell kontaminierten oder inkonsistenten Umgebung.
- Microservices: Docker ist ideal für eine Microservices-Architektur, da jeder Microservice in einem separaten Container laufen kann. Dies erleichtert die Skalierung, Aktualisierung und Isolierung einzelner Services.
- Testautomatisierung: Docker kann dazu verwendet werden, Testumgebungen aufzubauen. Ein Test kann in einem Container ausgeführt werden, der genau die Produktionsumgebung repliziert. Damit wird sichergestellt, dass Tests unter den gleichen Bedingungen durchgeführt werden.
- Anwendungsisolierung: Docker ermöglicht es, mehrere Anwendungen auf einem einzigen System zu betreiben, ohne dass sich diese gegenseitig beeinflussen. Jeder Container läuft isoliert und hat seine eigenen Prozesse, Netzwerke und Dateisysteme.
- Software-Verteilung: Docker kann verwendet werden, um Software und ihre Abhängigkeiten zu verpacken. Dies erleichtert den Auslieferungsprozess, da die Endbenutzer lediglich das Image herunterladen und starten müssen, ohne sich Gedanken über die Installation von Abhängigkeiten machen zu müssen.
Im Folgenden führen wir praktisch in einige grundlegende Konzepte von Docker ein und betrachten im Anschluss einen beispielhaften Anwendungsfall.
Einführung
Docker besteht seit 2013 und ist eine revolutionäre Technologie, die es erlaubt, Anwendungen in isolierten Container-Umgebungen zu betreiben. Diese Container beinhalten alle benötigten Ressourcen, sodass sichergestellt ist, dass die Anwendung in jeder Umgebung reibungslos läuft – unabhängig von den spezifischen Einstellungen des zugrundeliegenden Systems.
Zwei wesentliche Konzepte von Docker sind Images und Container.
Ein Image ist eine schreibgeschütztes Artefakt mit Anweisungen zur Erstellung eines Containers. Es beinhaltet alle nötigen Informationen wie Betriebssystem, Software, Anwendungscodes und Umgebungseinstellungen, um eine Anwendung auszuführen. Images werden erstellt durch Dockerfiles, welche eine Docker-eigene Programmiersprache nutzen, um die Container zu definieren und Code innerhalb des Containers zur Bauzeit auszuführen.
Ein Container hingegen ist die Laufzeitinstanz eines Images. Ein Container ist im Grunde die ausführbare Version des Images, das heißt, es wird gestartet (oder „läuft“), wenn das Image ausgeführt wird. Jeder Container hat seine eigene isolierte Umgebung und läuft unabhängig von anderen Containern, selbst wenn sie vom gleichen Image erstellt wurden.
Das erste Image – der erste Container
Zunächst muss Docker auf dem System installiert sein, was in der offiziellen Docker Dokumentation für Linux, Windows und Mac im Detail beschrieben ist.
Nun wollen wir, basierend auf einem Dockerfile, ein Image bauen und anschließend einen Container mit diesem Image starten. Das Dockerfile könnte folgendermaßen aussehen:
# Nutzen des offiziellen Python Images als Basis
FROM python:3.8
# Setzen des Arbeitsverzeichnisses im Docker-Container
WORKDIR /app
# Installieren von Jupyter
RUN pip install jupyter
# Exposen des Ports 8888 für den Zugang zum Jupyter Notebook
EXPOSE 8888
# Starten des Jupyter Notebooks beim Start des Containers
CMD ["jupyter", "notebook", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root"]
Das Image können wir nun mit
docker build -t my_jupyter_image PATH/TO/DOCKERFILE
bauen und schließlich den Container mit
docker run -p 8888:8888 my_jupyter_image
starten. Da der Port 8888 exposed ist, können wir einen Browser öffnen und über „localhost:8888“ bzw. „127.0.0.1:8888“ auf Jupyter im Container zugreifen und es verwenden!
Diese Anleitung zeigt ein erstes Beispiel. Es wäre jetzt z.B. auch möglich einen bestimmten Ordner als Volume in den Container zu mounten. Außerdem gibt es für Jupyter auch bereits vor-konfigurierte Images auf Dockerhub (einer öffentlichen Registry für Docker-Images).
Ein praktischer Anwendungsfall: Microservices-Architektur
Ein beispielhafter Einsatzbereich von Docker ist die Unterstützung einer Microservices-Architektur. Angenommen, ein Unternehmen betreibt eine komplexe Webanwendung, die aus mehreren kleineren Diensten besteht – den sogenannten Microservices. Jeder dieser Dienste hat eine spezifische Aufgabe, beispielsweise das Nutzermanagement, die Bestellverwaltung oder das Bezahlwesen.
In einer traditionellen Umgebung würde ein Update eines dieser Dienste oft eine umfangreiche Abstimmung und möglicherweise sogar eine Downtime für die gesamte Anwendung erfordern. Mit Microservices oder eben Docker ändert sich das: Jeder Microservice kann in einem eigenen Docker-Container verpackt (containerisiert) werden.
Das ist in Abbildung 3 veranschaulicht. Jeder Microservice läuft in seinem eigenen Docker-Container, der unabhängig skaliert, gebaut, deployed, aktualisiert und debugged werden kann. Jeder Container wiederum basiert auf einem eigenem Image (und Dockerfile), sodass auch hier eine Isolation der einzelnen Microservices vorliegt.
Vorteile durch Docker
Durch den Einsatz von Docker ergeben sich in unserem Beispiel mehrere Vorteile:
- Reibungslose Updates: Da jeder Dienst in einem separaten Container läuft, kann er unabhängig von den anderen aktualisiert werden. Dies minimiert das Risiko, dass ein Update den Betrieb der gesamten Anwendung stört.
- Skalierbarkeit: Docker-Container sind leichtgewichtig und benötigen nur die Ressourcen der Anwendung selbst. Dadurch können problemlos mehr Instanzen eines bestimmten Dienstes gestartet werden, wenn die Nachfrage steigt.
- Sicherheit: Ein weiterer Vorteil von Docker ist die Isolation. Selbst wenn ein Container kompromittiert wird, bleibt der Schaden auf diesen Container begrenzt, da er von den anderen Containern getrennt ist.
- Effizienz in der Entwicklung: Entwickler können die gleichen Docker-Container auf ihren lokalen Maschinen, auf Entwicklungs‑, Test- oder Produktionsumgebungen laufen lassen. Das vereinfacht den Testprozess und eliminiert Probleme à la „Es hat auf meinem Rechner funktioniert“. Außerdem sind Automatismen (z.B. Tests) aufgrund dieser Reproduzierbarkeit einfacher in Pipelines integrierbar.
Fazit
Docker ist eine äußerst nützliche Technologie, die den Prozess der Softwareentwicklung und ‑bereitstellung erheblich vereinfacht. Durch die Möglichkeit der Containerisierung eröffnet Docker neue Wege, effizient und skalierbar zu arbeiten, Sicherheitsrisiken zu minimieren und eine gleichbleibende Qualität ihrer Anwendungen zu gewährleisten.
Darüber hinaus bildet Docker die Grundlage für viele moderne Technologien, Tools und Frameworks. Technologien wie Kubernetes, die das Orchestrieren von Containern in großem Maßstab ermöglichen und Konzepte wie Cloud-native Entwicklung, die die Skalierbarkeit und Agilität von Anwendungen verbessern, sind auf Docker aufgebaut und nutzen seine Möglichkeiten zur Containerisierung.
Unabhängig von der Art der zu entwickelnden Software oder den spezifischen Anforderungen eines Projekts, bietet Docker eine robuste und flexible Lösung, die dazu beiträgt, die Bereitstellung und das Management von Anwendungen zu optimieren.
Seit seiner Einführung im Jahr 2013 hat Docker kontinuierlich an Popularität gewonnen und ist heute ein unverzichtbares Werkzeug in der modernen Softwareentwicklung und ‑betrieb. Mit seiner Hilfe können Entwickler und Betriebsteams besser zusammenarbeiten, was letztlich zu hochwertigeren Produkten führt.
Lesen Sie hier mehr über Lösungen im Bereich Cloud Enablement oder besuchen Sie eines unserer kostenlosen Webinare.