Übung – Implementieren der Infrastrukturresilienz mit Kubernetes

Abgeschlossen

In der vorherigen Einheit haben Sie Resilienz implementiert, indem Sie Fehlerbehandlungscode mithilfe der nativen Resilienzerweiterung .NET hinzufügen. 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 nichttrivial.

Anstatt codebasierte Resilienz zu verwenden, verwendet diese Einheit einen Ansatz, der als infrastrukturbasierte Resilienz bezeichnet wird, die die gesamte App umfasst. Sie werden folgende Aktionen ausführen:

  • Stellen Sie die App ohne Resilienz in Kubernetes erneut zur Anwendung.
  • Stellen Sie Linkerd in Ihrem Kubernetes-Cluster bereit.
  • Konfigurieren Sie die App für die Verwendung von Linkerd zur Resilienz.
  • Erkunden Sie das App-Verhalten mit Linkerd.

Erneutes Bereitstellen der App

Vor dem Anwenden von Linkerd können Sie die App auf einen Zustand zurücksetzen, bevor codebasierte Resilienz hinzugefügt wurde. Führen Sie zum Wiederherstellen die folgenden Schritte aus:

  1. Wählen Sie im unteren Bereich 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. k3d ist ein Tool, das einen Kubernetes-Cluster mit einem Einzigen Knoten auf einem virtuellen Computer (VM) auf Ihrem lokalen Computer ausführt. Es ist nützlich, Kubernetes-Bereitstellungen lokal zu testen und gut in einem Codespace ausgeführt zu werden.

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 auf Docker Hub

Die lokalen Images Ihrer Dienste, die Sie erstellen, müssen in einer Containerregistrierung gehostet werden, damit sie in Kubernetes bereitgestellt werden können. In dieser Einheit verwenden Sie Docker Hub als Containerregistrierung.

Führen Sie die folgenden Befehle aus, um Ihre Images an Docker Hub zu übertragen:

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 Der Docker-Compose-Datei in Kubernetes-Manifeste

Derzeit definieren Sie, wie Ihre App in Docker ausgeführt wird. Kubernetes verwendet ein anderes Format, um festzulegen, wie Ihre App ausgeführt wird. Sie können ein Tool namens Kompose verwenden, um Ihre Docker-Compose-Datei in Kubernetes-Manifeste zu konvertieren.

  1. Sie müssen diese Dateien bearbeiten, um die Bilder zu verwenden, die Sie an Docker Hub übertragen 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 [IHR DOCKER-BENUTZERNAME] durch Ihren tatsächlichen Docker-Benutzernamen.

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

  5. Ändern Sie diese Zeile:

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

    Ersetzen Sie den Platzhalter [IHR DOCKER-BENUTZERNAME] durch Ihren tatsächlichen Docker-Benutzernamen.

  6. Bereitstellen der eShop-App in Kubernetes:

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

    Die Ausgabe sollte ähnlich wie die folgenden Nachrichten angezeigt werden:

    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
    

    Die Ausgabe sollte ähnlich wie die folgenden Nachrichten angezeigt werden:

    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 den auf Kubernetes ausgeführten eShop anzuzeigen, wählen Sie das Globussymbol neben dem Front-End-Port (32000) aus.

Linkerd installieren

Der Entwicklercontainer benötigt linkerd CLI, um installiert zu werden. 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 -

Im vorherigen Befehl:

  • linkerd install generiert ein Kubernetes-Manifest mit den erforderlichen Ressourcen der Steuerebene.
  • Das generierte Manifest wird an diese Steuerebenenressourcen im Kubernetes-Cluster weitergeleitet kubectl apply.

Die erste Zeile der Ausgabe zeigt, dass die Steuerebene in einem eigenen linkerd Namespace installiert wurde. Die verbleibende Ausgabe stellt die erstellten Objekte dar.

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

Der vorstehende Befehl analysiert die Konfigurationen der Linkerd CLI und der Steuerebene. 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 ist nicht über Dienstinterne bewusst und kann nicht ermitteln, ob es geeignet ist, eine fehlgeschlagene Anforderung erneut zu versuchen. Es wäre z. B. eine schlechte Idee, einen fehlgeschlagenen HTTP POST für eine Zahlung erneut zu versuchen. Aus diesem Grund ist ein Dienstprofil erforderlich. Ein Dienstprofil ist eine benutzerdefinierte Kubernetes-Ressource, die Routen für den Dienst definiert. Außerdem werden Funktionen pro Route aktiviert, z. B. Wiederholungen und Timeouts. Linkerd führt nur Wiederholungsrouten aus, die im Dienstprofilmanifest konfiguriert sind.

Aus Platzgründen implementieren Sie Linkerd nur auf den Aggregator- und Coupon-Diensten. Um Linkerd für diese beiden Dienste zu implementieren, gehen Sie wie folgt vor:

  • Ändern Sie die eShop-Bereitstellungen so, dass Linkerd ihren Proxycontainer in den Pods erstellt.
  • Um Wiederholungen auf der Route des Coupondiensts zu konfigurieren, fügen Sie dem Cluster ein Dienstprofilobjekt hinzu.

Ä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 zur backend-deploy.yml Datei unter Vorlagenmetadaten hinzu.

      template:
        metadata:
          annotations:
            linkerd.io/inject: enabled
          labels: 
    
  2. Fügen Sie die linkerd.io/inject: enabled Anmerkung der frontend-deploy.yml Datei 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 lautet:

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 vorangehende Manifest ist so konfiguriert:

  • Jede idempotente HTTP GET-Route, die dem Muster /api/Product entspricht, kann wiederholt werden.
  • Wiederholungsversuche können der Anforderungslast nicht mehr als 20 Prozent hinzufügen, plus weitere 10 "freie" Wiederholungsversuche pro Sekunde.

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 Dienstgitter

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

  1. Führen Sie im Terminal diesen 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 sehen Sie einen neuen Port, der mit einem Prozess des ausgeführten Linkerd-Viz-Dashboards weitergeleitet wird. Wählen Sie den Im Browser öffnenden Browser aus, um das Dashboard zu öffnen.

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

  4. Wählen Sie unter HTTP-Metriken die Standardeinstellung aus.

    Screenshot des Linkerd-Dashboards mit dem Frontend und dem Back-End.

Testen der Linkerd-Resilienz

Nachdem die erneut 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 Produktservice-Pods:

    kubectl scale deployment productsbackend --replicas=0
    
  3. Wechseln Sie zur eShop-Web-App, und versuchen Sie, die Produkte anzuzeigen. Es gibt eine Verzögerung, bis die Fehlermeldung "Es gibt ein Problem beim Laden unserer Produkte. Versuchen Sie es später erneut."

  4. Starten Sie die Produktdienst-Pods neu:

    kubectl scale deployment productsbackend --replicas=1
    
  5. Die App sollte jetzt die Produkte anzeigen.

Linkerd folgt einem anderen Ansatz zur Resilienz als dem, was Sie mit codebasierter Resilienz gesehen haben. Linkerd hat den Vorgang mehrmals in schneller Folge wiederholt. Die App musste nicht geändert werden, um dieses Verhalten zu unterstützen.

Zusatzinformation

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