Esercizio - Implementare la resilienza dell'infrastruttura con Kubernetes
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:
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.
È necessario modificare questi file per usare le immagini di cui è stato eseguito il push nell'hub Docker.
Nello spazio di codice aprire il file backend-deploy.yml.
Sostituire questa riga:
containers: - image: [YOUR DOCKER USER NAME]/productservice:latest
Sostituire il segnaposto [YOUR DOCKER USER NAME] con il nome utente Docker effettivo.
Ripetere questi passaggi per il file frontend-deploy.yml .
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.
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
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
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.
Aggiungere l'
linkerd.io/inject: enabled
annotazione al file backend-deploy.yml nei metadati del modello.template: metadata: annotations: linkerd.io/inject: enabled labels:
Aggiungere l'annotazione
linkerd.io/inject: enabled
al file frontend-deploy.yml nella stessa posizione.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.
Nel terminale eseguire questo comando per installare l'estensione:
linkerd viz install | kubectl apply -f -
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.
Nel dashboard Linkerd selezionare Spazi dei nomi.
In Metriche HTTP selezionare predefinita.
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:
Controllare lo stato dei pod in esecuzione con questo comando:
kubectl get pods --all-namespaces
arrestare tutti i pod del servizio prodotto:
kubectl scale deployment productsbackend --replicas=0
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."
Riavviare tutti i pod del servizio prodotto:
kubectl scale deployment productsbackend --replicas=1
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: