Exercice : implémenter la résilience de l’infrastructure avec Kubernetes

Effectué

Dans l’unité précédente, vous avez implémenté la résilience en ajoutant du code de gestion des défaillances à l’aide de l’extension de résilience native .NET. Toutefois, cette modification s’applique uniquement au service que vous avez modifié. La mise à jour d’une application de grande taille avec de nombreux services serait une opération non négligeable.

Au lieu d’utiliser la résilience basée sur le code, cette unité utilise une approche appelée résilience basée sur l’infrastructure qui couvre l’ensemble de l’application. Vous allez :

  • Redéployez l’application sans aucune résilience dans Kubernetes.
  • Déployez Linkerd dans votre cluster Kubernetes.
  • configurer l’application pour qu’elle utilise Linkerd pour la résilience
  • explorer le comportement de l’application avec Linkerd.

Redéployer l’application

Avant d’appliquer Linkerd, rétablissez l’état de l’application comme il était avant l’ajout de la résilience basée sur le code. Pour effectuer une restauration, suivez ces étapes :

  1. Dans le volet inférieur, sélectionnez l’onglet TERMINAL et exécutez les commandes git suivantes pour annuler vos modifications :

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

Installer Kubernetes

Dans votre codespace, installez Kubernetes et k3d. k3d est un outil qui exécute un cluster Kubernetes à nœud unique dans une machine virtuelle sur votre ordinateur local. Il est utile de tester des déploiements Kubernetes localement et s’exécute correctement dans un codespace.

Exécutez ces commandes pour installer Kubernetes et 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

Déployer les services eShop sur Docker Hub

Les images locales de vos services que vous créez doivent être hébergées dans un registre de conteneurs pour être déployables dans Kubernetes. Dans cette unité, vous utilisez Docker Hub comme étant votre registre de conteneurs.

Exécutez ces commandes pour envoyer (push) vos images vers Docker Hub :

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

Convertir votre fichier docker-compose en manifestes Kubernetes

Maintenant, vous définissez le mode d’exécution de votre application dans Docker. Kubernetes utilise un format différent pour définir la façon dont votre application s’exécute. Vous pouvez utiliser un outil appelé Kompose pour convertir votre fichier docker-compose en manifestes Kubernetes.

  1. Vous devez modifier ces fichiers pour utiliser les images que vous avez envoyées (push) à Docker Hub.

  2. Dans le codespace, ouvrez le fichier backend-deploy.yml.

  3. Remplacez cette ligne :

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

    Remplacez l’espace réservé [YOUR DOCKER USERNAME] par votre nom d’utilisateur Docker réel.

  4. Répétez ces étapes pour le fichier frontend-deploy.yml.

  5. Remplacez cette ligne :

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

    Remplacez l’espace réservé [YOUR DOCKER USERNAME] par votre nom d’utilisateur Docker réel.

  6. Déployez l’application eShop dans Kubernetes :

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

    Vous devriez obtenir un résultat similaire aux messages suivants :

    deployment.apps/productsbackend created
    service/productsbackend created
    deployment.apps/storefrontend created
    service/storefrontend created
    
  7. Vérifiez que tous les services sont en cours d’exécution :

    kubectl get pods
    

    Vous devriez obtenir un résultat similaire aux messages suivants :

    NAME                        READY   STATUS    RESTARTS   AGE
    backend-66f5657758-5gnkw    1/1     Running   0          20s
    frontend-5c9d8dbf5f-tp456   1/1     Running   0          20s
    
  8. Basculez vers l’onglet PORTS pour afficher l’eShop en cours d’exécution sur Kubernetes, sélectionnez l’icône de globe en regard du Front End (32000).

Installer Linkerd

Le conteneur de développement doit avoir l’interface CLI Linkerd installée. Exécutez la commande suivante pour confirmer que les conditions préalables de Linkerd sont remplies :

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

Une variante de la sortie suivante apparaît :

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 √

Déployer Linkerd sur Kubernetes

Exécutez d’abord la commande suivante pour installer les définitions de ressources personnalisées (CRD, Custom Resource Definition) :

linkerd install --crds | kubectl apply -f -

Ensuite, exécutez la commande suivante :

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

Dans la commande précédente :

  • linkerd install génère un manifeste Kubernetes avec les ressources de plan de contrôle nécessaires.
  • Le manifeste généré est dirigé vers kubectl apply qui installe ces ressources de plan de contrôle dans le cluster Kubernetes.

La première ligne de la sortie indique que le plan de contrôle a été installé dans son propre espace de noms linkerd. La sortie restante représente les objets en cours de création.

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

Valider le déploiement Linkerd

Exécutez la commande suivante :

linkerd check

La commande précédente analyse les configurations de l’interface CLI et du plan de contrôle Linkerd. Si Linkerd est correctement configuré, la sortie suivante s’affiche :

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 √

Conseil

Pour afficher une liste des composants Linkerd qui ont été installés, exécutez cette commande : kubectl -n linkerd get deploy

Configurer l’application pour utiliser Linkerd

Linkerd est déployé, mais il n’est pas configuré. Le comportement de l’application est inchangé.

Linkerd ne tient pas compte des internes de service et ne peut pas déterminer s’il est approprié de retenter une demande ayant échoué. Par exemple, il serait inapproprié de retenter une opération HTTP POST ayant échoué pour un paiement. Un profil de service est nécessaire pour cette raison. Un profil de service est une ressource Kubernetes personnalisée qui définit des itinéraires pour le service. Il active également les fonctionnalités par itinéraire, telles que les nouvelles tentatives et les délais d’expiration. Linkerd réessaie uniquement les itinéraires configurés dans le manifeste du profil de service.

Par souci de concision, implémentez Linkerd uniquement sur les services de coupon et d’agrégation. Pour implémenter Linkerd pour ces deux services, vous allez :

  • Modifiez les déploiements eShop pour que Linkerd crée son conteneur proxy dans les pods.
  • Pour configurer les nouvelles tentatives sur l’itinéraire du service de coupon, ajoutez un objet de profil de service au cluster.

Modifier les déploiements eShop

Les services doivent être configurés pour utiliser des conteneurs de proxy Linkerd.

  1. Ajoutez l’annotation linkerd.io/inject: enabled au fichier backend-deploy.yml sous les métadonnées du modèle.

      template:
        metadata:
          annotations:
            linkerd.io/inject: enabled
          labels: 
    
  2. Ajoutez l’annotation linkerd.io/inject: enabled au fichier frontend-deploy.yml au même endroit.

  3. Mettez à jour les déploiements dans le cluster Kubernetes :

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

Appliquer le profil de service Linkerd pour le service de produit

Le manifeste du profil de service pour le service de produit est :

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

Le manifeste précédent est configuré afin que :

  • tout itinéraire GET HTTP idempotent correspondant au modèle /api/Product puisse être retenté.
  • les nouvelles tentatives ne peuvent pas ajouter plus de 20 % supplémentaires à la charge de la requête, plus 10 nouvelles tentatives « gratuites » par seconde.

Exécutez la commande suivante pour utiliser le profil de service dans le 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

Vous obtenez la sortie suivante :

serviceprofile.linkerd.io/backend created

Installer le monitoring sur le maillage de service

Linkerd dispose d’extensions pour vous offrir des fonctionnalités supplémentaires. Installez l’extension viz et affichez l’état de l’application dans le tableau de bord Linkerd.

  1. Dans le terminal, exécutez cette commande pour installer l’extension :

    linkerd viz install | kubectl apply -f -
    
  2. Affichez le tableau de bord avec cette commande :

    linkerd viz dashboard
    

    Accédez à l’onglet PORTS pour voir un nouveau port transféré avec un processus du tableau de bord viz linkerd en cours d’exécution. Sélectionnez Ouvrir dans le navigateur pour ouvrir le tableau de bord.

  3. Dans le tableau de bord Linkerd, sélectionnez Espaces de noms.

  4. Sous Métriques HTTP, sélectionnez par défaut.

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

Tester la résilience Linkerd

Une fois que les conteneurs redéployés sont sains, procédez comme suit pour tester le comportement de l’application avec Linkerd :

  1. Vérifiez l’état des pods en cours d’exécution avec cette commande :

    kubectl get pods --all-namespaces
    
  2. Arrêtez tous les pods de service de produit :

    kubectl scale deployment productsbackend --replicas=0
    
  3. Accédez à l’application web eShop et essayez d’afficher les produits. Il y a un délai jusqu’à l’affichage du message d’erreur « Il y a un problème de chargement de nos produits. Réessayez plus tard. »

  4. Redémarrez tous les pods de service de produit :

    kubectl scale deployment productsbackend --replicas=1
    
  5. L’application doit maintenant afficher les produits.

Linkerd suit une approche différente de la résilience par rapport à ce que vous avez vu avec la résilience basée sur le code. Linkerd a retenté de manière transparente l’opération plusieurs fois en succession rapide. Vous n’avez pas besoin de modifier l’application pour qu’elle prenne en charge ce comportement.

Informations supplémentaires

Pour plus d'informations sur la configuration Linkerd, consultez les ressources suivantes :