Esercizio - Implementare la resilienza dell'infrastruttura con Kubernetes

Completato

Nell'unità precedente è stata implementata la resilienza aggiungendo codice di gestione degli errori con l'estensione di resilienza nativa .NET. Tuttavia, questa modifica si applica solo al servizio modificato. L'aggiornamento di un'app di grandi dimensioni con molti servizi non sarebbe molto semplice.

Anziché usare la resilienza basata sul codice, questa unità usa un approccio denominato resilienza basata sull'infrastruttura che estende l'intera app. Si eseguiranno le seguenti attività:

  • Ridistribuire l'app senza resilienza in Kubernetes.
  • Distribuire Linkerd nel cluster Kubernetes.
  • Configurare l'app per l'uso di Linkerd per la resilienza.
  • Esplorare il comportamento dell'app con Linkerd.

Ridistribuire l'app

Prima di applicare Linkerd, ripristinare lo stato dell'app precedente all'aggiunta della resilienza basata sul codice. Per ripristinare, seguire questa procedura:

  1. Nel pannello inferiore selezionare la scheda TERMINALE ed eseguire i comandi Git seguenti per annullare le modifiche:

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

Installare Kubernetes

Nello spazio di codice installare Kubernetes e k3d. k3d è uno strumento che esegue un cluster Kubernetes a nodo singolo all'interno di una macchina virtuale (VM) nel computer locale. È utile per testare le distribuzioni di Kubernetes in locale e viene eseguito correttamente all'interno di uno spazio di codice.

Eseguire questi comandi per installare Kubernetes e MiniKube:

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

Distribuire i servizi eShop nell'hub Docker

Le immagini locali dei servizi compilati devono essere ospitate in un registro contenitori da distribuire in Kubernetes. In questa unità si usa Docker Hub come registro contenitori.

Eseguire questi comandi per eseguire il push delle immagini nell'hub Docker:

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

Convertire il file docker-compose in manifesti Kubernetes

Al momento si definisce il modo in cui viene eseguita l'app in Docker. Kubernetes usa un formato diverso per definire la modalità di esecuzione dell'app. È possibile usare uno strumento denominato Kompose per convertire il file docker-compose in manifesti Kubernetes.

  1. È necessario modificare questi file per usare le immagini di cui è stato eseguito il push nell'hub Docker.

  2. Nello spazio di codice aprire il file backend-deploy.yml.

  3. Sostituire questa riga:

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

    Sostituire il segnaposto [YOUR DOCKER USER NAME] con il nome utente Docker effettivo.

  4. Ripetere questi passaggi per il file frontend-deploy.yml .

  5. Sostituire questa riga:

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

    Sostituire il segnaposto [YOUR DOCKER USER NAME] con il nome utente Docker effettivo.

  6. Distribuire l'app eShop in Kubernetes:

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

    L'output dovrebbe essere simile ai messaggi seguenti:

    deployment.apps/productsbackend created
    service/productsbackend created
    deployment.apps/storefrontend created
    service/storefrontend created
    
  7. Verificare che tutti i servizi siano in esecuzione.

    kubectl get pods
    

    L'output dovrebbe essere simile ai messaggi seguenti:

    NAME                        READY   STATUS    RESTARTS   AGE
    backend-66f5657758-5gnkw    1/1     Running   0          20s
    frontend-5c9d8dbf5f-tp456   1/1     Running   0          20s
    
  8. Passare alla scheda PORTE; per visualizzare l'eShop in esecuzione in Kubernetes selezionare l'icona del globo accanto alla porta front-end (32000).

Installare linkerd

Il contenitore di sviluppo richiede l'installazione dell'interfaccia della riga di comando linkerd. Eseguire il comando seguente per verificare che i prerequisiti di Linkerd siano soddisfatti:

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

Compare una variante dell'output seguente:

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 √

Distribuire Linkerd in Kubernetes

Per prima cosa, eseguire il comando seguente per installare le definizioni di risorse personalizzate (CRD):

linkerd install --crds | kubectl apply -f -

Eseguire poi il comando seguente:

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

Nel comando precedente:

  • linkerd install genera un manifesto Kubernetes con le risorse del piano di controllo necessarie.
  • Il manifesto generato viene inviato tramite pipe a kubectl apply, che installa le risorse del piano di controllo nel cluster Kubernetes.

La prima riga dell'output mostra che il piano di controllo è stato installato nello specifico spazio dei nomi linkerd. L'output rimanente rappresenta gli oggetti da creare.

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

Convalidare la distribuzione di Linkerd

Esegui questo comando:

linkerd check

Il comando precedente analizza le configurazioni del piano di controllo e dell'interfaccia della riga di comando di Linkerd. Se Linkerd è configurato correttamente, viene visualizzato l'output seguente:

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 √

Suggerimento

Per visualizzare l'elenco dei componenti di Linkerd installati, eseguire il comando seguente:kubectl -n linkerd get deploy

Configurare l'app per l'uso di Linkerd

Linkerd viene distribuito, ma non è configurato. Il comportamento dell'app è invariato.

Linkerd non è a conoscenza degli elementi interni del servizio e non è in grado di determinare se è opportuno ritentare una richiesta non riuscita. Non è ad esempio consigliabile ritentare una funzione HTTP POST non riuscita per un pagamento. Per questo motivo è necessario un profilo del servizio. Un profilo del servizio è una risorsa Kubernetes personalizzata che definisce le route per il servizio. Questo profilo abilita anche le funzionalità per singola route, ad esempio le ripetizioni dei tentativi e i timeout. Linkerd ritenta solo le route configurate nel manifesto del profilo del servizio.

Per brevità, è necessario implementare Linkerd solo per i servizi di aggregazione e di riscatto dei buoni sconto. Per implementare Linkerd per questi due servizi, sarà necessario:

  • Modificare le distribuzioni eShop in modo che Linkerd crei il contenitore proxy nei pod.
  • Per configurare le ripetizioni dei tentativi nella route del servizio di riscatto dei buoni sconto aggiungere un oggetto profilo del servizio al cluster.

Modificare le distribuzioni eShop

I servizi di riscatto dei buoni sconto devono essere configurati per l'uso dei contenitori proxy Linkerd.

  1. Aggiungere l'linkerd.io/inject: enabledannotazione al file backend-deploy.yml nei metadati del modello.

      template:
        metadata:
          annotations:
            linkerd.io/inject: enabled
          labels: 
    
  2. Aggiungere l'annotazione linkerd.io/inject: enabled al file frontend-deploy.yml nella stessa posizione.

  3. Aggiornare le distribuzioni nel cluster Kubernetes:

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

Applicare il profilo del servizio Linkerd per il servizio prodotto

Il manifesto del profilo del servizio per il servizio prodotto è:

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

Il manifesto precedente è configurato così:

  • Qualsiasi route HTTP GET idempotente corrispondente al modello /api/Product possa essere ritentata.
  • Le ripetizioni dei tentativi possano aggiungere non più del 20% al carico della richiesta, con in più altri 10 tentativi "gratuiti" al secondo.

Eseguire il comando seguente per usare il profilo del servizio nel cluster Kubernetes:

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

Viene visualizzato l'output seguente:

serviceprofile.linkerd.io/backend created

Installare il monitoraggio nella mesh del servizio

Linkerd include estensioni per offrire funzionalità aggiuntive. Installare l'estensione viz e visualizzare lo stato dell'app nel dashboard di Linkerd.

  1. Nel terminale eseguire questo comando per installare l'estensione:

    linkerd viz install | kubectl apply -f -
    
  2. Visualizzare il dashboard con questo comando:

    linkerd viz dashboard
    

    passare alla scheda PORTE e visualizzare una nuova porta inoltrata con un processo di dashboard linkerd viz in esecuzione. Selezionare Apri nel browser per aprire il dashboard.

  3. Nel dashboard Linkerd selezionare Spazi dei nomi.

  4. In Metriche HTTP selezionare predefinita.

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

Testare la resilienza di Linkerd

Dopo aver verificato l'integrità dei contenitori ridistribuiti, attenersi alla procedura seguente per testare il comportamento dell'app con Linkerd:

  1. Controllare lo stato dei pod in esecuzione con questo comando:

    kubectl get pods --all-namespaces
    
  2. arrestare tutti i pod del servizio prodotto:

    kubectl scale deployment productsbackend --replicas=0
    
  3. passare all'app Web eShop e provare a visualizzare i prodotti. Si verifica un ritardo fino al messaggio di errore, "Si è verificato un problema durante il caricamento dei prodotti. Riprovare più tardi."

  4. Riavviare tutti i pod del servizio prodotto:

    kubectl scale deployment productsbackend --replicas=1
    
  5. l'app dovrebbe ora visualizzare i prodotti.

Linkerd segue un approccio diverso alla resilienza rispetto a quello esaminato per resilienza basata sul codice. Linkerd ha ritentato in modo trasparente l'operazione più volte in rapida successione. Non è necessario modificare l'app per supportare questo comportamento.

Informazioni aggiuntive

Per altre informazioni sulla configurazione di Linkerd, vedere le risorse seguenti: