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


Dans ce tutoriel, vous allez découvrir un cas d'utilisation courant de déploiement Canary avec Cloud Service Mesh.

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 vous permet de déployer progressivement l'ensemble de la base d'utilisateurs, tout en supprimant et supprimant l'ancienne version. Si un problème survient pendant le processus, le trafic peut revenir à l'ancienne version. 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 avez déployé la boutique en ligne :

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  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 vos 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
    

    Tous les pods de votre application doivent être opérationnels, avec une valeur 2/2 dans la colonne READY. Cela indique que les pods ont un proxy side-car 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 en utilisant l'adresse IP externe de votre entrée :

    kubectl get services -n GATEWAY_NAMESPACE
    

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

Déployer et afficher vos services dans la console Google Cloud

  1. Dans la console Google Cloud, accédez à la page Services GKE Enterprise.

    Accéder aux services GKE Enterprise

  2. Par défaut, vous affichez vos services dans la vue Table.

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

    Toutes les charges de travail de services

  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 des services et afficher les requêtes par seconde pour chacun d'entre eux en passant la souris sur leur nom.

    Topologie de toutes les charges de travail de services

  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.

    Trafic productcatalog svc

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.

    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. DestinationRule permet de spécifier les sous-ensembles d'un service. Dans ce scénario, il existe un sous-ensemble pour la version 1 et 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. Un VirtualService représente la façon dont vous introduisez 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 v2.

    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 de GKE Enterprise.

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. Les déploiements productcatalogservice et productcatalogservice-v2 s'affichent.

    Topologie de trafic productcatalog svc v1 v2

  3. Revenez à la vue Tableau. Cliquez sur productcatalogservice dans le tableau de services. Revenez à la section Trafic dans la barre de navigation de gauche.

  4. 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 l'écran, vous trouverez les requêtes, le taux d'erreur et les métriques de latence. Avec Cloud Service Mesh, ces métriques sont décrites pour chaque service pour vous fournir l'observabilité.

    Trafic productcatalog svc v1 v2

Déployer ou restaurer une version

Après avoir observé les métriques lors d'un déploiement Canary, vous pouvez déployer le nouveau service ou revenir à l'ancien service en utilisant la ressource VirtualService.

Déploiement

Une fois que vous êtes satisfait du comportement d'un service v2, augmentez progressivement le comportement du trafic vers le service v2. À terme, le trafic peut être dirigé 100% vers le nouveau service.

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

  1. 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 souhaitez conserver votre cluster et supprimer l'exemple de boutique en ligne, procédez comme suit :

    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