Blog

Einstieg in die Welt der Container

Docker-Grundlagen für .NET-Entwickler

Jul 31, 2018

Container und Docker sind in aller Munde. Doch die Einstiegshürde in die Docker-Welt ist nicht ganz niedrig. Aber auch für .NET-Entwickler lohnt es sich, zu fragen, was genau Docker eigentlich ist, wie es funktioniert, welche Probleme es löst und wie man es heute schon einsetzen kann.

In den vergangenen Jahren ist die Beliebtheit von Docker stetig gestiegen. Applikationen werden in einem Container ausgeführt und können somit auf beliebigen Umgebungen „angedockt“ werden. Das klingt ja ganz spannend. Aber warum sollte das einen .NET Entwickler interessieren, ist das denn überhaupt wichtig für den Entwicklungsalltag? Wieso ist Docker auch für uns eine solche Revolution?

 

Warum Docker?

Bei Docker geht es primär um das Verteilen von Anwendungen und Diensten, das sogenannte Deployment. Doch wie wurde das eigentlich früher gemacht? Nehmen wir an, ein Entwickler will seine frisch erstellte .NET-Webapplikation einer Kollegin zum lokalen Testen geben. Ganz früher war es noch so, dass die Kollegin zur Installation eine Anleitung mit Voraussetzungen und ggfs. auch manuelle Skripte bekam. Da stand dann z. B. in der Anleitung, dass Windows als Betriebssystem benötigt wird, dass das .NET Framework in einer bestimmten Version installiert sein muss, dass zur Ausführung eine bestimmte Datenbank benötigt wird usw. Es wird also für die Kollegin ein mühsames und aufwändiges Unterfangen, die Webapplikation lokal zum Laufen zu bekommen.

Im Laufe der Jahre hat sich das Ganze vereinfacht, indem man mit virtuellen Maschinen gearbeitet hat. Ja, viele Entwickler machen das natürlich auch heute noch. In der virtuellen Maschine wird die .NET-Webapplikation mit allen Abhängigkeiten installiert. Jetzt kann der Entwickler seiner Kollegin einfach die virtuelle Maschine geben, die Kollegin startet sie und hat somit eine lauffähige Applikation, die sie innerhalb der VM testen kann – ein deutlicher Fortschritt. Doch auch hier gibt es noch einen kleinen Haken: Die eigentliche Anwendung ist in der Praxis meist nur ein paar Megabytes groß, wenn überhaupt. Zur Größe der Anwendung kommen noch ein paar Abhängigkeiten, wie ein Webserver und eine Datenbank. Doch die virtuelle Maschine selbst beinhaltet ja noch das Gastbetriebssystem, und das nimmt üblicherweise gleich mal einige Gigabytes in Anspruch. Dass man der Kollegin die beispielsweise 100 GB große virtuelle Maschine für eine Anwendung geben muss, die mit ihren Abhängigkeiten nur einen Bruchteil dieser Größe hat, ist natürlich nicht ideal. Geht man sogar noch davon aus, dass man verschiedene Applikationen mit unterschiedlichen Abhängigkeiten hat, dann braucht es vielleicht sogar mehrere virtuelle Maschinen, um für jede Applikation eine zu haben. Wer kennt es nicht, dass die Festplattengröße des Entwicklungsrechners da oft ein Problem darstellt. Neben dem Datenvolumen einer VM ist auch das Startverhalten ein Kritikpunkt. Es dauert meist eine kleine Weile, bis das Betriebssystem hochgefahren ist. Doch warum brauche ich überhaupt ein zusätzliches Betriebssystem, wenn die Kollegin auf ihrem Rechner doch schon eins hat? Das ist eine sehr gute Frage, und das ist der Punkt, an dem Docker ins Spiel kommt.

 

Der Cloud, Azure, Serverless Track auf der BASTA! 2018

 

Über Images und Container

Mit Docker lassen sich alle Abhängigkeiten einer Anwendung in einem sogenannten Docker Image abbilden. Aus einem Image lässt sich dann eine Instanz erzeugen, die als Container bezeichnet wird. Um eine Applikation mit allen Abhängigkeiten an eine Kollegin zu geben, wird ein Docker Image bereitgestellt. Die Kollegin kann das Docker Image dann in Form eines Containers lokal auf ihrem Rechner ausführen. Doch was ist jetzt genau der Unterschied zwischen einem laufenden Docker-Container und einer laufenden virtuellen Maschine? Der große Unterschied ist, dass der Docker-Container im Gegensatz zur virtuellen Maschine kein eigenes Betriebssystem hat. Anstelle eines Gastsystems wie bei einer virtuellen Maschine, wird bei einem Docker-Container direkt das Betriebssystem des Hosts genutzt, das sogenannte Host-OS. Abbildung 1 verdeutlicht den Unterschied zwischen einer virtuellen Maschine und einem Docker-Container.

 

Abb. 1: Virtuelle Maschine vs. Docker Container 

 

Wie Abbildung 1 zeigt, benötigt eine virtuelle Maschine den sogenannten Hypervisor, der die Ressourcen des Hosts bereitstellt. Auch ein Docker-Container benötigt etwas ähnliches, die sogenannte Docker Engine. Die stellt den Zugriff auf den Kernel des Host-Betriebssystems sicher und ist in der Lage, Container zu erstellen, zu starten und zu stoppen. Aufgrund der Tatsache, dass ein Docker Image und somit auch ein daraus erstellter Docker-Container kein eigenes Betriebssystem mit sich bringt, sondern auf dem Host-Betriebssystem aufgesetzt wird, ist ein Docker Image sehr viel kleiner als eine virtuelle Maschine. Neben der Größe ist das schnelle Starten eines Docker-Containers ein weiterer großer Vorteil gegenüber einer virtuellen Maschine. Beim Starten eines Containers muss nicht ein ganzes Betriebssystem hochgefahren werden. Somit geht das Starten und Stoppen eines Containers ungewohnt schnell, es gleicht dem Starten und Stoppen eines Prozesses.

Um also Docker-Container ausführen zu können, wird die Docker Engine benötigt. Auf jedem Rechner, auf dem eine Docker Engine installiert ist, lassen sich Docker-Container ausführen. Es ist also an der Zeit, die Docker Engine auch auf dem eigenen Entwicklungsrechner zu installieren.

Mit Docker loslegen

Nach der Installation ist Docker auf der Kommandozeile verfügbar und es kann losgehen. Wie in Abbildung 2 zu sehen ist, läuft die Docker Engine auf Linux, das als Operating System (OS) angegeben ist.

 

Abb. 2: Die installierte Docker-Version

 

Beim Installieren von Docker stand die Option USE WINDOWS CONTAINERS INSTEAD OF LINUX CONTAINERS zur Verfügung. Docker wurde ursprünglich auf Linux aufbauend eingeführt, Windows-Container kamen erst später dazu. Da mit der Defaultinstallation Linux-Container verwendet werden, bedeutet das, dass Images und daraus instanziierte Container Linux-basiert sind und somit den Linux-Kernel des Hostbetriebssystems verwenden. Doch wo ist dieser Linux-Kernel unter Windows? Im Hintergrund hat die Docker-Installation eine virtuelle Maschine mit Linux installiert, damit sich auf einen Windows-Betriebssystem auch Linux-basierte Container starten lassen. Wird unter Windows der Hyper-V-Manager geöffnet, ist die von Docker installierte und genutzte Linux VM zu sehen, sie trägt den Namen MobyLinuxVM.

Im Icon Tray von Windows – das ist der Bereich rechts unten in der Taskbar links von der Uhr – ist nach einer erfolgreichen Installation und einem erfolgreichen Start der Docker Engine ein Docker-Icon zu sehen. Es repräsentiert die installierte Docker Engine und hat die Form des klassischen Walfischs mit Containern an Bord. Ein Rechtsklick auf dieses Icon zeigt ein Kontextmenü, das unter anderem einen Eintrag enthält, um von Linux-Containern auf Windows-Container umzusteigen.

Doch Linux-Container sind die übliche Variante. Ein Linux-Container kann zwar kein .NET Framework beinalten, da das nur unter Windows läuft. Aber .NET Core ist ein ideales Mittel, um .NET-Applikationen auch in einem Linux-Container auszuführen, da .NET Core ja eine modulare Cross-Platform-Implementierung von .NET ist, die unter Windows, Mac OS und Linux läuft. Jetzt dürfte auch klar sein, wieso die Cross-Platform-Fähigkeit von .NET Core so wichtig ist. Sie macht .NET Core zu einem wichtigen Framework für containerbasierte Applikationen, unabhängig davon, ob es sich um Linux- oder Windows-basierte Container handelt.

Docker in Visual Studio

Visual Studio enthält eine integrierte Unterstützung für Docker. Wird eine neue ASP.NET-Core-Webapplikation erstellt, gibt es dort im Dialog eine Checkbox, um die Docker-Unterstützung zu aktivieren. Wurde diese Auswahl beim Erstellen des Projekts nicht getroffen, lässt sie sich auch im Nachhinein noch aktivieren. Dazu genügt ein Rechtsklick auf das Projekt im Solution Explorer. Über das Kontextmenü und den Menüpunkt ADD | DOCKER SUPPORT wird die Docker-Unterstützung hinzugefügt (Abb. 3). Unmittelbar nach einem Klick auf diesen Menüpunkt erscheint ein Dialog, der eine Auswahl zwischen Windows und Linux erlaubt. Darüber wird definiert, was für eine Art von Container erstellt wird.

 

Abb. 3: Docker Support in Visual Studio

 

Fazit

Neben dem Deployment für produktive Applikationen ist Docker ideal, um Entwicklungs- und Testumgebungen aufzusetzen. Auf dem Docker Hub gibt es Datenbanken und andere Services, die das Entwicklerherz höherschlagen lassen. Haben Entwickler erst einmal mit Docker angefangen, sind vermutlich die Tage gezählt, an denen sie SQL Server direkt auf ihrem Entwicklungsrechner installiert haben. Stattdessen läuft das Ganze in einem Container. Unterschiedliche Versionen lassen sich somit problemlos parallel installieren, starten, stoppen und auch wieder entfernen.

Die Mächtigkeit von Docker macht virtuelle Maschinen weitestgehend überflüssig und bringt uns im 21. Jahrhundert endlich an den Punkt, an dem wir tatsächlich von echten Softwarekomponenten sprechen können. Es ist an der Zeit, sich mit dem Thema Docker auseinanderzusetzen, denn in Zukunft wird vermutlich kein Entwickler daran vorbeikommen.

Die vollständige Einführung in Docker für .NET-Entwickler von Thomas Claudius Huber bietet die aktuelle Ausgabe des Windows Developers „Docker für .NET-Entwickler“. Noch mehr Wissenswertes zum Thema finden Sie in den Artikeln zu Windows- oder Linux-basierten Containern von Dr. Holger Schwichtenberg und Serverless Containern in Azure von Rainer Stropek.

Noch weiter vertiefen können Sie Ihr Docker-Wissen in den praxisorientierten Sessions von Marc Müller und Thorsten Hans auf der BASTA!. Bis dahin behalten Sie mit dem Docker-Spickzettel von Dr. Holger Schwichtenberg alles Wichtige zu Docker im Blick.

 

Ihr aktueller Zugang zur .NET- und Microsoft-Welt.
Der BASTA! Newsletter:

Behind the Tracks

.NET Framework & C#
Visual Studio, .NET, Git, C# & mehr

Agile & DevOps
Agile Methoden, wie Scrum oder Kanban und Tools wie Visual Studio, Azure DevOps usw.

Web Development
Alle Wege führen ins Web

Data Access & Storage
Alles rund um´s Thema Data

JavaScript
Leichtegewichtig entwickeln

UI Technology
Alles rund um UI- und UX-Aspekte

Microservices & APIs
Services, die sich über APIs via REST und JavaScript nutzen lassen

Security
Tools und Methoden für sicherere Applikationen

Cloud & Azure
Cloud-basierte & Native Apps