Déployer une application ASP.NET Core sur Google Kubernetes Engine avec Istio (Partie 2)

1. Présentation

Dans la première partie de l'atelier, vous avez créé une application ASP.NET Core, l'avez conteneurisée et déployée sur Google Kubernetes Engine (GKE), puis vous avez configuré son trafic pour qu'il soit géré par Istio.

Cette deuxième partie de l'atelier suppose que votre cluster Kubernetes et l'application du premier atelier sont déjà en cours d'exécution. Vous verrez comment Istio peut vous aider à gérer, surveiller et sécuriser vos services avec un minimum de modifications de code. Plus précisément, vous allez explorer les fonctionnalités d'Istio, telles que les métriques, le traçage, la visualisation des services, la gestion dynamique du trafic, l'injection de pannes, etc.

Points abordés

  • Comment interroger les métriques avec Prometheus.
  • Visualiser des métriques avec Grafana
  • Découvrez comment créer une version de votre service.
  • Comment épingler un service à une version spécifique
  • Découvrez comment répartir le trafic entre différentes versions.
  • Comment injecter des erreurs dans les appels de service.

Prérequis

Comment allez-vous utiliser ce tutoriel ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Quel est votre niveau d'expérience avec Google Cloud Platform ?

Débutant Intermédiaire Expert

2. Préparation

Configuration de l'environnement d'auto-formation

  1. Connectez-vous à Cloud Console, puis créez un projet ou réutilisez un projet existant. (Si vous n'avez pas encore de compte Gmail ou G Suite, vous devez en créer un.)

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID tout au long de cet atelier de programmation.

  1. Vous devez ensuite activer la facturation dans Cloud Console pour pouvoir utiliser les ressources Google Cloud.

L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Veillez à suivre les instructions de la section "Nettoyer" qui indique comment désactiver les ressources afin d'éviter les frais une fois ce tutoriel terminé. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300 $.

Démarrer Cloud Shell

Bien que Google Cloud puisse être utilisé à distance depuis votre ordinateur portable, nous allons nous servir de Google Cloud Shell pour cet atelier de programmation, un environnement de ligne de commande exécuté dans Google Cloud.

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell dnDTxS9j60RcXdTjea12HLB9paS9Gzf7PfFLE9RW8g0Qx1bz7nmCzyCu4rjluX3bOEwavOpDwioXEkzOf6xtZp6-ZbJa08jwJqtmeeW8jZ1tYfi2lyXqvW3WFHP0eAxDkQDfpO9Ljw.

yzBQBp2RC1EFvSSLYVkMA2m6LHqGsp22O81rUS5tGb9Y1FqlVhoRj_ka8V_uEjtpcirZRULMy1IjNr848uYvb9mC9RcGGqeayaLcXFfRwUGeXWChZPtWkHzUshTcqx_wJHis0X8viA

Si vous n'avez encore jamais démarré Cloud Shell, un écran intermédiaire s'affiche en dessous de la ligne de séparation pour décrire de quoi il s'agit. Si tel est le cas, cliquez sur Continuer (cet écran ne s'affiche qu'une seule fois). Voici à quoi il ressemble :

VgsaqGbKPRiqK24CqAKjSXjepuJT96PmiDqQMcySmWKx8QyW5F3G2D8JH2d08ek-YM77wWKxPvggpOFER8Hbq3aaZipTDU2o0il7A0kS3FXY_NzuujjEqDF1nsbDKkNMThrqcdMGtQ

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

7RuYr-LCKzdiE1veTFmL_lYrVxsMZ6-xDoxAnfwPPc5uFA0utmFGejvu81jGmTdbqnqxrytW3KcHT6xrMIRc3bskctnDZC5nJdpqw-LRxu3r35hL4A0BSBTtbtirfh3PKv-eOKt8Rg

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle intègre un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances réseau et l'authentification. Vous pouvez réaliser une grande partie, voire la totalité, des activités de cet atelier dans un simple navigateur ou sur votre Chromebook.

Une fois connecté à Cloud Shell, vous êtes en principe authentifié et le projet est défini avec votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

3. Tester l'application

Avant de commencer l'atelier, assurez-vous que l'application fonctionne toujours comme dans l'atelier précédent. Pour rappel, voici comment afficher l'adresse IP externe et le port de la passerelle, qui sont listés sous EXTERNAL-IP :

kubectl get svc istio-ingressgateway -n istio-system

Pour afficher l'application, vous pouvez ouvrir votre navigateur et accéder à http://<gatewayurl> :

f579a9baedc108a9.png

Si vous ne voyez pas l'application, revenez à l'atelier précédent pour vous assurer d'avoir suivi toutes les étapes et que l'application et Istio sont installés et fonctionnent correctement.

À ce stade, vous vous demandez peut-être quel est l'intérêt d'Istio. En laissant Istio gérer le trafic de votre application, vous bénéficiez sans frais de fonctionnalités telles que les métriques, le traçage, la gestion dynamique du trafic, la visualisation des services, l'injection de pannes et plus encore.

Vous commencerez par explorer les métriques à la prochaine étape.

4. Métriques avec Grafana et Prometheus

Par défaut, Istio génère certaines métriques. Vous pouvez utiliser des modules complémentaires pour interroger et visualiser ces métriques par défaut.

Prometheus

Prometheus est une solution de surveillance Open Source. Vous pouvez utiliser Prometheus pour interroger les métriques générées par Istio, mais vous devez d'abord installer le module complémentaire Prometheus.

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yaml

Vérifiez que Prometheus est en cours d'exécution :

kubectl get svc prometheus -n istio-system

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
prometheus   ClusterIP   10.31.243.62   <none>        9090/TCP   1d

Envoyez du trafic vers l'application en accédant à http://<gatewayurl> plusieurs fois ou en exécutant la commande curl.

Configurez le transfert de port pour l'interface utilisateur Prometheus :

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 8080:9090

Vous pouvez maintenant exécuter une requête en cliquant sur le bouton "Aperçu sur le Web" en haut à droite de Cloud Shell, puis sur Prévisualiser sur le port 8080 :

772a5248aa493025.png

L'interface utilisateur Prometheus s'affiche dans un nouvel onglet :

272ee63c1fe0be16.png

Pour en savoir plus sur Prometheus, consultez Interroger les métriques avec Prometheus.

Grafana

Grafana est un autre module complémentaire permettant de visualiser les métriques.

Installez Grafana. Remplacez istio-version par votre version actuelle d'Istio, par exemple 1.0.3-gke.3 :

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/grafana.yaml

Vérifiez que Grafana est en cours d'exécution :

kubectl get svc grafana -n istio-system

NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
grafana   ClusterIP   10.31.248.230   <none>        3000/TCP   1d

Envoyez du trafic vers l'application en accédant à http://<gatewayurl> plusieurs fois ou en exécutant la commande curl.

Configurez le transfert de port pour l'interface utilisateur Grafana :

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 8080:3000

Pour afficher les tableaux de bord Grafana, accédez à l'aperçu Web :

806d696d85267a37.png

524cb9f6d66f8655.png

Pour en savoir plus sur Grafana, consultez Visualiser les métriques avec Grafana.

5. Créer une version de l'application

À un moment donné, l'application que vous avez déployée en production nécessitera des corrections de bugs ou l'ajout de nouvelles fonctionnalités. Voyons à quoi ressemble ce processus.

Commençons par modifier l'application. Ouvrez l'éditeur de code depuis Cloud Shell.

mxrggIJ2Zz8E47ULCEo4NywjM-EpSkZF5c3TQgfGx4nODwP2obiQXrwQjEEaXuBhJDA2jJ5evR7TuHIy1gsqqDRFm0Wh3xhZUu9tn_xb1ygFlBm1HKJqLdfz_aK7WJS33u2IBDO2oQ

Accédez à Index.cshtml sous HelloWorldAspNetCore > Views > Home et mettez à jour l'un des messages du carrousel.

Recherchez la ligne suivante :

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core 

Remplacez-le par le message suivant :

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core on Google Cloud

Enregistrez les modifications, puis revenez à Cloud Shell. Dans HelloWorldAspNetCore,, créez l'image Docker :

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 . 

Puis, transférez-la vers Container Registry :

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 

Une fois l'image de conteneur transférée, vous pouvez déployer la nouvelle version à l'étape suivante.

6. Créer le déploiement

Pour déployer la nouvelle version, vous devez d'abord créer un déploiement pour celle-ci dans Kubernetes. Ajoutez ce qui suit à la fin du fichier aspnetcore.yaml :

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v2
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v2
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

Déployez la nouvelle version dans l'espace de noms par défaut avec kubectl :

kubectl apply -f aspnetcore.yaml
service "aspnetcore" unchanged
deployment.extensions "aspnetcore-v1" unchanged
deployment.extensions "aspnetcore-v2" created

Vérifiez que les pods attendus sont en cours d'exécution :

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s
aspnetcore-v2-5d765db-l9xmg   2/2       Running   0          1m

Testez à nouveau l'application. Obtenez l'adresse IP externe de la passerelle :

kubectl get svc istio-ingressgateway -n istio-system

Elle est indiquée sous EXTERNAL-IP. Ouvrez un navigateur en mode navigation privée et accédez à http://<replace-with-external-ip>.

Lorsque vous actualisez la page, le message "Découvrez comment créer des applications Web avec ASP.NET Core " s'affiche parfois :

11d528132dbb6cee.png

Dans d'autres cas, le message "Découvrez comment créer des applications Web avec ASP.NET Core sur Google Cloud" s'affiche :

3eb0d5be1b4cb40b.png

En effet, les déploiements v1 et v2 sont exposés derrière le même service Kubernetes (aspnetcore-service), et le VirtualService que vous avez créé dans l'atelier précédent (aspnetcore-virtualservice) utilise ce service comme hôte.

Dans l'étape suivante, vous allez associer le service au déploiement v2 à l'aide d'une DestinationRule.

7. Épingler votre service à la nouvelle version

Dans cette étape, vous épinglez votre service pour qu'il utilise le déploiement v2. Pour ce faire, vous pouvez utiliser une DestinationRule. Une ressource DestinationRule configure l'ensemble des règles à appliquer à une requête après une opération de routage VirtualService.

Une DestinationRule définit également des sous-ensembles adressables, c'est-à-dire des versions nommées, de l'hôte de destination correspondant. Ces sous-ensembles sont utilisés dans les spécifications de route VirtualService lors de l'envoi de trafic vers des versions spécifiques du service.

Créez un fichier appelé aspnetcore-destinationrule.yaml :

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: aspnetcore-destinationrule
spec:
  host: aspnetcore-service
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

Créez ensuite la DestinationRule. Cela crée deux sous-ensembles (v1 et v2) que vous pouvez utiliser à partir de VirtualService :

kubectl apply -f aspnetcore-destinationrule.yaml
destinationrule.networking.istio.io "aspnetcore-destionationrule" created

Revenez maintenant au fichier aspnetcore-virtualservice.yaml pour mettre à jour le VirtualService afin qu'il utilise le sous-ensemble v2 :

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v2

Mettez à jour le VirtualService :

kubectl apply -f aspnetcore-virtualservice.yaml

Ouvrez votre navigateur et accédez à http://<replace-with-external-ip>.. Même après plusieurs actualisations, le message "Découvrez comment créer des applications Web avec ASP.NET Core sur Google Cloud" devrait s'afficher :

3eb0d5be1b4cb40b.png

8. Répartir le trafic entre les versions

Il peut arriver que vous souhaitiez répartir le trafic entre les versions pour effectuer des tests. Par exemple, vous pouvez envoyer 75 % du trafic vers la version v1 du service et 25 % vers la version v2. Vous pouvez facilement y parvenir avec Istio. Créez un fichier aspnetcore-virtualservice-weights.yaml pour faire référence aux deux sous-ensembles avec des pondérations différentes :

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v1
      weight: 75
    - destination:
        host: aspnetcore-service
        subset: v2
      weight: 25

Mettez à jour le VirtualService :

kubectl apply -f aspnetcore-virtualservice-weights.yaml

Maintenant, lorsque vous actualisez le navigateur, vous devriez voir les versions v1 et v2 diffusées dans un rapport d'environ 3:1.

Pour en savoir plus, consultez la section Répartition du trafic dans Istio.

9. Injecter des défaillances

Une autre tâche de développement utile pour les tests consiste à injecter des défaillances ou des retards dans le trafic et à observer le comportement des services en réponse.

Par exemple, vous pouvez renvoyer une réponse de requête incorrecte (HTTP 400) pour 50 % du trafic vers la version v1. Créez un fichier aspnetcore-virtualservice-fault-abort.yaml correspondant à ce qui suit :

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      abort:
        percentage:
          value: 50
        httpStatus: 400
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

Mettez à jour le VirtualService :

kubectl apply -f aspnetcore-virtualservice-fault-abort.yaml

Maintenant, lorsque vous actualisez le navigateur, vous devriez constater que le service v1 renvoie un code de réponse HTTP 400 la moitié du temps.

Ou peut-être souhaitez-vous ajouter un délai de cinq secondes aux requêtes. Créez un fichier aspnetcore-virtualservice-fault-delay.yaml correspondant à ce qui suit :

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      delay:
        fixedDelay: 5s
        percentage:
          value: 100
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

Mettez à jour le VirtualService :

kubectl apply -f aspnetcore-virtualservice-fault-delay.yaml

Maintenant, lorsque vous actualisez le navigateur, vous devriez constater que les requêtes sont retardées de cinq secondes.

Pour en savoir plus sur les fonctionnalités Istio telles que les délais avant expiration, les nouvelles tentatives, les règles conditionnelles, les disjoncteurs et plus encore, consultez Fonctionnalités de gestion du trafic.

10. Félicitations !

Nous espérons que cet atelier vous a donné un aperçu de ce qu'Istio peut faire pour vos services prêts à l'emploi. Pour en savoir plus sur Istio et GKE.

Étapes suivantes

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.

11. Nettoyage

Vous pouvez supprimer l'application et désinstaller Istio, ou simplement supprimer le cluster Kubernetes.

Supprimer l'application

Pour supprimer l'application :

kubectl delete -f aspnetcore-gateway.yaml
kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore-destinationrule.yaml
kubectl delete -f aspnetcore.yaml

Pour vérifier que l'application a bien disparu :

kubectl get gateway 
kubectl get virtualservices
kubectl get destinationrule
kubectl get pods

Désinstaller Istio

Pour supprimer Istio :

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

Pour vérifier qu'Istio a bien été supprimé :

kubectl get pods -n istio-system

Supprimer un cluster Kubernetes

gcloud container clusters delete hello-dotnet-cluster