Übung: Implementieren von Infrastrukturresilienz mit Kubernetes

Abgeschlossen

In der vorherigen Lerneinheit haben Sie mithilfe der nativen .NET-Resilienzerweiterung Resilienz durch das Hinzufügen von Fehlerbehandlungscode implementiert. Diese Änderung gilt jedoch nur für den Dienst, den Sie geändert haben. Das Aktualisieren einer großen App mit vielen Diensten wäre kein leichtes Unterfangen.

Anstelle der codebasierten Resilienz wird in dieser Lerneinheit ein Ansatz verwendet, der als infrastrukturbasierte Resilienz bezeichnet wird und die gesamte App umfasst. Dieses Modul umfasst Folgendes:

  • Stellen Sie die App erneut ohne jegliche Resilienz in Kubernetes bereit.
  • Stellen Sie Linkerd in Ihrem Kubernetes-Cluster bereit.
  • Konfigurieren der App für die Verwendung von Linkerd für Resilienz
  • Untersuchen des App-Verhaltens mit Linkerd

Erneutes Bereitstellen der App

Bevor Sie Linkerd anwenden, sollten Sie den Zustand der App vor dem Hinzufügen der codebasierten Resilienz wiederherstellen. Führen Sie zum Wiederherstellen die folgenden Schritte aus:

  1. Wählen Sie im unteren Panel die Registerkarte TERMINAL aus, und führen Sie die folgenden Git-Befehle aus, um Ihre Änderungen rückgängig zu machen:

    cd Store
    git checkout Program.cs
    git checkout Store.csproj
    cd ..
    dotnet publish /p:PublishProfile=DefaultContainer
    

Installieren von Kubernetes

Installieren Sie in Ihrem Codespace Kubernetes und k3d. Bei k3d handelt es sich um ein Tool, das einen Einzelknotencluster von Kubernetes in einer VM auf Ihrem lokalen Computer ausführt. Es ist für das lokale Testen von Kubernetes-Bereitstellungen und Ausführungen innerhalb eines Codespace hilfreich.

Führen Sie die folgenden Befehle aus, um Kubernetes und MiniKube zu installieren:

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubectl

curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
k3d cluster create devcluster --config k3d.yml

Bereitstellen der eShop-Dienste in Docker Hub

Die lokalen Images der von Ihnen erstellten Dienste müssen in einer Containerregistrierung gehostet werden, damit sie in Kubernetes bereitgestellt werden können. In dieser Lerneinheit verwenden Sie Docker Hub als Ihre Containerregistrierung.

Führen Sie diese Befehle aus, um Ihre Images an Docker Hub zu pushen:

sudo docker login

sudo docker tag products [your username]/productservice
sudo docker tag store [your username]/storeimage

sudo docker push [your username]/productservice
sudo docker push [your username]/storeimage

Konvertieren Ihrer Docker-Compose-Datei in Kubernetes-Manifeste

Momentan haben Sie definiert, wie Ihre App in Docker ausgeführt wird. Kubernetes verwendet ein anderes Format, um festzulegen, wie Ihre App ausgeführt wird. Sie verwenden ein Tool namens Kompose, um Ihre Docker-Compose-Datei in Kubernetes-Manifeste zu konvertieren.

  1. Sie müssen diese Dateien bearbeiten, um die Images zu verwenden, die Sie an Docker Hub gepusht haben.

  2. Öffnen Sie im Codespace die Datei backend-deploy.yml.

  3. Ändern Sie diese Zeile:

      containers:
        - image: [YOUR DOCKER USER NAME]/productservice:latest
    

    Ersetzen Sie den Platzhalter [YOUR DOCKER USER NAME] durch Ihren tatsächlichen Docker-Benutzernamen.

  4. Wiederholen Sie diese Schritte für die Datei frontend-deploy.yml.

  5. Ändern Sie diese Zeile:

      containers:
      - name: storefrontend
        image: [YOUR DOCKER USER NAME]/storeimage:latest  
    

    Ersetzen Sie den Platzhalter [YOUR DOCKER USER NAME] durch Ihren tatsächlichen Docker-Benutzernamen.

  6. Stellen Sie die eShop-App in Kubernetes bereit:

    kubectl apply -f backend-deploy.yml,frontend-deploy.yml  
    

    Sie sollten eine Ausgabe ähnlich der folgenden Antwort erhalten:

    deployment.apps/productsbackend created
    service/productsbackend created
    deployment.apps/storefrontend created
    service/storefrontend created
    
  7. Überprüfen Sie, ob alle Dienste ausgeführt werden:

    kubectl get pods
    

    Sie sollten eine Ausgabe ähnlich der folgenden Antwort erhalten:

    NAME                        READY   STATUS    RESTARTS   AGE
    backend-66f5657758-5gnkw    1/1     Running   0          20s
    frontend-5c9d8dbf5f-tp456   1/1     Running   0          20s
    
  8. Wechseln Sie zur Registerkarte PORTS, um die in Kubernetes ausgeführten eShop-App anzuzeigen, und wählen Sie das Globussymbol neben dem Port Front End (32000) aus.

Installieren von Linkerd

Der Entwicklercontainer benötigt eine Installation der Linkerd-CLI. Führen Sie den folgenden Befehl aus, um zu bestätigen, dass die Voraussetzungen für Linkerd erfüllt sind:

curl -sL run.linkerd.io/install | sh
export PATH=$PATH:/home/vscode/.linkerd2/bin
linkerd check --pre

Eine Variation der folgenden Ausgabe wird angezeigt:

kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version

pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
√ can create non-namespaced resources
√ can create ServiceAccounts
√ can create Services
√ can create Deployments
√ can create CronJobs
√ can create ConfigMaps
√ can create Secrets
√ can read Secrets
√ can read extension-apiserver-authentication configmap
√ no clock skew detected

pre-kubernetes-capability
-------------------------
√ has NET_ADMIN capability
√ has NET_RAW capability

linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date

Status check results are √

Bereitstellen von Linkerd in Kubernetes

Führen Sie zunächst den folgenden Befehl aus, um die benutzerdefinierten Ressourcendefinitionen (Custom Resource Definitions, CRDs) zu installieren:

linkerd install --crds | kubectl apply -f -

Führen Sie dann den folgenden Befehl aus:

linkerd install --set proxyInit.runAsRoot=true | kubectl apply -f -

Für den obigen Befehl gilt Folgendes:

  • linkerd install generiert ein Kubernetes-Manifest mit den erforderlichen Steuerungsebenenressourcen.
  • Das generierte Manifest wird an kubectl apply weitergeleitet, wodurch diese Steuerungsebenenressourcen im Kubernetes-Cluster installiert werden.

Die erste Zeile der Ausgabe zeigt, dass die Steuerungsebene in einem eigenen linkerd-Namespace installiert wurde. Die verbleibende Ausgabe stellt die Objekte dar, die erstellt werden.

namespace/linkerd created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-identity created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-identity created
serviceaccount/linkerd-identity created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-controller created

Überprüfen der Linkerd-Bereitstellung

Führen Sie den folgenden Befehl aus:

linkerd check

Mit dem vorangehenden Befehl werden die Konfigurationen der Linkerd-CLI und der Steuerungsebene analysiert. Wenn Linkerd ordnungsgemäß konfiguriert ist, wird die folgende Ausgabe angezeigt:

kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version

linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ controller pod is running
√ can initialize the client
√ can query the control plane API

linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist
√ control plane PodSecurityPolicies exist

linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor

linkerd-api
-----------
√ control plane pods are ready
√ control plane self-check
√ [kubernetes] control plane can talk to Kubernetes
√ [prometheus] control plane can talk to Prometheus
√ tap api service is running

linkerd-version
---------------
√ can determine the latest version
√ CLI is up to date

control-plane-version
---------------------
√ control plane is up to date
√ control plane and CLI versions match

linkerd-addons
--------------
√ 'linkerd-config-addons' config map exists

linkerd-grafana
---------------
√ grafana add-on service account exists
√ grafana add-on config map exists
√ grafana pod is running

Status check results are √

Tipp

Führen Sie den folgenden Befehl aus, um eine Liste der installierten Linkerd-Komponenten anzuzeigen: kubectl -n linkerd get deploy

Konfigurieren der App für die Verwendung von Linkerd

Linkerd wird bereitgestellt, ist aber nicht konfiguriert. Das Verhalten der App ist unverändert.

Linkerd kennt keine Besonderheiten von Diensten und kann nicht bestimmen, ob es angemessen ist, eine fehlerhafte Anforderung zu wiederholen. Es wäre beispielsweise nicht empfehlenswert, eine fehlerhafte HTTP POST-Methode für eine Zahlung zu wiederholen. Aus diesem Grund ist ein Dienstprofil erforderlich. Ein Dienstprofil ist eine benutzerdefinierte Kubernetes-Ressource, die Routen für den Dienst definiert. Es ermöglicht auch routenspezifische Features wie Wiederholungen und Timeouts. Linkerd wiederholt Versuche nur für Routen, die im Dienstprofilmanifest konfiguriert sind.

Der Kürze halber implementieren Sie Linkerd hier nur für den Aggregator und den Coupondienst. Sie müssen folgende Schritte ausführen, um Linkerd für diese beiden Dienste zu implementieren:

  • Ändern Sie die eShop-Bereitstellungen, damit Linkerd seinen Proxycontainer in den Pods erstellt.
  • Fügen Sie dem Cluster ein Dienstprofilobjekt hinzu, um Wiederholungsversuche für die Route des Coupondiensts zu konfigurieren.

Ändern der eShop-Bereitstellungen

Die Dienste müssen für die Verwendung von Linkerd-Proxycontainern konfiguriert werden.

  1. Fügen Sie die linkerd.io/inject: enabled-Anmerkung der Datei backend-deploy.yml unter Vorlagenmetadaten hinzu.

      template:
        metadata:
          annotations:
            linkerd.io/inject: enabled
          labels: 
    
  2. Fügen Sie die linkerd.io/inject: enabled-Anmerkung zur Datei fromkend-deploy.yml an derselben Stelle hinzu.

  3. Aktualisieren Sie die Bereitstellungen im Kubernetes-Cluster:

    kubectl apply -f backend-deploy.yml,frontend-deploy.yml
    

Anwenden des Linkerd-Dienstprofils für den Produktdienst

Das Dienstprofilmanifest für den Produktdienst sieht folgendermaßen aus:

apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: backend
  namespace: default
spec:
  routes:
  - condition:
      method: GET
      pathRegex: /api/Product
    name: GET /v1/products
    isRetryable: true
  retryBudget:
    retryRatio: 0.2
    minRetriesPerSecond: 10
    ttl: 120s

Das vorherige Manifest ist so konfiguriert, dass Folgendes gilt:

  • Jede idempotente HTTP GET-Route, die mit dem Muster /api/Product übereinstimmt, kann wiederholt werden.
  • Bei Wiederholungen können der Anforderungslast nicht mehr als zusätzlich 20 Prozent plus weitere zehn „freie“ Wiederholungen pro Sekunde hinzugefügt werden.

Führen Sie den folgenden Befehl aus, um das Dienstprofil im Kubernetes-Cluster zu verwenden:

kubectl apply -f - <<EOF
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: backend
  namespace: default
spec:
  routes:
  - condition:
      method: GET
      pathRegex: /api/Product
    name: GET /v1/products 
    isRetryable: true
  retryBudget:
    retryRatio: 0.2
    minRetriesPerSecond: 10
    ttl: 120s  
EOF

Die folgende Ausgabe wird angezeigt:

serviceprofile.linkerd.io/backend created

Installieren der Überwachung im Dienstnetz

Linkerd verfügt über Erweiterungen, die Ihnen zusätzliche Features bieten. Sie installieren die Viz-Erweiterung und zeigen den App-Status im Linkerd-Dashboard an.

  1. Führen Sie im Terminal den folgenden Befehl aus, um die Erweiterung zu installieren:

    linkerd viz install | kubectl apply -f -
    
  2. Zeigen Sie das Dashboard mit diesem Befehl an:

    linkerd viz dashboard
    

    Wechseln Sie zur Registerkarte PORTS und es wird ein neuer Port angezeigt, der mit einem laufenden Prozess des linkerd viz-Dashboards weitergeleitet wurde. Wählen Sie Im Browser öffnen aus, um das Dashboard zu öffnen.

  3. Wählen Sie im Linkerd-Dashboard Namespaces aus.

  4. Wählen Sie unter „HTTP Metrics“ die Option default aus.

    Screenshot showing the Linkerd dashboard with both the frontend and backend.

Testen der Linkerd-Resilienz

Nachdem die neu bereitgestellten Container fehlerfrei sind, führen Sie die folgenden Schritte aus, um das Verhalten der App mit Linkerd zu testen:

  1. Überprüfen Sie den Status der ausgeführten Pods mit diesem Befehl:

    kubectl get pods --all-namespaces
    
  2. Beenden Sie alle Produktdienstpods:

    kubectl scale deployment productsbackend --replicas=0
    
  3. Besuchen Sie die eShop-Web-App, und versuchen Sie, die Produkte anzuzeigen. Die folgende Fehlermeldung wird nach einer Verzögerung angezeigt: There is a problem loading our products. Versuchen Sie es später erneut.

  4. Starten Sie die Produktdienstpods neu:

    kubectl scale deployment productsbackend --replicas=1
    
  5. Die Produkte sollten jetzt in der App angezeigt werden.

Linkerd folgt einem anderen Ansatz für Resilienz als dem hier dargestellten Ansatz mit codebasierter Resilienz. Linkerd hat den Vorgang in kurzen Abständen mehrmals wiederholt. Die App musste nicht geändert werden, um dieses Verhalten zu unterstützen.

Weitere Informationen

Weitere Informationen zur Linkerd-Konfiguration finden Sie in den folgenden Ressourcen: