April 2017

Band 32, Nummer 4

Container: Modernisieren traditioneller .NET-Apps mit Docker

Von Elton Stoneman

Microsoft .NET Framework ist nun schon seit 15 Jahren eine erfolgreiche Anwendungsplattform. Unzählige unternehmenswichtige Apps werden mit älteren Versionen des Frameworks und älteren Versionen von Windows Server ausgeführt. Diese traditionellen Apps bieten noch immer einen großen Geschäftswert, sind aber wahrscheinlich schwierig zu warten, zu aktualisieren, zu erweitern und zu verwalten. Außerdem rechtfertigen sie ggf. nicht die erforderlichen Investitionen für eine vollständige Neuerstellung. Mit Docker (einer Plattform zum Ausführen von Anwendungen in einfachen Containern) und Windows Server 2016 erschließen sich für traditionelle Apps ganz neue Aspekte der Lebensdauer. Features werden hinzugefügt, Sicherheit und Leistung gesteigert, und Continuous Deployment wird ohne ein langwieriges und teures Neuerstellungsprojekt ermöglicht.

In diesem Artikel verwende ich eine monolithische ASP.NET WebForms-App, die eine Verbindung mit einer SQL Server-Datenbank herstellt, und modernisiere diese, indem ich die Vorteile der Docker-Plattform nutze. Ich beginne, indem ich die gesamte App in ihrem gegenwärtigen Zustand ohne Codeänderungen nach Docker verschiebe und die Website und die Datenbank in einfachen Containern ausführe. Anschließend zeige ich eine featuregesteuerte Verfahrensweise zum Erweitern der App und Verbessern der Leistung. Außerdem ermögliche ich Benutzern Self-Service-Analysen. Anhand der Docker-Plattform zeige ich, wie die Iteration mit neuen Versionen der App erfolgt, wie die Komponenten schnell und sicher aktualisiert werden können und wie die vollständige Lösung in Microsoft Azure bereitgestellt wird.

Einsatzmöglichkeiten von Docker in .NET-Lösungen

Docker wurde für Serveranwendungen konzipiert: Websites, APIs, Messaginglösungen und andere Komponenten, die im Hintergrund ausgeführt werden. Sie können keine Desktop-Apps in Docker ausführen, weil keine Benutzeroberflächenintegration zwischen der Docker-Plattform und dem Windows-Host verfügbar ist. Dies schließt die Ausführung von Windows Forms- oder WPF-Apps (Windows Presentation Foundation) in Containern aus (Sie könnten Docker jedoch für die Paketerstellung und Verteilung dieser Desktop-Apps verwenden). WCF- (Windows Communication Foundation), .NET-Konsolen-Apps und alle Spielarten von ASP.NET sind jedoch hervorragende Kandidaten.

Wenn Sie ein Anwendungspaket für die Ausführung in Docker erstellen möchten, schreiben Sie ein kleines Skript, das als „Dockerfile-Datei“ bezeichnet wird und alle Schritte für die Bereitstellung der App automatisiert. In der Regel enthält dieses Skript Windows PowerShell-Befehle für die Konfiguration sowie Anweisungen zum Kopieren von Anwendungsinhalten und Einrichten ggf. erforderlicher Abhängigkeiten. Sie können auch komprimierte Archive entzippen oder MSIs installieren, der Paketerstellungsvorgang ist jedoch vollständig automatisiert. Sie können daher keinen Installationsprozess ausführen, für den eine Windows-Benutzeroberfläche und Benutzereingaben erforderlich sind.

Wenn Sie eine Lösungsarchitektur untersuchen, um zu ermitteln, welche Bestandteile in Docker-Containern ausgeführt werden können, denken Sie daran, dass jede Komponente ein guter Kandidat ist, die ohne die Windows-Benutzeroberfläche installiert und ausgeführt werden kann. In diesem Artikel lege ich den Schwerpunkt auf .NET Framework-Apps. Sie können jedoch beliebige Apps in einem Windows-Container ausführen, die unter Windows Server ausgeführt werden können, z. B. .NET Core-, Java-, Node.js- und Go-Apps.

Migrieren von .NET-Apps in Container

Wie die Migration zu Docker erfolgt, hängt davon ab, wie Ihre App zurzeit ausgeführt wird. Wenn Sie eine vollständig konfigurierte App verwenden, die in einem virtuellen Hyper-V-Computer ausgeführt wird, kann das Open Source-Tool Image2Docker automatisch eine Dockerfile-Datei vom Datenträger des virtuellen Computers generieren. Wenn Sie einen Buildprozess verwenden, der ein MSI- oder WebDeploy-Paket veröffentlicht, können Sie ganz einfach eine eigene Dockerfile-Datei erstellen, indem Sie eines der Microsoft-Basisimages auf Docker Hub verwenden.

Die folgende Dockerfile-Datei enthält ein Skript für die Paketerstellung einer ASP.NET WebForms-App in ein Docker-Image:

FROM microsoft/aspnet:windowsservercore-10.0.14393.693
SHELL ["powershell"]
RUN Remove-Website -Name 'Default Web Site'; \
    New-Item -Path 'C:\web-app' -Type Directory; \
    New-Website -Name 'web-app' -PhysicalPath 'C:\web-app' -Port 80 -Force
EXPOSE 80
RUN Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' \
    -Name ServerPriorityTimeLimit -Value 0 -Type DWord
COPY ProductLaunch.Web /web-app

Nur neun Skriptzeilen sind erforderlich, und es müssen keine Anwendungsänderungen vorgenommen werden. Dies könnte eine ASP.NET 2.0-App sein, die zurzeit unter Windows Server 2003 ausgeführt wird. Mit dieser Dockerfile-Datei kann ich aus ihr ein Image erstellen, das sofort ein Upgrade der App auf Windows Server 2016 und .NET Framework 4.5 ausführt. Ich werde jede der folgenden Anweisungen schrittweise erläutern:

  • „FROM microsoft/aspnet“ informiert Docker, welches Image als Ausgangspunkt verwendet werden soll. In diesem Fall handelt es sich um ein Microsoft-Image, in dem IIS und ASP.NET über einer bestimmten Version von Windows Server Core installiert sind.
  • „SHELL ["powershell"]“ wechselt für die restliche Dockerfile-Datei zu einer anderen Shell, damit ich PowerShell-Cmdlets ausführen kann.
  • „RUN Remove-Website“ verwendet PowerShell zum Einrichten von IIS, Entfernen der Standardwebsite und Erstellen einer neuen Website mit einem bekannten Speicherort für die Anwendung.
  • „EXPOSE 80“ öffnet Port 80 explizit, um Netzwerkdatenverkehr in den Container zu erlauben, weil Docker-Container standardmäßig gesperrt sind.
  • „RUN Set-ItemProperty“ deaktiviert den Windows DNS-Cache im Image, damit DNS-Anforderungen von Docker verarbeitet werden können.
  • „COPY ProductLaunch.Web“ kopiert das veröffentlichte Websiteprojekt aus dem Verzeichnis „ProductLaunch.Web“ auf dem Host in das Image.

Die Dockerfile-Datei ist wie ein Bereitstellungsleitfaden für die Webanwendung. Sie ist jedoch kein ungenaues, von einem Menschen erstellten Dokument, sondern ein präzises und handlungsrelevantes Skript. Zum Generieren der Paket-App führe ich den Befehl „docker build“ aus dem Verzeichnis aus, das die Dockerfile-Datei und die veröffentlichte Website enthält:

docker build --tag sixeyed/msdn-web-app:v1 .

Dieser Befehl erstellt das Docker-Image mit dem Namen „sixeyed/msdn-web-app“ sowie das Tag „v1“. Der Name enthält mein Benutzerkonto für den Hub („sixeyed“). Ich kann also dieses Image freigeben, indem ich mich mit meinen Anmeldeinformationen anmelde und das Image dann mithilfe von Push auf den Hub übertrage. Tags sind für die Versionsverwaltung von Images sinnvoll. Wenn ich also eine neue Version des Anwendungspakets erstelle, bleibt der Imagename gleich, das Tag ist aber „v2“.

Nun kann ich einen Container aus dem Image ausführen und so die Anwendung starten. Die Beispiel-App weist jedoch eine Abhängigkeit von SQL Server auf. Deshalb muss ich SQL Server ausführen, bevor ich die Website starten kann.

Abrufen von Abhängigkeiten von Docker Hub mithilfe von Pull

Docker verfügt über einen Netzwerkstapel, mit dem Container sich gegenseitig über ein virtuelles Netzwerk erreichen können. Außerdem können Container über ihn auch externe Hosts erreichen, die im physikalischen Netzwerk ausgeführt werden. Wenn ich über eine SQL Server-Instanz verfüge, die auf dem Computer im Netzwerk ausgeführt wird, kann die ASP.NET-App im Container diese verwenden. Ich muss nur den Servernamen in der Verbindungszeichenfolge angeben. Ich kann aber auch SQL Server in einem Container ausführen. Die Web-App ist dann in der Lage, das Programm zu erreichen, indem der Containername in der Verbindungszeichenfolge verwendet wird.

SQL Server Express ist auf Docker Hub in einem Image verfügbar, das von Microsoft verwaltet wird. Zum Starten eines Datenbankcontainers aus diesem Image führe ich Folgendes aus:

docker run --detach `
 --publish 1433:1433 `
 --env sa_password=MSDNm4g4z!n3 `
 --env ACCEPT_EULA=Y `
 --name sql-server `
 microsoft/mssql-server-windows-express

Es wird ein Container im Hintergrund mit der detach-Kennzeichnung gestartet, und Port 1433 wird veröffentlicht. Ich kann daher von außerhalb eine Verbindung mit der SQL-Instanz im Container herstellen, z. B. durch Verwenden von SQL Server Management Studio auf dem Host. Die env-Optionen sind Schlüssel-Wert-Paare, die Docker im Container als Systemumgebungsvariablen bereitstellt. Das SQL Server-Image verwendet diese Werte zum Bestätigen, dass den Lizenzbestimmungen zugestimmt wurde, sowie zum Einrichten des Kennworts des sa-Benutzers.

Zum Ausführen eines Containers muss Docker lokal über eine Kopie des Image verfügen. Die Verteilung ist in die Docker-Plattform integriert. Wenn Sie also beim Ausführen dieses Befehls lokal nicht über das SQL Server Express-Image verfügen, lädt Docker dieses vom Hub herunter. Auf Docker Hub finden Sie mehr als eine halbe Million Images, die über 9 Milliarden Mal heruntergeladen wurden. Docker war ursprünglich in der Linux-Welt beheimatet, und die Mehrzahl dieser Images sind Linux-Apps. Die Zahl der qualitativ hochwertigen Windows-Apps wächst jedoch stetig, die Sie herunterladen und direkt in Ihrer Lösung speichern können.

SQL Server wird jetzt in einem Docker-Container ausgeführt, und meine Web-App verwendet „sql-server“ als Hostnamen in der Verbindungszeichenfolge, damit eine Verbindung mit der in Docker ausgeführten Datenbank hergestellt werden kann. Ich kann die WebForms-Anwendung im Hintergrund starten und Port 80 veröffentlichen, damit auf die Website zugegriffen werden kann:

docker run --detach `
 --publish 80:80 `
 sixeyed/msdn-web-app:v1

Wenn ein externer Computer eine Anforderung an Port 80 an meinen Host sendet, empfängt Docker die Anforderung und leitet sie transparent an die ASP.NET-App weiter, die im Container ausgeführt wird. Wenn ich auf dem Host arbeite, muss ich „docker inspect“ verwenden, um die IP-Adresse des Containers abzurufen und zu dem Container zu navigieren, damit ich die Website anzeigen kann, die eine einfache Produktstart-Microsite ist. Abbildung 1 zeigt die Datenerfassungsseite der Website, die in Docker ausgeführt wird.

Eine Registrierungsseite für eine in Docker ausgeführte Website
Abbildung 1: Eine Registrierungsseite für eine in Docker ausgeführte Website

Führen Sie „docker ps“ aus, um eine Liste aller aktuell ausgeführten Container anzuzeigen. Ein Container ist eine Datenbank, ein anderer eine Webanwendung. Beide werden jedoch auf die gleiche Weise verwaltet: „docker top“ zeigt Ihnen die im Container ausgeführten Prozesse, „docker logs“ zeigt die Protokollausgabe aus der App und „docker inspect“ gibt die geöffneten Ports sowie eine Vielzahl weiterer Informationen zum Container an. Konsistenz ist ein Hauptvorteil der Docker-Plattform. Apps werden unabhängig von der verwendeten Technologie auf die gleiche Weise verpackt, verteilt und verwaltet.

Aufteilen von Features aus monolithischen Apps

Da die Anwendung nun auf einer modernen Plattform ausgeführt wird, kann ich mit der Modernisierung der Anwendung selbst beginnen. Das Aufteilen einer monolithischen Anwendung in kleinere Dienste kann einen erheblichen Arbeitsaufwand darstellen. Sie können jedoch einen zielgerichteteren Ansatz verwenden, indem Sie an Schlüsselfeatures arbeiten, z. B. an den Features, die sich regelmäßig ändern, damit Sie Updates für ein geändertes Feature bereitstellen können, ohne einen Regressionstest für die gesamte Anwendung ausführen zu müssen. Features mit nichtfunktionalen Anforderungen, die von einem anderen Entwurf profitieren können, ohne eine vollständige Überarbeitung der Architektur zu erfordern, können ebenfalls eine gute Wahl darstellen.

Hier beginne ich, indem ich ein Leistungsproblem behebe. Im vorhandenen Code stellt die Anwendung eine synchrone Verbindung mit der Datenbank her, um die Daten des Benutzers zu speichern. Dieser Ansatz lässt sich nicht gut skalieren: Eine große Anzahl gleichzeitiger Benutzer würde aus SQL Server einen Engpass werden lassen. Asynchrone Kommunikation mit einer Nachrichtenwarteschlange ist ein Entwurf, der viel besser skaliert werden kann. Für dieses Feature kann ich ein Ereignis aus der Web-App in einer Nachrichtenwarteschlange veröffentlichen und den Datenpersistenzcode in eine neue Komponente verschieben, die diese Ereignisnachricht verarbeitet.

Der Entwurf lässt sich gut skalieren. Wenn eine Datenverkehrsspitze für die Website auftritt, kann ich weitere Container auf weiteren Hosts ausführen, um die eingehenden Anforderungen zu verarbeiten. Ereignisnachrichten verbleiben in der Warteschlange, bis sie durch den Nachrichtenhandler verbraucht werden. Für Features, die keine bestimmte SLA besitzen, können Sie einen Nachrichtenhandler in einem Container ausführen und sich auf die Garantien der Nachrichtenwarteschlange verlassen, dass alle Ereignisse letztendlich verarbeitet werden. Für SLA-gesteuerte Features können Sie die Persistenzschicht horizontal hochskalieren, indem Sie weitere Nachrichtenhandlercontainer ausführen.

Der Quellcode, der diesen Artikel begleitet, verfügt über Ordner für Version 1, Version 2 und Version 3 der Anwendung. In Version 2 veröffentlicht die Seite „SignUp.aspx“ ein Ereignis, wenn der Benutzer das Detailformular übermittelt:

var eventMessage = new ProspectSignedUpEvent
{
  Prospect = prospect,
  SignedUpAt = DateTime.UtcNow
};
MessageQueue.Publish(eventMessage);

In Version 2 ist außerdem ein freigegebenes Messagingprojekt vorhanden, das die Details der Nachrichtenwarteschlange abstrahiert, sowie eine Konsolenanwendung, die auf das von der Web-App veröffentlichte Ereignis lauscht und die Daten des Benutzers in der Datenbank speichert. Der Persistenzcode in der Konsolen-App wurde direkt aus dem Code von Version 1 in der Web-App entnommen. Die Implementierung ist daher identisch, aber der Entwurf des Features wurde modernisiert.

Die neue Version der Anwendung ist eine verteilte Lösung mit zahlreichen funktionierenden Bestandteilen. Abbildung 2 zeigt dies.

Die modernisierte Anwendung verfügt über zahlreiche funktionierende Bestandteile
Abbildung 2: Die modernisierte Anwendung verfügt über zahlreiche funktionierende Bestandteile

Zwischen den Komponenten sind Abhängigkeiten vorhanden, und diese müssen in der richtigen Reihenfolge gestartet werden, damit die Lösung ordnungsgemäß funktioniert. Dies ist eines der Probleme bei der Orchestrierung einer Anwendung, die über zahlreiche Container hinweg ausgeführt wird. Die Docker-Plattform löst dieses Problem jedoch, indem verteilte Anwendungen als Objekte erster Klasse behandelt werden.

Orchestrieren von Anwendungen mit Docker Compose

Docker Compose ist der Bestandteil der Docker-Plattform, der für verteilte Anwendungen konzipiert wurde. Sie definieren alle Teile Ihrer Anwendung in einer einfachen Textdatei als Dienste. Dies umfasst auch die Abhängigkeiten zwischen ihnen und alle von ihnen benötigten Konfigurationswerte. Das folgende Beispiel ist Teil der Docker Compose-Datei für Version 2 und zeigt nur die Konfiguration für die Web-App:

product-launch-web:
  image: sixeyed/msdn-web-app:v2
  ports:
    - "80:80"
  depends_on:
    - sql-server
    - message-queue
  networks:
    - app-net

Hier gebe ich die Version des für meine Webanwendung zu verwendenden Image an. Ich veröffentliche Port 80 und gebe dann explizit an, dass die Web-App von den SQL Server- und Nachrichtenwarteschlangencontainern abhängig ist. Damit diese Container erreicht werden können, muss sich der Webcontainer im gleichen virtuellen Docker-Netzwerk befinden. Alle Container in der Docker Compose-Datei werden daher in das gleiche virtuelle Netzwerk eingebunden, das den Namen „app-net“ trägt.

An anderer Stelle in der Docker Compose-Datei definiere ich einen Dienst für SQL Server und verwende dabei das Microsoft-Image auf Docker Hub. Außerdem verwende ich das NATS-Messagingsystem für meinen Nachrichtenwarteschlangendienst, eine Open Source-Hochleistungs-Nachrichtenwarteschlange. NATS ist als offizielles Image auf Docker Hub verfügbar. Der letzte Dienst ist für den Nachrichtenhandler bestimmt, einer .NET-Konsolenanwendung, die ein Docker-Imagepaket mit einer einfachen Dockerfile-Datei ist.

Nun kann ich die Anwendung mithilfe der Befehlszeile von Docker Compose ausführen:

docker-compose up -d

Anschließend startet Docker Compose Container für jede der Komponenten in der richtigen Reihenfolge und stellt mir so eine funktionierende Lösung mit einem einzigen Befehl zur Verfügung. Jeder Benutzer mit Zugriff auf die Docker-Images und die Docker Compose-Datei kann die Anwendung ausführen. Sie funktioniert immer auf die gleiche Weise – auf einem Windows 10-Laptop oder auf einem Windows Server 2016-Computer, der im Datencenter oder in Azure ausgeführt wird.

Für Version 2 habe ich eine kleine Änderung am Anwendungscode vorgenommen, um eine Featureimplementierung aus einer Komponente in eine andere zu verschieben. Das Endbenutzerverhalten ist identisch, aber nun kann die Lösung auf einfache Weise skaliert werden, weil die Webschicht von der Datenschicht abgekoppelt ist und die Nachrichtenwarteschlange eventuelle Spitzen im Nachrichtenverkehr abfängt. Der neue Entwurf kann auch problemlos erweitert werden, weil ich eine ereignisgesteuerte Architektur eingeführt habe, damit ich neues Verhalten auslösen kann, indem ich mich in die vorhandenen Ereignisnachrichten einhänge.

Self-Service-Analysen

Für meine Beispiel-App nehme ich eine weitere Änderung vor, um zu zeigen, was alles mit der Docker-Plattform mit nur minimalem Aufwand möglich ist. Die App verwendet zurzeit SQL Server als eine transaktionale Datenbank. Ich möchte einen zweiten Datenspeicher als Berichtsdatenbank hinzufügen. Auf diese Weise kann ich Berichtsaspekte von Transaktionsaspekten trennen, und ich habe die freie Wahl hinsichtlich des Technologiestapels.

In Version 3 des Beispielcodes habe ich eine neue .NET-Konsolen-App hinzugefügt, die auf die gleichen Ereignisnachrichten lauscht, die von der Webanwendung veröffentlicht werden. Wenn beide Konsolen-Apps ausgeführt werden, stellt die NATS-Nachrichtenwarteschlange sicher, dass beide Apps eine Kopie aller Ereignisse erhalten. Die neue Konsolen-App empfängt die Ereignisse und speichert die Benutzerdaten in Elasticsearch, einem Open Source-Dokumentspeicher, den Sie in einem Windows Docker-Container ausführen können. Elasticsearch ist hier eine gute Wahl, weil die Skalierbarkeit ausgezeichnet ist. Ich kann also aus Redundanzgründen einen Cluster aus mehreren Containern verwenden und das ausgezeichnete Front-End namens Kibana auf der Benutzerseite einsetzen.

Ich habe im Vergleich zu Version 2 keine Änderungen an der Webanwendung oder dem SQL Server-Nachrichtenhandler vorgenommen. Ich füge daher in meiner Docker Compose-Datei nur neue Dienste für Elasticsearch und Kibana sowie für den neuen Nachrichtenhandler hinzu, der Dokumente in den Elasticsearch-Index schreibt:

index-prospect-handler:
  image: sixeyed/msdn-index-handler:v3
  depends_on:
    - elasticsearch
    - message-queue
  networks:
    - app-net

Docker Compose kann inkrementelle Upgrades an einer Anwendung vornehmen und ersetzt keine aktuell ausgeführten Container, wenn deren Definition mit dem Dienst in der Docker Compose-Datei übereinstimmt. In Version 3 der Beispielanwendung sind neue Dienste vorhanden, aber keine Änderungen an den vorhandenen Diensten. Wenn ich also „docker-compose up –d“ ausführe, führt Docker neue Container für Elasticsearch, Kibana und den Indexnachrichtenhandler aus, behält die aktuelle Ausführung der anderen Dienste jedoch bei. Dies führt zu einem sehr sicheren Upgradevorgang, bei dem Sie Features hinzufügen können, ohne die Anwendung offline schalten zu müssen.

Diese Anwendung zieht die Konvention der Konfiguration vor. Die Hostnamen für Abhängigkeiten wie Elasticsearch werden daher als Standardwerte in der App festgelegt, und ich muss nur sicherstellen, dass die Containernamen mit dem Docker Compose-Setup übereinstimmen.

Nachdem die neuen Container gestartet wurden, kann ich „docker inspect“ zum Abrufen der IP-Adresse des Kibana-Containers verwenden und zu Port 5601 für diese Adresse navigieren. Kibana verfügt über eine sehr einfache Schnittstelle. Ich kann innerhalb weniger Minuten ein Dashboard erstellen, das die Schlüsselmetriken für Personen anzeigt, die sich mit ihren Details registrieren. Abbildung 3 zeigt dies.

Ein Kibana-Dashboard
Abbildung 3: Ein Kibana-Dashboard

Poweruser werden sich schnell in Kibana zurechtfinden, und sie können ihre eigenen Visualisierungen und Dashboards erstellen, ohne die IT-Abteilung einbeziehen zu müssen. Ohne jede Downtime habe ich der Anwendung Self-Service-Analysen hinzugefügt. Der Kern dieses Features stammt aus der Open Source-Unternehmenssoftware, die ich aus Docker Hub in meine Lösung abgerufen habe. Die benutzerdefinierte Komponente zum Einlesen von Daten in den Dokumentspeicher ist eine einfache .NET-Konsolenanwendung, die aus ungefähr 100 Codezeilen besteht. Die Docker-Plattform übernimmt die Integration der einzelnen Komponenten.

Ausführen von Docker-Lösungen in Azure

Ein weiterer Großer Vorteil von Docker ist die Portabilität. Anwendungen, die als Docker-Imagepakete vorliegen, werden auf jedem Host auf genau die gleiche Weise ausgeführt. Die endgültige Anwendung für diesen Artikel verwendet die Windows Server- und SQL Server-Images von Microsoft, das NATS-Image von Docker sowie meine eigenen, benutzerdefinierten Images. Alle diese Images werden auf Docker Hub veröffentlicht. Jeder Windows 10- oder Windows Server 2016-Computer kann die Images daher mithilfe von Pull übertragen und Container daraus ausführen.

Meine App ist nun für Tests bereit, und die Bereitstellung in einer freigegebenen Umgebung in Azure ist einfach. Ich habe in Azure mithilfe von Windows Server 2016 Datacenter mit der Container-Option einen virtuellen Computer erstellt. Im Image dieses virtuellen Computers ist Docker installiert und konfiguriert, und die Docker-Basisimages für Windows Server Core und Nano Server sind bereits heruntergeladen. Ein Element, das im virtuellen Computer nicht enthalten ist, ist Docker Compose. Diese Komponente habe ich von der GitHub-Releaseseite heruntergeladen.

Die in meiner Docker Compose-Datei verwendeten Images befinden sich alle in öffentlichen Repositorys auf Docker Hub. Bei einem privaten Softwarestapel möchten Sie bestimmt nicht, dass alle Ihre Images öffentlich verfügbar sind. Sie können Docker Hub trotzdem verwenden und Images in privaten Repositorys speichern, oder Sie können eine alternative gehostete Registrierung wie die Azure-Containerregistrierung verwenden. Innerhalb Ihres eigenen Datencenters können Sie eine lokale Option verwenden, z. B. Docker Trusted Registry.

Weil alle meine Images öffentlich sind, muss ich nur die Docker Compose-Datei auf den virtuellen Azure-Computer kopieren und „docker-compose up -d“ ausführen. Docker überträgt alle Images mithilfe von Pull vom Hub und führt dann Container aus ihnen in der richtigen Reihenfolge aus. Jede Komponente verwendet Konventionen für den Zugriff auf die anderen Komponenten, und diese Konventionen werden in die Docker Compose-Datei eingefügt. Selbst in einer komplett neuen Umgebung wird die Lösung einfach gestartet und wie erwartet ausgeführt.

Wenn Sie bereits an Releases von Unternehmenssoftware gearbeitet haben, bei denen das Einrichten einer neuen Umgebung ein manueller, risikoreicher und langsamer Vorgang war, werden Sie die Vorteile zu schätzen wissen, die Windows Server 2016 und die Docker-Plattform mit sich bringen. Die Schlüsselartefakte in einer Docker-Lösung (die Dockerfile-Datei und die Docker Compose-Datei) ersetzen manuelle Bereitstellungsdokumente auf einfache und unmissverständliche Weise. Sie fördern Automatisierung und machen es ganz einfach, eine Lösung auf konsistente Weise auf jedem beliebigen Computer zu erstellen, auszuliefern und auszuführen.

Nächste Schritte

Wenn Sie Docker selbst ausprobieren möchten, ist das PowerShell-Modul Image2Docker ein hervorragender Ausgangspunkt. Es kann eine Dockerfile-Datei für Sie erstellen und den Lernprozess beschleunigen. Auf training.docker.com sind einige hervorragende kostenlose Kurse verfügbar, deren Tempo sie selbst bestimmen können. Eine Umgebung wird dort für Sie bereitgestellt. Wenn Sie anschließend die nächsten Schritte ausführen möchten, sehen Sie sich die Docker Labs auf GitHub an. Dort finden Sie eine Vielzahl von exemplarischen Vorgehensweisen für Windows-Container.

Außerdem finden weltweit Docker MeetUps statt, bei denen Profis und Experten Vorträge zu allen Aspekten von Docker halten. Die größte, immer ausverkaufte Docker-Konferenz ist DockerCon. In diesem Jahr findet sie im April in Texas und im Oktober in Kopenhagen statt. Sehen Sie sich schließlich noch die Docker Captains an. Sie sind das Docker-Äquivalent zu Microsoft-MVPs. Sie bloggen, tweeten und reden unaufhörlich über all die coolen Dinge, die sie mit Docker anstellen. Folgen Sie Ihnen, um am Puls der Technologie zu sein.


Elton Stonemanist siebenfacher Microsoft-MVP sowie ein Pluralsight-Autor, der als Developer Advocate bei Docker arbeitet. Seit dem Jahr 2000 hat er mit Microsoft-Technologien erfolgreich Lösungen konzipiert und bereitgestellt, zuletzt API- und Big Data-Projekte in Azure, sowie verteilte Anwendungen mit Docker.

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Mark Heath
Mark Heath ist .NET-Entwickler mit dem Spezialgebiet Azure, Erfinder von NAudio und Autor bei Pluralsight. Er bloggt unter markheath.net, und Sie können ihm auf Twitter folgen: @mark_heath