© AVA Bitter/Shutterstock.com
ASP.NET Core Microservices in Kubernetes (AKS) betreiben

Kapitän im Service-Orchester


Containertechnologien wie Docker haben sich in den letzten Jahren auch im Microsoft-Technologieumfeld stark etabliert. Ein Container bietet viele Vorteile in Bezug auf Isolation, Abhängigkeitsmanagement und die Laufzeitumgebung einer Applikation. Für den professionellen Betrieb der Services benötigt man jedoch noch ein weiteres Werkzeug, das uns in den Bereichen Lastverteilung, Service Discovery, Speicherverwaltung und Ausfallsicherheit unterstützt: Kubernetes hat sich als führender Containerorchestrator durchgesetzt. Dieser Artikel zeigt, was man als ASP.NET-Core-Entwickler unternehmen muss, um seine Applikationen in Kubernetes zum Laufen zu bringen.

Anstelle eines großen Monolithen viele kleine Services zu verwenden, bietet in vielen Bereichen deutliche Vorteile. Microservices sind – wie der Name schon andeutet – nicht groß und entsprechend nimmt die Komplexität eines einzelnen Dienstes deutlich ab. Die Entwicklung kann auf ein Team beschränkt werden und eine Änderung bringt normalerweise einen überschaubaren Testaufwand mit sich. Das führt dazu, dass wir mit Microservices kleine und häufige Releases durchführen können – ideal für einen modernen und effizienten DevOps-Prozess. Leider ist nicht alles Gold, was glänzt und es existieren auch immer Nachteile. Auf die Herausforderungen im Bereich Softwarearchitektur werden wir in diesem Artikel nicht eingehen. Stattdessen werden wir uns auf den Betrieb dieser Services konzentrieren. Beim Verwalten von vielen kleinen Diensten muss sichergestellt werden, dass diese untereinander kommunizieren können. Bei einer Aktualisierung eines Service sollte das Gesamtsystem immer noch lauffähig bleiben und im Fehlerfall sollte dieser möglichst automatisch erkannt und behoben werden.

Cloud hin oder her: Am Ende läuft jede Dienstinstanz auf einer physikalischen oder virtuellen Maschine. Diese Instanzen manuell zu verwalten und entsprechend die Netzwerkadressierung zu aktualisieren, ist nahezu unmöglich. Genau hier benötigen wir Unterstützung von Kubernetes. Doch was bedeutet das für eine ASP.NET-Core-Applikation? Benötigt man Änderungen an der Architektur oder der Konfiguration?

Kubernetes mit Azure Kubernetes Services

Der einfachste Weg einen Kubernetes-Cluster im Microsoft-Umfeld zu betreiben, ist eine Instanz eines Azure Kubernetes Services (AKS) zu erstellen. Hierbei handelt es sich um einen Managed Service in Azure. Das bedeutet konkret, dass sich Microsoft um das Set-up, die Konfiguration, Aktualisierung und die Integration in die Cloud-Infrastruktur kümmert. Der Managed Service ist kostenlos [1], jedoch bezahlt man die Kosten der virtuellen Maschinen, der Worker Nodes. Der eine oder andere fragt sich nun, ob man nicht auch Azure App Services für das Hosting hätte verwenden können. Klar! Mit AKS gewinnen wir aber mehr Flexibilität und vor allem Portabilität. Bei allen großen Public-Cloud-Anbietern ist ein Kubernetes-Hosting verfügbar und auch im eigenen Data Center kann und wird oft Kubernetes betrieben. Ein Wechsel des Data Centers ist also in Windeseile vollzogen.

Wie funktioniert nun Kubernetes und wie betreibe ich meinen Service im Cluster? Ein Cluster besteht aus Master Nodes und (Worker) Nodes, die die Applikationsinstanzen ausführen. Am Anfang steht ein Container – meistens wird Docker verwendet. Die Applikation respektive der Service muss in einem Container lauffähig sein. Für das Beispiel, das im Folgenden vorgeführt wird, kann der Container die passende ASP.NET Core Runtime mit Kestrel vorweisen und führt im Wesentlichen die Binärdateien der Applikation aus. Ab hier erst beginnen wir mit Kubernetes. Es verwaltet sogenannte Pods. Ein Pod kapselt die Containerinstanz und bietet einen Netzwerkendpunkt. Außerdem können hier noch Hardwareressourcen definiert und limitiert werden (Abb. 1).

mueller_ofner_aspnetcore_1.tif_fmt1.jpgAbb. 1: Pods und Containerinstanzen

Diese Pods möchte man jedoch nicht manuell verwalten. Kubernetes verwendet dazu ein Desired State Model. In diesem wird deklarativ beschrieben, wie das Zielsystem auszusehen hat. Somit kann der Cluster selbst entscheiden, was unternommen werden muss, um diesen Status aufrecht zu erhalten, beispielsweise neue Pods erstellen, fehlerhafte entfernen oder ein Update mit einer neuen Version einspielen. Das erreichen wir mit einer Deployment-Definition (Abb. 2).

mueller_ofner_aspnetcore_2.tif_fmt1.jpgAbb. 2: Pods werden über ein Deployment verwaltet

Zu guter Letzt muss auf einen einzelnen Pod zugegriffen werden können. Doch wie funktioniert das in einem Cluster? Pods kommen und gehen oder werden auf andere Nodes verteilt. Es ist unmöglich, sich all die IP-Adressen zu merken und stetig beim Aufrufen zu aktualisieren. Hierzu kennt Kubernetes den Service. Ein Service ist ein logischer, aber persistenter Netzwerkendpunkt, der sich um das interne Load Balancing und das Weiterleiten auf die gewünschten Pods kümmert. Das funktioniert im Grunde ganz einfach: Die Pods definieren Labels und auf dem Service werden die Labels über einen Selektor gefiltert. Alle hieraus gesammelten Pods sind Bestandteil des Service Load Balancing (Abb. 3).

mueller_ofner_aspnetcore_3.tif_fmt1.jpgAbb. 3: Service-Definition und Load Balancing auf Pods

Mit dem Service haben wir nun einen statischen Endpunkt, um mit den eigentlichen Diensten in den Pods zu ...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang