Dieser Artikel zeigt, wie eine .NET-Anwendung mit Hilfe von Azure Arc automatisch in einen On-premises-Kubernetes-Cluster deployt wird und wie dafür Azure DevOps bzw. die Deployment Pipeline konfiguriert werden muss.
Der erste Teil dieser Serie hat eine theoretische Einführung in Hybrid-Cloud-Architekturen gegeben. Auf der einen Seite gibt es Hardwarelösungen von Microsoft, wie Azure Stack HCI oder Azure Stack Hub, mit denen Azure Dienste im eigenen Rechenzentrum betrieben werden können. Auf der anderen Seite gibt es mit Azure Arc eine Softwarelösung, mit der Infrastruktur, die außerhalb von Azure betrieben wird, mit Azure verwaltet werden kann. Außerhalb von Azure bedeutet „on premises" im eigenen Rechenzentrum, aber auch bei anderen Cloud-Anbietern wie AWS oder Google Cloud. Azure Arc erlaubt es, physische und virtuelle (z. B. VMware oder Azure Stack HCI) Linux- und Windows-Server sowie SQL-Server und Kubernetes-Cluster zu verwalten.
Um die wichtigsten Features von Azure Arc vorzustellen, wird ein fiktives Projekt mit den folgenden Anforderungen implementiert:
Das Aufsetzen eines Kubernetes-Clusters kann je nach Erfahrung relativ aufwendig und kompliziert sein. Deshalb wird für das Demoprojekt ein Azure-Kubernetes-Service-(AKS-)Cluster verwendet. Sollte eine On-premises-Microsoft-Hardwarelösung wie Azure Stack HCI oder Azure Edge Stack verwendet werden, kann dort ebenfalls AKS installiert sein.
Laut Anforderung soll der Kubernetes-Cluster nicht über das Internet erreichbar sein. Dafür setzen Unternehmen oft eine Firewall ein, um alle eingehenden Requests zu blockieren. Da das Aufsetzen einer Firewall hier den Rahmen sprengen und das Testen des Deployments verkomplizieren würde, wird angenommen, dass der AKS-Cluster nicht über das Internet erreichbar ist. Für die Installation des Clusters wird das Azure CLI [1] benötigt. Zusätzlich müssen einige Erweiterungen für das Azure CLI installiert und drei Provider in der Azure Subscription registriert werden. Listing 1 zeigt, wie mit Hilfe des Azure CLI das Log-in in Azure durchgeführt wird und anschließend die Erweiterungen installiert sowie die benötigten Provider registriert werden.
Listing 1
az login
 
az extension add --name connectedk8s
az extension add -n k8s-configuration
az extension add -n k8s-extension
 
az provider register --namespace Microsoft.Kubernetes
az provider register --namespace Microsoft.KubernetesConfiguration
az provider register --namespace Microsoft.ExtendedLocation
 
az provider show -n Microsoft.Kubernetes -o table
az provider show -n Microsoft.KubernetesConfiguration -o table
az provider show -n Microsoft.ExtendedLocation -o table
Die Registrierung der Azure-Provider kann bis zu zehn Minuten dauern. Das ist allerdings nur einmalig pro Subscription nötig. Abbildung 1 zeigt, wie mit den letzten drei Befehlen von Listing 1 der Status der Provider überprüft werden kann. Wenn der Status Registered ist, kann mit den nächsten Schritten fortgefahren werden.
Abb. 1: Alle Azure-Provider sind in der Subscription registriert
Nachdem die Azure-Provider registriert sind, kann mit der eigentlichen Installation begonnen werden. Zunächst werden in Listing 2 einige Variablen definiert. Falls eine andere Container Registry als die Azure Container Registry (ACR), etwa Docker Hub, verwendet wird, wird die Variable AcrName nicht benötigt. Falls ACR verwendet wird, muss der Name dafür weltweit einzigartig sein.
Listing 2
$Location="WestEurope"
$ResourceGroupName="ArcDemo"
$AksClusterName="AksCluster"
$ArcName="AksArc"
$AcrName="windevacr" <em># must be unique</em>
Listing 3 zeigt die Erstellung einer neuen Ressourcengruppe, die Erstellung einer ACR in dieser Ressourcengruppe sowie die Erstellung eines AKS-Clusters. Sollte keine ACR verwendet werden, dann wird der zweite Befehl (az acr create ...) nicht benötigt. Ebenfalls nicht benötigt wird dann der Parameter --attach-acr $AcrName im letzten Befehl. Dieser Parameter konfiguriert den Zugriff des AKS-Clusters auf die Azure Container Registry.
Listing 3
az group create --name $ResourceGroupName --location $Location
 
az acr create --name $AcrName --resource-group $ResourceGroupName --location $Location --sku Basic
 
az aks create --name $AksClusterName --resource-group $ResourceGroupName --location $Location --attach-acr $AcrName --generate-ssh-keys
Die Installation des AKS-Clusters sollte nur einige Minuten dauern. Nachdem die Installation abgeschlossen ist, kann mit den Befehlen in Listing 4 die Konfiguration für die Verbindung zum Cluster heruntergeladen werden. Dafür muss das Kubernetes CLI kubectl [2] installiert sein. Sollte Docker Desktop [3] verwendet werden, wird es automatisch mit installiert. Anschließend kann Azure Arc auf dem Cluster installiert werden.
Listing 4
az aks get-credentials --resource-group $ResourceGroupName --name $AksClusterName
 
az connectedk8s connect --name $ArcName --resource-group $ResourceGroupName --location $Location
Die Installation von Azure Arc dauert ebenfalls nur einige Minuten und erstellt einen neuen Namespace mit dem Namen azure-arc. Mit Hilfe des Kubernetes CLI können alle Namespaces im Cluster angezeigt und alle Pods im azure-arc Namespace ausgegeben werden:
kubectl get namespace
kubectl get pods -n azure-arc
Abbildung 2 zeigt alle elf Anwendungen, die im neuen azure-arc-Namespace erstellt wurden.
Abb. 2: Azure Arc hat diverse Anwendungen im azure-arc-Namespace installiert
Zusätzlich wird eine neue Azure-Arc-Instanz im Azure-Portal angelegt. Das Menü von Azure Arc ist dabei sehr ähnlich wie das von AKS. Der größte Unterschied ist, dass für die Ansicht der Ressourcen im Cluster ein Access-Token benötigt wird (Abb. 3). Dieses Token wird im nächsten Teil dieser Artikelserie erstellt.
Abb. 3: Azure Arc benötigt ein Token für den Zugriff auf die Clusterressourcen
Eine Anforderung an das Projekt lautet, dass die .NET-Anwendung automatisch deployt werden kann, obwohl kein Zugriff auf den Kubernetes-Cluster über das Internet vorhanden ist. Das bedeutet, dass klassische CD Pipelines in GitHub oder Azure DevOps nicht funktionieren, weil diese die Änderungen über das Internet in den Cluster pushen.
Die Lösung für dieses Problem besteht darin, dass der Kubernetes-Cluster prüft, ob es eine neue Version der Anwendung gibt, diese dann herunterlädt und installiert. Zusätzlich wird die gesamte Konfiguration des Clusters in Git abgelegt, wodurch Git die Single Source of Truth ist. Dieser Ansatz wird als GitOps bezeichnet. Die zwei bekanntesten GitOps-Tools sind ArgoCD [4] und Flux [5]. Beide Tools funktionieren ähnlich und sind Open Source. Allerdings lautete eine Anforderung an das Projekt, die Lösung möglichst einfach zu halten und möglichst nur Azure-Dienste zu verwenden.
Hier hilft wieder Azure Arc. Azure Arc bietet Erweiterungen an, mit denen zusätzliche Funktionalität in den Cluster gebracht werden kann. Für das Deployment kann deshalb die GitOps-Erweiterung verwendet werden, welche einen Flux Agent im Kubernetes-Cluster installiert. Dieser Agent prüft regelmäßig ein Git-Repository auf Änderungen und lädt diese herunter. Da die Verbindung vom Cluster nach außen geöffnet wird, wird die Anforderung, dass der Cluster nicht über das Internet erreichbar sein soll, erfüllt.
Abbildung 4 zeigt den Ablauf, wie Änderungen im Cluster deployt werden. Microsoft empfiehlt, dabei zwei Git-Repositorys zu verwenden, um den Code für die Anwendung vom Code für die Konfiguration des Clusters zu trennen. Dieser Ansatz folgt dem Separation-of-Concerns-Prinzip und erlaubt es, verschiedene...