Cloud Service Mesh par l'exemple: déploiements Canary


Dans ce tutoriel, vous allez découvrir un cas d'utilisation courant: le déploiement d'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 faible pourcentage du trafic vers une nouvelle version d'un microservice, puis augmente progressivement ce pourcentage tout en supprimant et supprimant l'ancienne version. Si un problème survient pendant le processus, le trafic peut revenir à la version précédente. Avec Cloud Service Mesh, vous pouvez acheminer le trafic pour vous assurer que les nouveaux services sont introduits en toute sécurité.

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 sur lequel vous prévoyez de déployer Online Boutique. La commande dépend de la configuration de Cloud Service Mesh sur un cluster GKE ou 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. Dans 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 un libellé 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
    

    Un 2/2 dans la colonne READY indique qu'un pod est opérationnel avec un proxy Envoy injecté avec succès.

  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
    

Cette section présente l'interface utilisateur de Cloud Service Mesh et explique comment afficher vos métriques.

Afficher vos services dans la console Google Cloud

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

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

  2. Par défaut, vous affichez vos services 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 Services et afficher le nombre de 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 serez alors redirigé vers un aperçu 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 3 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 les versions v1 et v2

  1. Utilisez VirtualService pour définir un faible 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 dirigé vers la version 1 de productcatalog, 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, explorez 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, puis 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.

    Sur la droite de la page, vous trouverez les sections Requêtes, Taux d'erreur et Métriques de latence. Avec Cloud Service Mesh, ces métriques sont décrites pour chaque service afin de vous fournir des métriques d'observabilité.

Déployer ou restaurer une version

Après avoir observé les métriques lors d'un déploiement Canary, vous pouvez déployer la nouvelle version du service ou revenir à la version d'origine en utilisant la ressource VirtualService.

Déploiement

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

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 revenir au service v1, appliquez simplement le destination-vs-v1.yaml précédent. Le trafic sera dirigé uniquement vers la version v1 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 dans le parc à l'aide de gcloud container fleet memberships (plutôt que de --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 votre cluster configuré pour Cloud Service Mesh, mais supprimer l'exemple de boutique en ligne:

  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
    

Étape suivante