Cloud Service Mesh am Beispiel: Canary-Deployments


In dieser Anleitung wird ein häufiger Anwendungsfall für das Roll-out eines Canary-Deployments mit Cloud Service Mesh erläutert.

Was ist ein Canary-Deployment?

Bei einem Canary-Deployment wird ein kleiner Prozentsatz des Traffics an eine neue Version eines Mikrodienstes weitergeleitet. So können Sie das Deployment nach und nach für die gesamte Nutzerbasis einführen, während die alte Version eingestellt und ausgemustert wird. Wenn während dieses Vorgangs ein Fehler auftritt, kann der Traffic wieder auf die alte Version umgestellt werden. Mit Cloud Service Mesh können Sie Traffic steuern, um Dienste sicher einzuführen.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss dieser Anleitung können Sie weitere Kosten durch Löschen von erstellten Ressourcen vermeiden. Weitere Informationen finden Sie unter Bereinigen.

Hinweis

Online Boutique bereitstellen

  1. Legen Sie den aktuellen Kontext für kubectl auf dem Cluster fest, in dem Sie Online Boutique bereitgestellt haben:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Erstellen Sie den Namespace für die Beispielanwendung und das Ingress-Gateway:

    kubectl create namespace onlineboutique
    
  3. Fügen Sie dem Namespace onlineboutique ein Label hinzu, um Envoy-Proxys automatisch einzufügen. Folgen Sie den Schritten zum Aktivieren der automatischen Sidecar-Einfügung.

  4. Stellen Sie die Beispielanwendung bereit. Im Rahmen dieser Anleitung stellen Sie die Mikrodienst-Demo-Anwendung "Online Boutique" bereit.

    kubectl apply \
    -n onlineboutique \
    -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/shared/online-boutique/kubernetes-manifests.yaml
    
  5. Fügen Sie dem Deployment productcatalog das Label version=v1 hinzu. Dazu führen Sie diesen Befehl aus:

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

    Rufen Sie die von Ihnen bereitgestellten Dienste auf:

    kubectl get pods -n onlineboutique
    

    Erwartete Ausgabe:

    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
    

    Alle Pods für Ihre Anwendung sollten mit dem Wert 2/2 in der Spalte READY ausgeführt werden. Dieser Wert weist darauf hin, dass die Pods einen Envoy-Sidecar-Proxy erfolgreich eingefügt haben.

  6. Stellen Sie VirtualService und DestinationRule für v1 von productcatalog bereit:

    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

    Beachten Sie, dass in den Ressourcen nur v1 vorhanden ist.

  7. Rufen Sie die Anwendung in Ihrem Browser mithilfe der externen IP-Adresse Ihres Ingress auf:

    kubectl get services -n GATEWAY_NAMESPACE
    

Im nächsten Abschnitt lernen Sie die Cloud Service Mesh-UI kennen und erfahren, wie Sie Messwerte aufrufen.

Dienste in der Google Cloud Console bereitstellen und aufrufen

  1. Rufen Sie in der Google Cloud Console die Seite GKE Enterprise-Dienste auf.

    Zu GKE Enterprise-Diensten

  2. Standardmäßig werden die Dienste in der Ansicht Tabelle angezeigt.

    In der Tabellenübersicht können Sie alle Dienste und wichtigen Messwerte auf einen Blick sehen.

    Arbeitslasten aller Dienste

  3. Klicken Sie oben rechts auf Topologie. Hier können Sie Ihre Dienste und deren Interaktion miteinander ansehen.

    Sie können Dienste erweitern und die Anfragen pro Sekunde für jeden Ihrer Dienste anzeigen, indem Sie den Mauszeige darauf bewegen.

    Topologie der Arbeitslasten aller Dienste

  4. Kehren Sie zur Tabellenansicht zurück.

  5. Wählen Sie in der Tabelle der Dienste die Option productcatalogservice aus. Daraufhin wird eine Übersicht über den Dienst angezeigt.

  6. Klicken Sie auf der linken Seite des Bildschirms auf Traffic.

  7. 100 % des eingehenden Traffics zu productcatalogservice werden an den Arbeitslastdienst weitergeleitet.

    Traffic für Dienst "productcatalog"

Im nächsten Abschnitt wird die Erstellung einer v2 des Dienstes productcatalog beschrieben.

v2 eines Dienstes bereitstellen

  1. In dieser Anleitung führt productcatalogservice-v2 mit dem Feld EXTRA_LATENCY eine Latenz von 3 Sekunden in Anfragen ein.

    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

    Wenden Sie diese Ressource auf den Namespace onlineboutique an.

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. Prüfen Sie die Anwendungs-Pods.

    kubectl get pods -n onlineboutique
    

    Erwartete Ausgabe:

    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
    

    Beachten Sie, dass jetzt zwei productcatalogservices aufgeführt sind.

  3. Mit DestinationRule werden die Teilmengen eines Dienstes angegeben. In diesem Szenario gibt es eine Teilmenge für v1 und v2 von 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

    Beachten Sie das Feld labels. Die Versionen von productcatalogservice werden unterschieden, nachdem der Traffic von VirtualService weitergeleitet wurde.

    Wenden Sie die DestinationRule an:

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

Traffic zwischen v1 und v2 aufteilen

  1. Durch VirtualService wird ein kleiner Prozentsatz des Traffics eingeführt, der an v2 von productcatalogservice weitergeleitet wird.

    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

    Das Feld "Teilmenge" enthält die Version und das Feld "Gewichtung" die prozentuale Aufteilung des Traffics. 75 % des Traffics werden an v1 von productcatalog und 25 % an v2 gesendet.

    Wenden Sie den VirtualService an:

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

Wenn Sie die EXTERNAL_IP des Cluster-Ingress aufrufen, sehen Sie, dass das Frontend periodisch langsamer geladen wird.

Im nächsten Abschnitt erfahren Sie mehr über die Trafficaufteilung in der GKE Enterprise-Google Cloud Console.

Trafficaufteilung in der Google Cloud Console beobachten

  1. Kehren Sie zur Google Cloud Console zurück und rufen Sie die Seite „GKE Enterprise-Dienste“ auf. Zur Seite „GKE Enterprise-Dienste“

  2. Klicken Sie oben rechts auf Topologie.

    Maximieren Sie die Arbeitslast productcatalogservice. Sie sehen die Bereitstellungen productcatalogservice und productcatalogservice-v2.

    Topologie des Traffics zwischen v1 und v2 für Dienst "productcatalog"

  3. Kehren Sie zur Tabellenansicht zurück. Klicken Sie in der Tabelle "Dienste" auf productcatalogservice. Kehren Sie in der linken Navigationsleiste zu Traffic zurück.

  4. Beachten Sie, dass der eingehende Traffic zwischen v1 und v2 anhand des in der Datei VirtualService angegebenen Prozentsatzes aufgeteilt wird und zwei Arbeitslasten des Dienstes "productcatalog" vorhanden sind.

    Auf der rechten Seite des Bildschirms sehen Sie Messwerte für Anfragen, Fehlerrate und Latenz. In Cloud Service Mesh werden diese Messwerte für jeden Dienst dargestellt, um Beobachtbarkeit zu ermöglichen.

    Traffic zwischen v1 und v2 des Dienstes "productcatalog"

Roll-out oder Rollback zu einer Version

Nachdem Sie die Messwerte während eines Canary-Deployments beobachtet haben, können Sie mithilfe der Ressource VirtualService ein Roll-out zum neuen Dienst oder ein Rollback zum alten Dienst ausführen.

Roll-out

Wenn Sie mit dem Verhalten eines v2-Dienstes zufrieden sind, erhöhen Sie schrittweise das Verhalten des Traffics zum v2-Dienst. Schließlich kann der Traffic zu 100 % an den neuen Dienst weitergeleitet werden.

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

So leiten Sie den gesamten Traffic an v2 von productcatalogservice weiter:

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

Rollback

Wenn Sie ein Rollback zum v1-Dienst durchführen müssen, wenden Sie einfach destination-vs-v1.yaml von zuvor an. Dadurch wird der Traffic nur an v1 von productcatalogservice weitergeleitet.

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

So leiten Sie den gesamten Traffic an v1 von productcatalogservice weiter:

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

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, können Sie entweder das Projekt löschen oder die einzelnen Ressourcen entfernen.

Projekt löschen

  1. Löschen Sie das Projekt in Cloud Shell:

    gcloud projects delete PROJECT_ID
    

Ressourcen löschen

  • Wenn Sie zusätzliche Gebühren vermeiden möchten, löschen Sie den Cluster:

    gcloud container clusters delete  CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  • Wenn Sie den Cluster behalten und das Online Boutique-Beispiel entfernen möchten:

    1. Löschen Sie die Anwendungs-Namespaces:

      kubectl delete -f namespace onlineboutique
      

      Erwartete Ausgabe:

      namespace "onlineboutique" deleted
      
    2. Löschen Sie die Diensteinträge:

      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
      

      Erwartete Ausgabe:

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

Nächste Schritte