Adrian Mouat ist Chief Scientist bei Container Solutions – einem europaweit vertretenen Serviceunternehmen, das sich auf Docker und Mesos spezialisiert hat. Zuvor war er Anwendungsberater bei EPCC, das zur University of Edinburgh gehört.
Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+: www.dpunkt.de/plus |
Software entwickeln und deployen mit Containern
Adrian Mouat
Übersetzung: Thomas Demmig
Überarbeitung und Aktualisierung: Peter Roßbach
Lektorat: René Schönfeldt
Copy-Editing: Annette Schwarz, Ditzingen
Satz: III-satz, www.drei-satz.de
Herstellung: Nadine Thiele
Umschlaggestaltung: Helmut Kraus, www.exclam.de
Druck und Bindung: M.P. Media-Print Informationstechnologie GmbH, Paderborn
Bibliografische Information der Deutschen Nationalbibliothek
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.
ISBN:
Buch 978-3-86490-384-7
PDF 978-3-96088-036-3
ePub 978-3-96088-037-0
mobi 978-3-96088-038-7
1. Auflage 2016
Copyright © 2016 dpunkt.verlag GmbH
Wieblinger Weg 17
69123 Heidelberg
Authorized German translation of the English edition of Using Docker ISBN 9781491915769
© 2016 Adrian Mouat. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same.
Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.
Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.
Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buches stehen.
5 4 3 2 1 0
Für alle, die es versuchen – ob mit oder ohne Erfolg
Build, Ship and Run,
Any App,
Anywhere
Docker Mantra
Container-Technologie, Clouds, Microservices und die Anforderungen an Zuverlässigkeit und schnelle Reaktion verändern gerade die IT-Welt. Information werden als eigenständiger Wert gehandelt. Diese Entwicklung nimmt seit 20 Jahren durch das Internet ihren Lauf. Erst belächelt, dann immer schneller verwendet, ist es heute essenzieller Bestandteil des Lebens in unserer Gesellschaft. Nur durch die gigantischen Server-Farmen im Hintergrund und die Bereitstellung des Betriebsökosystems, ist das möglich. Immer leistungsfähigere Soft- und Hardware ist im Einsatz.
Ende 2013 entdeckte ich Docker und hatte ein Schlüsselerlebnis: endlich, nach fast 30 Jahren IT, eine simple Lösung, um komplexe Software einfach in kleine Containern zu verpacken, sinnvoll zu kombinieren und dann auch noch zwischen Maschinen austauschbar zu machen. Nach all den vorangegangenen Erfahrungen – manuell, mit Skripten, Packages, Betriebssystem-Images, Konfigurationsmanagement, kryptischer Isolierung von Prozessen – nun eine einfache Lösung! Docker vereint großartig die bestehende Linux-Virtualisierung, Ressourcen-Isolierung, Sicherheits-Features, Netzwerke und Storage-Lösungen in einem einfachen Ansatz.
Die Verbreitung von Docker ist die schnellste Technologie Adaption, die ich je beobachtet habe. Ende 2014 auf der DockerCon in Amsterdam, lernte ich Adrian Mouat und viele andere Docker-Enthusiasten kennen und schätzen. Zu diesem Zeitpunkt war in jedem Gespräch deutlich zu spüren, dass Docker unsere IT-Welt unumkehrbar veränderte und noch mehr zu erwarten war. Seit diesem Zeitpunkt promote ich Container-Technologien des Docker-Ökosystems, gebe Trainings, organisiere Meetings und Konferenzen, schreibe Artikel und lerne jeden Tag etwas Neues über IT-Infrastruktur.
Ein Buch über Docker zu schreiben – eine Technologie, die sich enorm schnell verändert – ist mutig. Adrian ist dies 2015 vorbildlich gelungen. Anschaulich beschreibt er die Grundlagen von Docker, das sich darum entwickelnde Öko-system sowie aktuelle Trends. Mit einem durchgängigen Beispiel bietet er einen praktischen Einstieg und zeigt, wie Sie erste Schritte mit Docker gehen.
Die Idee einer deutschen Übersetzung betrachtete ich anfangs allerdings skeptisch: Konnte sie überhaupt die zahlreichen Neuerungen des Docker-Ökosystems seit Erscheinen des englischen Originals angemessen darstellen? Zwischen Version 1.8 und der heute aktuellen Version 1.12 von Docker gab es ja einige Erweiterungen und Veränderungen, z.B. was Netzwerke und die Orchestrierung von Containern angeht.
Nachdem ich mich im Auftrag des Verlages dann im Detail mit dem Manuskript beschäftigte, war ich allerdings erst erleichtert und dann begeistert: Adrians Text war so angelegt, dass eigentlich nichts falsch oder komplett umzubauen war. Nur an wenigen Stellen mussten Textstellen leicht umformuliert sowie Hinweise auf Neuerungen hinzugefügt werden, damit das Buch auch weiterhin einen gelungenen praktischen Einstieg in die Technologie von Docker bietet. Die Grundlagen von Docker sind stabile und müssen erlernt werden. Ohne gute Kenntnisse der Docker Basics kann man die großartigen Neuerungen in den Bereichen Netzwerk, Storage, Clustering und Betrieb von Docker nicht wirklich sicher nutzen.
Lieben Dank an den Übersetzer Thomas Demmig sowie René Schönfeldt und sein Verlagsteam, dass sie mir die Chance gegeben haben, Teil dieses Projektes zu sein.
Viel Spaß beim Lesen, Probieren, Übertragen und Einsetzen von Docker!
August 2016
Peter Roßbach
Container sind eine schlanke und portable Möglichkeit, beliebige Anwendungen und ihre Abhängigkeiten zu verpacken und transportabel zu machen.
Wenn man das so aufschreibt, klingt es ziemlich trocken und langweilig. Aber die Verbesserungen im Prozess, die durch Container möglich werden, sind das genaue Gegenteil davon – korrekt eingesetzt können Container wegweisend sein. Die Verlockungen der dadurch möglich werdenden Architekturen und Arbeitsabläufe sind so überzeugend, dass man glauben mag, spätestens in einem Jahr hat sich in jeder größeren IT-Firma der Status von »Docker? Nie gehört!« zu »Klar, schauen wir uns gerade an und setzen wir auch schon probehalber ein« geändert hat.
Der Aufstieg von Docker ist erstaunlich. Ich kann mich an keine Technologie erinnern, die so schnell so tiefgreifende Auswirkungen auf die IT-Branche hatte. Dieses Buch ist mein Versuch, Ihnen zu zeigen, warum Container so wichtig sind, was es Ihnen bringt, Ihre Umgebung zu containerisieren, und – am wichtigsten – wie Sie das erreichen.
Dieses Buch versucht, Docker ganzheitlich anzugehen, die Gründe für dessen Einsatz zu erklären und zu zeigen, wie man es nutzt und in einen Softwareentwicklungsworkflow integriert. Es behandelt den gesamten Software-Lifecycle – von der Entwicklung über die Produktion bis zur Wartung.
Ich habe versucht, möglichst wenige Annahmen über Sie als Leser zu treffen, und gehe nur davon aus, dass Sie grundlegende Kenntnisse von Linux und der Softwareentwicklung im Allgemeinen haben. Zielgruppe sind vor allem Softwareentwickler, Administratoren und Systemverwalter (insbesondere solche, die einen DevOps-Ansatz verfolgen wollen). Aber auch technisch affine Manager und andere Interessierte sollten ebenfalls Gewinn aus diesem Buch ziehen.
Ich befand mich in der glücklichen Lage, Docker kennenzulernen und einzusetzen, während es noch ganz am Anfang seines kometenhaften Aufstiegs stand. Als sich die Gelegenheit ergab, dieses Buch zu schreiben, ergriff ich sie mit beiden Händen. Wenn mein Geschreibsel einem von Ihnen dabei hilft, die Containerisierungs-Community zu verstehen und das Beste daraus zu machen, dann habe ich mehr erreicht als in all den Jahren der Softwareentwicklung zuvor.
Ich hoffe wirklich, dass Ihnen das Lesen dieses Buches Spaß macht und es Ihnen dabei hilft, beim Einsatz von Docker in Ihrer Umgebung vorwärtszukommen.
Dieses Buch ist in drei Abschnitte unterteilt:
Teil I beginnt mit der Erklärung, was Container sind und warum Sie an ihnen interessiert sein sollten. Dann folgt ein Tutorial-Kapitel mit den ersten Schritten beim Einsatz von Docker. Der Abschnitt endet mit einem langen Kapitel mit den zugrunde liegenden Konzepten und Technologien, die hinter Docker stecken, einschließlich eines Überblicks über die diversen Docker-Befehle.
Teil II erklärt, wie Sie Docker in einem Softwareentwicklungs-Lifecycle einsetzen. Zuerst wird gezeigt, wie Sie eine Entwicklungsumgebung einrichten, bevor Sie eine einfache Webanwendung erstellen, die für den Rest dieses Abschnitts als Beispiel dient. Die Kapitel drehen sich um Entwicklung, Testen und Integration, aber auch darum, wie Sie Container ausrollen und ein Produktivsystem effektiv überwachen und protokollieren.
In Teil III geht es um die fortgeschrittenen Details und die Tools und Techniken, die Sie brauchen, um Multihost-Cluster mit Docker-Containern sicher und zuverlässig zu betreiben. Haben Sie Docker schon im Einsatz und müssen herausfinden, wie Sie damit wachsen können oder Netzwerk- und Sicherheitsprobleme lösen, ist das Ihr Abschnitt.
Die folgenden typografischen Konventionen werden in diesem Buch genutzt:
Kursiv
für neue Begriffe, URLs, E-Mail-Adressen, Dateinamen und Dateierweiterungen
Nichtproportionalschrift
für Programmlistings, aber auch für Codefragmente in Absätzen, wie zum Beispiel Variablen- oder Funktionsnamen, Datenbanken, Datentypen, Umgebungsvariablen, Anweisungen und Schlüsselwörter
fette Nichtproportionalschrift
für Befehle und anderen Text, der genau so vom Benutzer eingegeben werden sollte
kursive Nichtproportionalschrift
für Text, der vom Benutzer durch eigene Werte ersetzt werden sollte
Dieses Symbol steht für einen Tipp oder Vorschlag.
Dieses Symbol steht für einen allgemeinen Hinweis.
Dieses Symbol steht für eine Warnung oder Vorsichtsmaßnahme.
Zusätzliches Material (Codebeispiele, Übungen und so weiter) finden Sie (auf Englisch) zum Herunterladen auf https://github.com/using-docker.
Dieses Buch soll Ihnen bei der Arbeit helfen. Die Codebeispiele in diesem Buch können Sie im Allgemeinen in Ihren Programmen und Ihrer Dokumentation nutzen. Sie müssen uns nicht um Erlaubnis fragen, sofern Sie nicht einen signifikanten Anteil des Codes veröffentlichen. So erfordert zum Beispiel das Schreiben eines Programms, das diverse Codeschnipsel aus diesem Buch nutzt, keine Erlaubnis. Das Verkaufen oder Bereitstellen einer CD-ROM mit Beispielen aus diesem Buch benötigt hingegen eine Erlaubnis. Beantworten Sie eine Frage, indem Sie dieses Buch zitieren und Beispielcode daraus nutzen, benötigen Sie keine Erlaubnis. Übernehmen Sie einen deutlichen Teil des Beispielcodes für Ihre Produktdokumentation, müssen Sie dieses Vorhaben von uns genehmigen lassen.
Wir freuen uns über eine Quellenangabe, verlangen sie aber nicht unbedingt. Zu einer Quellenangabe gehören normalerweise Titel, Autor, Verlag und ISBN (zum Beispiel: »Adrian Mouat: Docker – Software entwickeln und deployen mit Containern. dpunkt.verlag 2016, ISBN 978-3-86490-384-7«).
Wenn Sie das Gefühl haben, dass Ihr Einsatz der Codebeispiele über die Grenzen des Erlaubten hinausgeht, können Sie uns über hallo@dpunkt.de erreichen.
Ich bin für all die Hilfe, Ratschläge und Kritik unglaublich dankbar, die ich während des Schreibens dieses Buches erhalten habe. Wenn ich einen Namen in der folgenden Liste vergessen habe, bitte ich um Verzeihung – ich wusste alle Beiträge zu schätzen, auch wenn ich nicht darauf reagiert habe.
Für allgemeines Feedback möchte ich mich bei Ally Hume, Tom Sugden, Lukasz Guminski, Tilaye Alemu, Sebastien Goasguen, Maxim Belooussov, Michael Boelen, Ksenia Burlachenko, Carlos Sanchez, Daniel Bryant, Christoffer Holmstedt, Mike Rathbun, Fabrizio Soppelsa, Yung-Jin Hu, Jouni Miikki und Dale Bewley bedanken.
Mein Dank für technische Diskussionen und Erläuterungen zu bestimmten Technologien geht an Andrew Kennedy, Peter White, Alex Pollitt, Fintan Ryan, Shaun Crampton, Spike Curtis, Alexis Richardson, Ilya Dmitrichenko, Casey Bisson, Thijs Schnitger, Sheng Liang, Timo Derstappen, Puja Abbassi, Alexander Larsson und Kelsey Hightower. Für die Erlaubnis, monsterid.js nutzen zu dürfen, bedanke ich mich bei Kevin Gaudin.
Ein großer Dank für all die Hilfe geht auch an die O’Reilly-Mitarbeiter, insbesondere an meinen Lektor Brian Anderson und an Meghan Blanchette, die das Ganze erst ins Rollen gebracht hat.
Diogo Mónica und Mark Coleman – vielen Dank an euch beide für das Beantworten meines Hilferufs in letzter Sekunde.
Zwei Firmen sollen besonders hervorgehoben werden: Container Solutions und CloudSoft. Jamie Dobson und Container Solutions sorgten dafür, dass ich mit Bloggen und Vorträgen beschäftigt war, und brachten mich mit vielen Leuten zusammen, die Einfluss auf dieses Buch hatten. CloudSoft erlaubten es mir freundlicherweise, in ihren Räumen an diesem Buch zu arbeiten. Zudem organisierten sie das Edinburgh Docker Meetup, das ebenfalls sehr wichtig für mich war.
Dafür, dass Ihr mein Gejammer über dieses Buch und meine Obsession ausgehalten habt, möchte ich mich bei all meinen Freunden und meiner Familie bedanken – Ihr wisst, wen ich meine (und werdet diese Zeilen sehr wahrscheinlich sowieso nicht lesen).
Schließlich möchte ich den DJs von BBC 6 Music danken, die den Soundtrack zu diesem Buch geliefert haben – unter anderem Lauren Laverne, Radcliffe and Maconie, Shaun Keaveny und Iggy Pop.
Teil I Hintergrund und Grundlagen
1 Was Container sind und warum man sie nutzt
1.1 Container versus VMs
1.2 Docker und Container
1.3 Eine Geschichte von Docker
1.4 Plugins und Plumbing
1.5 64-Bit-Linux
2 Installation
2.1 Docker auf Linux installieren
2.1.1 SELinux im Permissive Mode ausführen
2.1.2 Ohne sudo starten
2.2 Docker auf Mac OS oder Windows installieren
2.3 Ein schneller Check
3 Erste Schritte
3.1 Ihr erstes Image ausführen
3.2 Die grundlegenden Befehle
3.3 Images aus Dockerfiles erstellen
3.4 Mit Registries arbeiten
3.4.1 Private Repositories
3.5 Das offizielle Redis-Image verwenden
3.6 Zusammenfassung
4 Grundlagen von Docker
4.1 Die Architektur von Docker
4.1.1 Zugrunde liegende Technologien
4.1.2 Zugehörige Technologien
4.1.3 Docker Hosting
4.2 Wie Images gebaut werden
4.2.1 Der Build Context
4.2.2 Imageschichten
4.2.3 Caching
4.2.4 Basis-Images
4.2.5 Anweisungen im Dockerfile
4.3 Container mit der Außenwelt verbinden
4.4 Container verlinken
4.5 Daten mit Volumes und Datencontainern verwalten
4.5.1 Daten gemeinsam nutzen
4.5.2 Datencontainer
4.6 Häufig eingesetzte Docker-Befehle
4.6.1 Der Befehl run
4.6.2 Container verwalten
4.6.3 Docker-Info
4.6.4 Container-Info
4.6.5 Arbeit mit Images
4.6.6 Die Registry verwenden
4.7 Zusammenfassung
Teil II Der Software-Lebenszyklus mit Docker
5 Docker in der Entwicklung einsetzen
5.1 Sag »Hallo Welt!«
5.2 Mit Compose automatisieren
5.2.1 Der Compose-Workflow
5.3 Zusammenfassung
6 Eine einfache Webanwendung erstellen
6.1 Eine einfache Webseite erstellen
6.2 Auf vorhandene Images zurückgreifen
6.3 Caching ergänzen
6.4 Microservices
6.5 Zusammenfassung
7 Bereitstellen von Images
7.1 Namensgebung für Images und Repositories
7.2 Der Docker Hub
7.3 Automatisierte Builds
7.4 Private Distribution
7.4.1 Eine eigene Registry betreiben
7.4.2 Kommerzielle Registries
7.5 Die Imagegröße verringern
7.6 Herkunft eines Image
7.7 Zusammenfassung
8 Continuous Integration und Testen mit Docker
8.1 identidock mit Unit-Tests versehen
8.2 Einen Jenkins-Container erstellen
8.2.1 Builds triggern
8.3 Das Image pushen
8.3.1 Sinnvolles Taggen
8.3.2 Staging und Produktion
8.3.3 Image Sprawl
8.3.4 Jenkins Slaves durch Docker betreiben
8.4 Backups für Jenkins
8.5 Gehostete CI-Lösungen
8.6 Testen und Microservices
8.6.1 Im Produktivumfeld testen
8.7 Zusammenfassung
9 Container deployen
9.1 Ressourcen mit Docker Machine aufsetzen
9.2 Einen Proxy verwenden
9.3 Ausführungsoptionen
9.3.1 Shell-Skripten
9.3.2 Einen Process Manager einsetzen (oder systemd, sie alle zu knechten)
9.3.3 Ein Tool zum Configuration Management einsetzen
9.4 Host-Konfiguration
9.4.1 Ein Betriebssystem wählen
9.4.2 Einen Storage-Treiber wählen
9.5 Spezialisierte Hosting-Möglichkeiten
9.5.1 Triton
9.5.2 Google Container Engine
9.5.3 Amazon EC2 Container Service
9.5.4 Giant Swarm
9.6 Persistente Daten und Produktivcontainer
9.7 Gemeinsame Geheimnisse
9.7.1 Geheimnisse im Image ablegen
9.7.2 Geheimnisse in Umgebungsvariablen übergeben
9.7.3 Geheimnisse in Volumes übergeben
9.7.4 Einen Key/Value-Store einsetzen
9.8 Vernetzen
9.9 Produktiv-Registry
9.10 Continuous Deployment/Delivery
9.11 Zusammenfassung
10 Protokollieren und Überwachen
10.1 Protokollieren
10.1.1 Standard-Logging von Docker
10.1.2 Logs zusammenfassen
10.1.3 Mit ELK loggen
10.1.4 Docker-Logging mit syslog
10.1.5 Logs aus Dateien auslesen
10.2 Überwachen und Benachrichtigen
10.2.1 Mit den Docker-Tools überwachen
10.2.2 cAdvisor
10.2.3 Cluster-Lösungen
10.3 Kommerzielle Monitoring- und Logging-Lösungen
10.4 Zusammenfassung
Teil III Tools und Techniken
11 Vernetzung und Service Discovery
11.1 Ambassadors
11.2 Service Discovery
11.2.1 etcd
11.2.2 SkyDNS
11.2.3 Consul
11.2.4 Registrieren
11.2.5 Andere Lösungen
11.3 Networking-Optionen
11.3.1 Bridge
11.3.2 Host
11.3.3 Container
11.3.4 None
11.4 Neues Docker-Networking
11.4.1 Netzwerktypen und Plugins
11.5 Vernetzungslösungen
11.5.1 Overlay
11.5.2 Weave
11.5.3 Flannel
11.5.4 Project Calico
11.6 Zusammenfassung
12 Orchestrieren, Clustering und Verwaltung
12.1 Clustering- und Orchestrierungstools
12.1.1 Swarm
12.1.2 fleet
12.1.3 Kubernetes
12.1.4 Mesos und Marathon
12.2 Container-Management-Plattformen
12.2.1 Rancher
12.2.2 Clocker
12.2.3 Tutum
12.3 Zusammenfassung
13 Container sichern und beschränken
13.1 Worüber Sie sich Gedanken machen sollten
13.2 Verteidigung in der Tiefe
13.2.1 Least Privilege
13.3 identidock absichern
13.4 Container nach Host trennen
13.5 Updates anwenden
13.5.1 Nicht unterstützte Treiber vermeiden
13.6 Imageherkunft
13.6.1 Docker Digests
13.6.2 Docker Content Trust
13.6.3 Reproduzierbare und vertrauenswürdige Dockerfiles
13.7 Sicherheitstipps
13.7.1 Einen Benutzer setzen
13.7.2 Netzwerkzugriffe von Containern beschränken
13.7.3 setuid/setgid-Binaries entfernen
13.7.4 Den Speicher begrenzen
13.7.5 Den CPU-Einsatz beschränken
13.7.6 Neustarts begrenzen
13.7.7 Zugriffe auf die Dateisysteme begrenzen
13.7.8 Capabilities einschränken
13.7.9 Ressourcenbeschränkungen (ulimits) anwenden
13.8 Einen gehärteten Kernel ausführen
13.9 Linux Security Modules
13.9.1 SELinux
13.9.2 AppArmor
13.10 Auditing
13.11 Reaktion auf Zwischenfälle
13.12 Zukünftige Features
13.13 Zusammenfassung
Index
Im ersten Teil dieses Buches schauen wir uns zunächst an, was Container sind und warum sie sich so großer Beliebtheit erfreuen. Darauf folgt eine Einführung in Docker und die Schlüsselkonzepte, die Sie verstehen müssen, um Container wirklich sinnvoll einzusetzen.
Container ändern die Art und Weise, wie wir Software entwickeln, verteilen und laufen lassen, grundlegend. Entwickler können Software lokal bauen, weil sie wissen, dass sie auch woanders genauso laufen wird – sei es ein Rack in der ITAbteilung, der Laptop eines Anwenders oder ein Cluster in der Cloud. Administratoren können sich auf die Netzwerke, Ressourcen und die Uptime konzentrieren und müssen weniger Zeit mit dem Konfigurieren von Umgebungen und dem Kampf mit Systemabhängigkeiten verbringen. Der Einsatz von Containern wächst in der gesamten Branche mit einer erstaunlichen Geschwindigkeit – von den kleinsten Startups bis hin zu großen Unternehmen. Entwickler und Administratoren sollten davon ausgehen, dass sie innerhalb der nächsten Jahre Container regelmäßig einsetzen werden.
Container sind eine Verkapselung einer Anwendung und ihrer Abhängigkeiten. Auf den ersten Blick scheint das nur eine abgespeckte Version einer virtuellen Maschine (VM) zu sein – wie eine VM findet sich in einem Container eine isolierte Instanz eines Betriebssystems (Operating System, OS), mit dem wir Anwendungen laufen lassen können.
Container haben aber eine Reihe von Vorteilen, durch die Anwendungsfälle möglich werden, welche mit klassischen VMs schwierig oder unmöglich zu realisieren wären:
Container teilen sich Ressourcen mit dem Host-Betriebssystem, wodurch sie um eine wesentliche Größenordnung effizienter sind als virtuelle Maschinen. Container können im Bruchteil einer Sekunde gestartet und gestoppt werden. Anwendungen, die in Containern laufen, verursachen wenig bis gar keinen Overhead im Vergleich zu Anwendungen, die direkt auf dem Host-Betriebs-system gestartet werden.
Die Portierbarkeit von Containern besitzt das Potenzial, eine ganze Klasse von Bugs auszumerzen, die durch subtile Änderungen in der Laufzeitumgebung entstehen – sie könnte sogar die seit Anbeginn der Softwareentwicklung bestehende Litanei der Entwickler »Aber bei mir auf dem Rechner lief es doch!« beenden.
Die leichtgewichtige Natur von Containern sorgt dafür, dass Entwickler dutzende davon zur gleichen Zeit laufen lassen können, wodurch das Emulieren eines produktiv nutzbaren, verteilten Systems möglich wird. Administratoren können viel mehr Container auf einer einzelnen Host-Maschine laufen lassen, als dies mit VMs möglich wäre.
Container haben zudem Vorteile für Endanwender und Entwickler außerhalb des Bereitstellens in der Cloud. Benutzer können komplexe Anwendungen herunterladen und laufen lassen, ohne sich Stunden mit Konfiguration und Installation herumzuschlagen oder über die Änderungen Sorgen machen zu müssen, die am System notwendig wären. Umgekehrt brauchen sich die Entwickler solcher Anwendungen nicht mehr um solche Unterschiede in den Benutzerumgebungen und um eventuelle Abhängigkeiten Gedanken machen.
Wichtiger ist noch, dass sich die grundlegenden Ziele von VMs und Containern unterscheiden – eine VM ist dafür gedacht, eine fremde Umgebung vollständig zu emulieren, während ein Container Anwendungen portabel und in sich abgeschlossen macht.
Obwohl Container und VMs auf den ersten Blick sehr ähnlich wirken, gibt es einige wichtige Unterschiede, die sich am einfachsten über ein Schaubild aufzeigen lassen.
Abb. 1–1 Drei VMs laufen auf einem Host.
In Abbildung 1–1 sind drei Anwendungen zu sehen, die auf einem Host in getrennten VMs laufen. Der Hypervisor1 wird dazu benötigt, VMs zu erstellen und laufen zu lassen, den Zugriff auf das zugrunde liegende Betriebssystem und die Hardware zu steuern und bei Bedarf Systemaufrufe umzusetzen. Jede VM erfordert eine vollständige Kopie des Betriebssystems für sich, dazu die gewünschte Anwendung und alle Bibliotheken, die dafür notwendig sind.
Abb. 1–2 Drei Container laufen auf einem Host.
Im Gegensatz dazu sehen Sie in Abbildung 1–2, wie die gleichen drei Anwendungen in einem containerisierten System laufen könnten. Anders als bei VMs wird der Kernel des Host2 von den laufenden Containern gemeinsam genutzt. Sie sind also immer darauf beschränkt, den gleichen Kernel zu nutzen wie der Host. Die Anwendungen Y und Z verwenden die gleichen Bibliotheken, und sie müssen dafür keine identischen Kopien davon haben, sondern können auf die gleichen Dateien zugreifen. Die Container Engine ist für das Starten und Stoppen von Containern genauso verantwortlich wie der Hypervisor bei einer VM. Aber Prozesse, die innerhalb von Containern laufen, entsprechen nativen Prozessen auf dem Host, und es kommt kein Overhead durch die Ausführung des Hypervisors hinzu.
Sowohl VMs wie auch Container können genutzt werden, um Anwendungen von anderen Anwendungen zu isolieren, die auf dem gleichen Host laufen. VMs haben durch den Hypervisor eine weitgehendere Isolation, und es handelt sich bei ihnen um eine vertraute und durch Erfahrung gehärtete Technologie. Container sind verglichen damit recht neu, und viele Firmen scheuen sich, den Isolations-Features von Containern zu trauen, bevor diese ihr Können gezeigt haben. Aus diesem Grund findet man häufig Hybridsysteme mit Containern, die innerhalb von VMs laufen, um die Vorteile beider Technologien vereinen zu können.
Container sind ein altes Konzept. Schon seit Jahrzehnten gibt es in UNIX-Systemen den Befehl chroot, der eine einfache Form der Dateisystem-Isolation bietet. Seit 1998 gibt es in FreeBSD das Jail-Tool, welches das chroot-Sandboxing auf Prozesse erweitert. Solaris Zones boten 2001 eine recht vollständige Technologie zum Containerisieren, aber diese war auf Solaris OS beschränkt. Ebenfalls 2001 veröffentlichte Parallels Inc. (damals noch SWsoft) die kommerzielle Container-technologie Virtuozzo für Linux, deren Kern später (im Jahr 2005) als Open Source unter dem Namen OpenVZ bereitgestellt wurde.3 Dann startete Google die Entwicklung von CGroups für den Linux-Kernel und begann damit, seine Infrastruktur in Container zu verlagern. Das Linux Containers Project (LXC) wurde 2008 initiiert, und in ihm wurden (unter anderem) CGroups, Kernel-Namensräume und die chroot-Technologie zusammengeführt, um eine vollständige Containerisierungslösung zu bieten. 2013 lieferte Docker schließlich die fehlenden Teile für das Containerisierungspuzzle, und die Technologie begann, den Mainstream zu erreichen.
Docker nahm die bestehende Linux-Containertechnologie auf und verpackte und erweiterte sie in vielerlei Hinsicht – vor allem durch portable Images und eine benutzerfreundliche Schnittstelle –, um eine vollständige Lösung für das Erstellen und Verteilen von Containern zu schaffen. Die Docker-Plattform besteht vereinfacht gesagt aus zwei getrennten Komponenten: der Docker Engine, die für das Erstellen und Ausführen von Containern verantwortlich ist, sowie dem Docker Hub, einem Cloud Service, um Container-Images zu verteilen.
Die Docker Engine bietet eine schnelle und bequeme Schnittstelle für das Ausführen von Containern. Zuvor waren für das Laufenlassen eines Containers mit einer Technologie wie LXC umfangreiches Wissen und viel manuelle Arbeit nötig. Auf dem Docker Hub finden sich unglaublich viele frei verfügbare Container-Images zum Herunterladen, so dass Anwender schnell loslegen können und es vermeiden, Arbeit doppelt zu erledigen, die andere schon gemacht hatten. Zu weiteren Tools, die von Docker entwickelt wurden, gehören der Clustering Manager Swarm, die GUI Kitematic für die Arbeit mit Containern und das Befehlszeilentool Machine für die Erzeugung von Docker Hosts.
Durch das Bereitstellen der Docker Engine als Open Source konnte Docker eine große Community aufbauen und auf deren Hilfe bei Bugfixes und Verbesserungen zählen. Das massive Wachstum von Docker hat dazu geführt, dass es ein De-facto-Standard wurde, und das wiederum sorgte für Druck aus der Branche, einen unabhängigen, formalen Standard für die Runtime und das Format der Container zu entwickeln. 2015 schließlich wurde dafür die Open Container Initiative4 gegründet – eine Initiative, die von Docker, Microsoft, CoreOS und vielen weiteren wichtigen Gruppen und Firmen unterstützt wird. Ihre Mission ist das Entwickeln solch eines Standards. Das Containerformat und die Runtime von Docker dienen dabei als Ausgangsbasis Seit der Version 1.11 basiert die Docker Engine auf dem RunC-Kern, der eine Implementierung des Open-Container-Standards ist.
Die wachsende Verbreitung von Containern geht vor allem auf Entwickler zurück, die nun erstmals Tools zur Verfügung hatten, um Container effektiv zu nutzen. Die kurze Startzeit von Docker-Containern hat für die Entwickler einen hohen Stellenwert, weil sie natürlich schnelle und iterative Entwicklungszyklen bevorzugen, in denen sie die Ergebnisse von Codeänderungen möglichst direkt sehen können. Die Portierbarkeits- und Isolationsgarantien von Containern vereinfachen die Zusammenarbeit mit anderen Entwicklern und Administratoren: Entwickler können sicher sein, dass ihr Code in allen Umgebungen laufen wird, während sich die Administratoren auf das Hosten und Orchestrieren von Containern konzentrieren können, statt sich mit dem Code herumschlagen, der darin läuft.
Die Änderungen, die Docker angestoßen hat, sorgen für eine deutlich unterschiedliche Art und Weise, wie wir Software entwickeln. Ohne Docker würden Container noch für eine lange Zeit bei der IT vergessen sein.
2008 gründete Solomon Hykes dotCloud, um ein sprachunabhängiges Platform-as-a-Service-(PaaS-)Angebot aufzubauen. Diese Sprachunabhängigkeit war das Alleinstellungsmerkmal für dotCloud – bestehende PaaS waren an bestimmte Sprachen gebunden (so unterstützte Heroku zum Beispiel Ruby und die Google App Engine Java und Python). 2010 beteiligte sich dotCloud am Y Combinator Accelerator Program, wo es mit neuen Partnern zusammengebracht wurde und damit begann, ernsthafte Investitionen einzuwerben. Die entscheidende Wende kam im März 2013, als dotCloud Docker als Open Source bereitstellte – den zentralen Baustein von dotCloud. Während manche Firmen Angst davor gehabt hätten, ihre Geheimnisse preiszugeben, erkannte dotCloud, dass Docker sehr stark davon profitieren würde, wenn es ein durch eine Community unterstütztes Projekt würde.
Frühe Versionen von Docker waren nicht mehr als ein Wrapper für LXC, kombiniert mit einem geschichteten Dateisystem (Union-Dateisystem). Aber die Entwicklung ging ausgesprochen schnell voran: Innerhalb von sechs Monaten gab es mehr als 6700 Stars bei GitHub und 175 Contributors, die keine Mitarbeiter waren. Das führte dazu, dass dotCloud seinen Namen in Docker Inc. änderte und sein Geschäftsmodell anpasste. Docker 1.0 wurde im Juni 2014 veröffentlicht, nur 15 Monate nach der Version 0.1. Docker 1.0 stand für einen großen Schritt in Bezug auf Stabilität und Zuverlässigkeit – und wurde jetzt als »Production Ready« bezeichnet (in vielen Firmen hatte man es sogar schon zuvor tatsächlich produktiveingesetzt, wie zum Beispiel bei Spotify und Baidu). Gleichzeitig eröffnete Docker den Docker Hub – ein öffentliches Repository für Container. Damit war Docker nicht mehr nur eine einfache Container-Engine, sondern begann, sich zu einer vollständigen Plattform zu entwickeln.
Andere Firmen sahen schnell das Potenzial von Docker. Red Hat wurde im September 2013 ein wichtiger Partner und nutzte Docker, um sein OpenShift-Cloud-Angebot zu unterstützen. Google, Amazon und DigitalOcean boten bald Docker-Support für ihre Clouds an, und eine Reihe von Startups spezialisierte sich auf das Docker Hosting, wie zum Beispiel StackDock. Im Oktober 2014 gab Microsoft bekannt, dass zukünftige Versionen des Windows Server eine Unterstützung für Docker enthalten würden – was eine große Veränderung für eine Firma war, die klassischerweise mit aufgeblasener Firmensoftware in Verbindung gebracht wurde.
Auf der DockerConEU wurde im Dezember 2014 Docker Swarm angekündigt – ein Clustering Manager für Docker – sowie Docker Machine (Letzteres ein CLI-Tool für das Vorbereiten von Docker Hosts). Das war ein deutliches Signal für die Ziele von Docker: eine vollständige und integrierte Lösung für das Ausführen von Containern anzubieten und nicht nur selbst auf die Docker Engine beschränkt zu sein.
Im gleichen Monat kündigte CoreOS an, ihre eigene Container-Runtime rkt zu entwickeln und die appc-Containerspezifikation-S zu erstellen. Im Juni 2015 gaben Solomon Hykes von Docker und Alex Polvi von CoreOS auf der DockerCon in San Francisco die Gründung der Open Container Initiative bekannt (zunächst noch als Open Container Project bezeichnet), um einen gemeinsamen Standard für Containerformate und Runtimes zu entwickeln.
Ebenfalls im Juni 2015 kündigte das FreeBSD-Projekt an, dass Docker nun von FreeBSD unterstützt würde, wobei ZFS und der Linux Compatibility Layer zum Einsatz kommen. Im August 2015 veröffentlichten Docker und Microsoft ein »Tech Preview« der Docker Engine für Windows Server.
Mit dem Release 1.8 wurde von Docker das Content Trust Feature eingeführt, mit dem die Integrität und die Herausgeber von Docker-Images überprüft werden können. Content Trust ist eine entscheidende Komponente für den Aufbau vertrauenswürdiger Arbeitsabläufe, die auf aus Docker Registries stammenden Images basieren.
6