Exemple de Cloud Service Mesh: déploiements Canary


Dans ce tutoriel, vous allez découvrir un cas d'utilisation courant: déployer un déploiement Canary avec Cloud Service Mesh à l'aide des API Istio.

Qu'est-ce qu'un déploiement Canary ?

Un déploiement Canary achemine un petit pourcentage du trafic vers une nouvelle version d'un microservice, puis augmente progressivement ce pourcentage lors de l'arrêt progressif de l'ancienne version. Si un problème survient au cours de ce processus, le trafic peut être basculé vers la version antérieure. Avec Cloud Service Mesh, vous pouvez acheminer le trafic pour vous assurer que les nouveaux services sont introduits en toute sécurité.

Pour en savoir plus sur les tests Canary, consultez la page Stratégies de déploiement et de test d'applications.

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Une fois que vous aurez terminé ce tutoriel, évitez de payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.

Avant de commencer

Déployer Online Boutique

  1. Définissez le contexte actuel de kubectl sur le cluster dans lequel vous prévoyez de déployer Online Boutique. La commande varie selon que vous avez provisionné Cloud Service Mesh sur un cluster GKE ou sur un cluster Kubernetes en dehors de GKE:

    GKE sur Google Cloud

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    

    GKE en dehors de Google Cloud

    kubectl config use-context CLUSTER_NAME 
    
  2. Créez l'espace de noms pour l'exemple d'application et la passerelle d'entrée:

    kubectl create namespace onlineboutique
    
  3. Ajoutez un libellé à l'espace de noms onlineboutique pour injecter automatiquement les proxys Envoy. Suivez les étapes permettant d'activer l'injection side-car automatique.

  4. Déployez l'exemple d'application. Pour ce tutoriel, vous allez déployer Online Boutique, une application de démonstration de microservices.

    kubectl apply \
    -n onlineboutique \
    -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/shared/online-boutique/kubernetes-manifests.yaml
    
  5. Ajoutez une étiquette version=v1 au déploiement productcatalog en exécutant la commande suivante:

    kubectl patch deployments/productcatalogservice -p '{"spec":{"template":{"metadata":{"labels":{"version":"v1"}}}}}' \
    -n onlineboutique
    

    Affichez les services que vous avez déployés:

    kubectl get pods -n onlineboutique
    

    Résultat attendu :

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    La valeur 2/2 dans la colonne READY indique qu'un pod est opérationnel et qu'un proxy Envoy a bien été injecté.

  6. Déployez VirtualService et DestinationRule pour v1 de productcatalog:

     kubectl apply -f destination-vs-v1.yaml -n onlineboutique
    
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productcatalogservice
    spec:
      host: productcatalogservice
      subsets:
      - labels:
          version: v1
        name: v1
    ---
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productcatalogservice
    spec:
      hosts:
      - productcatalogservice
      http:
      - route:
        - destination:
            host: productcatalogservice
            subset: v1

    Notez que seul v1 est présent dans les ressources.

  7. Accédez à l'application dans votre navigateur à l'aide de l'adresse IP externe de votre passerelle d'entrée:

    kubectl get services -n GATEWAY_NAMESPACE
    

La section suivante présente l'interface utilisateur de Cloud Service Mesh et montre comment afficher vos métriques.

Afficher vos services dans la console Google Cloud

  1. Dans la console Google Cloud, accédez à la page Services Google Kubernetes Engine (GKE) Enterprise Edition.

    Accéder aux services de l'édition Enterprise de Google Kubernetes Engine (GKE)

  2. Par défaut, vos services s'affichent dans la vue Liste.

    La présentation du tableau vous permet d'observer tous vos services, ainsi que les métriques importantes en un coup d'œil.

  3. En haut à droite, cliquez sur Topologie. Ici, vous pouvez afficher vos services et leurs interactions les uns avec les autres.

    Vous pouvez développer la section Services et afficher les requêtes par seconde pour chacun de vos services en pointant dessus avec votre curseur.

  4. Revenez à la vue Tableau.

  5. Dans le tableau des services, sélectionnez productcatalogservice. Vous accédez alors à une vue d'ensemble de votre service.

  6. Sur le côté gauche de l'écran, cliquez sur Trafic.

  7. Assurez-vous que 100% du trafic entrant vers productcatalogservice est dirigé vers le service de charge de travail.

La section suivante explique comment créer une version 2 du service productcatalog.

Déployer la version 2 d'un service

  1. Pour ce tutoriel, productcatalogservice-v2 introduit une latence de trois secondes dans les requêtes avec le champ EXTRA_LATENCY. Cela simule une régression dans la nouvelle version du service.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productcatalogservice-v2
    spec:
      selector:
        matchLabels:
          app: productcatalogservice
      template:
        metadata:
          labels:
            app: productcatalogservice
            version: v2
        spec:
          containers:
          - env:
            - name: PORT
              value: '3550'
            - name: EXTRA_LATENCY
              value: 3s
            name: server
            image: gcr.io/google-samples/microservices-demo/productcatalogservice:v0.3.6
            livenessProbe:
              exec:
                command: ["/bin/grpc_health_probe", "-addr=:3550"]
            ports:
            - containerPort: 3550
            readinessProbe:
              exec:
                command: ["/bin/grpc_health_probe", "-addr=:3550"]
            resources:
              limits:
                cpu: 200m
                memory: 128Mi
              requests:
                cpu: 100m
                memory: 64Mi
          terminationGracePeriodSeconds: 5

    Appliquez cette ressource à l'espace de noms onlineboutique.

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. Vérifiez les pods de votre application.

    kubectl get pods -n onlineboutique
    

    Résultat attendu :

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-8wqfd                  2/2     Running   0          25h
    cartservice-c77f6b866-7jwcr                 2/2     Running   0          25h
    checkoutservice-654c47f4b6-n8c6x            2/2     Running   0          25h
    currencyservice-59bc889674-l5xw2            2/2     Running   0          25h
    emailservice-5b9fff7cb8-jjr89               2/2     Running   0          25h
    frontend-77b88cc7cb-bwtk4                   2/2     Running   0          25h
    loadgenerator-6958f5bc8b-lqmnw              2/2     Running   0          25h
    paymentservice-68dd9755bb-dckrj             2/2     Running   0          25h
    productcatalogservice-84f95c95ff-ddhjv      2/2     Running   0          25h
    productcatalogservice-v2-6df4cf5475-9lwjb   2/2     Running   0          8s
    recommendationservice-64dc9dfbc8-7s7cx      2/2     Running   0          25h
    redis-cart-5b569cd47-vw7lw                  2/2     Running   0          25h
    shippingservice-5488d5b6cb-dj5gd            2/2     Running   0          25h
    

    Notez que deux productcatalogservices sont désormais répertoriés.

  3. Utilisez DestinationRule pour spécifier les sous-ensembles d'un service. Dans ce scénario, il existe un sous-ensemble pour la version 1, puis un sous-ensemble distinct pour la version 2 de productcatalogservice.

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productcatalogservice
    spec:
      host: productcatalogservice
      subsets:
      - labels:
          version: v1
        name: v1
      - labels:
          version: v2
        name: v2

    Notez le champ labels. Les versions de productcatalogservice sont distinctives une fois que le trafic est acheminé par VirtualService.

    Appliquez la fonctionDestinationRule :

    kubectl apply -f destination-v1-v2.yaml -n onlineboutique
    

Répartir le trafic entre v1 et v2

  1. Utilisez VirtualService pour définir un petit pourcentage du trafic à diriger vers la version 2 de productcatalogservice.

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productcatalogservice
    spec:
      hosts:
      - productcatalogservice
      http:
      - route:
        - destination:
            host: productcatalogservice
            subset: v1
          weight: 75
        - destination:
            host: productcatalogservice
            subset: v2
          weight: 25

    Le champ de sous-ensemble indique la version, et le champ de pondération indique la répartition en pourcentage du trafic. 75% du trafic est acheminé vers la version 1 du catalogue de produits, et 25% vers la version 2.

    Appliquez la fonctionVirtualService :

    kubectl apply -f vs-split-traffic.yaml -n onlineboutique
    

Si vous accédez à la EXTERNAL_IP de l'entrée du cluster, vous remarquerez que l'interface est périodiquement plus lente à charger.

Dans la section suivante, vous allez découvrir la répartition du trafic dans la console Google Cloud.

Observer la répartition du trafic dans la console Google Cloud

  1. Revenez à la console Google Cloud et accédez à la page "Services GKE Enterprise". Accéder aux services GKE Enterprise

  2. En haut à droite, cliquez sur Topologie.

    Développez la charge de travail productcatalogservice, et notez les déploiements productcatalogservice et productcatalogservice-v2.

  3. Revenez à la vue Tableau.

  4. Cliquez sur productcatalogservice dans le tableau des services.

  5. Revenez à Trafic dans la barre de navigation de gauche.

  6. Notez que le trafic entrant est réparti entre v1 et v2 selon le pourcentage spécifié dans le fichier VirtualService et qu'il existe deux charges de travail du service productcatalog.

    Requêtes, Taux d'erreur et Métriques de latence s'affichent sur le côté droit de la page. Avec Cloud Service Mesh, ces métriques sont décrites pour chaque service pour vous fournir des métriques d'observabilité.

Effectuer un déploiement ou un rollback vers une version

Après avoir observé les métriques lors d'un déploiement Canary, vous pouvez terminer le déploiement de la nouvelle version du service ou effectuer un rollback vers la version d'origine du service en exploitant la ressource VirtualService.

Déploiement

Une fois que vous êtes satisfait du comportement d'un service de la version 2, vous pouvez augmenter progressivement le pourcentage de trafic dirigé vers ce service. À terme, en supprimant la répartition du trafic de cette ressource, le trafic peut être entièrement dirigé vers le nouveau service de la ressource VirtualService que vous avez créée ci-dessus.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productcatalogservice
spec:
  hosts:
  - productcatalogservice
  http:
  - route:
    - destination:
        host: productcatalogservice
        subset: v2

Pour diriger l'ensemble du trafic vers la version 2 de productcatalogservice, procédez comme suit:

kubectl apply -f vs-v2.yaml -n onlineboutique

Rollback

Si vous devez effectuer un rollback vers le service v1, appliquez la destination-vs-v1.yaml précédemment utilisée. Cela dirige uniquement le trafic vers la version 1 de productcatalogservice.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productcatalogservice
spec:
  hosts:
  - productcatalogservice
  http:
  - route:
    - destination:
        host: productcatalogservice
        subset: v1

Pour diriger tout le trafic vers la version v1 de productcatalogservice, procédez comme suit:

kubectl apply -f vs-v1.yaml -n onlineboutique

Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.

Pour éviter que les ressources utilisées lors de ce tutoriel continuent d'être facturées sur votre compte Google Cloud, supprimez le projet ou les ressources individuelles.

Supprimer le projet

Dans Cloud Shell, supprimez le projet :

gcloud projects delete PROJECT_ID

Supprimer les ressources

Si vous souhaitez éviter des frais supplémentaires, supprimez le cluster :

gcloud container clusters delete  CLUSTER_NAME  \
  --project=PROJECT_ID \
  --zone=CLUSTER_LOCATION 

Si vous avez enregistré votre cluster avec un parc à l'aide de gcloud container fleet memberships (plutôt que --enable-fleet ou --fleet-project lors de la création du cluster), supprimez l'appartenance obsolète:

gcloud container fleet memberships delete  MEMBERSHIP  \
  --project=PROJECT_ID

Si vous souhaitez conserver la configuration de votre cluster pour Cloud Service Mesh, mais que vous souhaitez supprimer l'exemple Online Boutique:

  1. Supprimez les espaces de noms de l'application :

    kubectl delete -f namespace onlineboutique
    

    Résultat attendu :

    namespace "onlineboutique" deleted
    
  2. Supprimez les entrées de service :

    kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/istio-manifests/frontend.yaml -n onlineboutique
    kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/istio-manifests/frontend-gateway.yaml -n onlineboutique
    

    Résultat attendu :

    serviceentry.networking.istio.io "allow-egress-googleapis" deleted
    serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
    

Étapes suivantes