Beispiel eines Cloud Service Mesh: Canary-Deployments


In dieser Anleitung führen Sie einen häufigen Anwendungsfall durch: das Roll-out eines Canary-Deployments mit Cloud Service Mesh mithilfe von Istio APIs.

Was ist ein Canary-Deployment?

Ein Canary-Deployment leitet einen kleinen Prozentsatz des Traffics an die neue Version einer und erhöht diesen Prozentsatz dann allmählich, während die alte Version ausmustert. 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 weiterleiten, damit neue Dienste sicher eingeführt werden.

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.

Hinweise

Online Boutique bereitstellen

  1. Legen Sie als aktuellen Kontext für kubectl den Cluster fest, in dem Sie ihn ausführen möchten Online Boutique bereitstellen. Der Befehl hängt davon ab, ob Sie Cloud Service Mesh in einem GKE-Cluster oder Kubernetes Cluster außerhalb von GKE:

    GKE in Google Cloud

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

    GKE außerhalb von Google Cloud

    kubectl config use-context CLUSTER_NAME 
    
  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
    

    Ein 2/2 in der Spalte READY gibt an, dass ein Pod mit einem Envoy ausgeführt wird. Proxy erfolgreich eingefügt.

  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 im Browser über die externe IP-Adresse Ihres Ingress-Gateway:

    kubectl get services -n GATEWAY_NAMESPACE
    

Im nächsten Abschnitt wird die Cloud Service Mesh-UI vorgestellt. Sie erfahren, wie Sie Ihre Metriken.

Dienste in der Google Cloud Console ansehen

  1. Rufen Sie in der Google Cloud Console die Seite Dienste der Enterprise-Version der Google Kubernetes Engine (GKE) auf.

    Zu den GKE Enterprise-Diensten (Google Kubernetes Engine)

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

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

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

    Bewegen Sie den Mauszeiger auf Dienste und sehen Sie sich die Anfragen pro Sekunde für jeden Ihrer Dienste an.

  4. Kehren Sie zur Tabellenansicht zurück.

  5. Wählen Sie in der Tabelle der Dienste die Option productcatalogservice aus. So gelangen Sie einen Überblick über Ihren Service.

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

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

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. Dadurch wird eine Regression in der neuen Version des Dienstes simuliert.

    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 dann eine separate Teilmenge für 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 den DestinationRule an:

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

Traffic zwischen v1 und v2 aufteilen

  1. Verwenden Sie VirtualService, um einen kleinen Prozentsatz des Traffics zu definieren, der zu Version 2 von productcatalogservice weitergeleitet werden soll.

    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 gehen an v1 des Produktkatalogs und 25% an v2.

    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.

Sehen Sie sich im nächsten Abschnitt die Trafficaufteilung in der Google Cloud Console an.

Trafficaufteilung in der Google Cloud Console beobachten

  1. Kehren Sie zur Google Cloud Console zurück und rufen Sie die Seite mit den GKE Enterprise-Diensten auf. Zu den GKE Enterprise-Diensten

  2. Klicken Sie rechts oben auf Topologie.

    Maximieren Sie die Arbeitslast productcatalogservice und notieren Sie sich die Deployments productcatalogservice und productcatalogservice-v2.

  3. Kehren Sie zur Tabellenansicht zurück.

  4. Klicken Sie in der Tabelle „Dienste“ auf productcatalogservice.

  5. Kehren Sie in der linken Navigationsleiste zu Traffic zurück.

  6. 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 der Seite sehen Sie die Messwerte Anfragen, Fehlerrate und Latenz. Bei Cloud Service Mesh werden diese Messwerte für jeden Dienst beschrieben, um Ihnen Beobachtbarkeitsmesswerte bereitzustellen.

Versionen einführen oder auf eine Version zurücksetzen

Nachdem Sie die Messwerte während eines Canary-Deployments beobachtet haben, können Sie Roll-out der neuen Dienstversion ausführen oder ein Rollback auf die ursprüngliche Dienstversion durchführen durch Nutzung der VirtualService-Ressource.

Roll-out durchführen

Wenn Sie mit dem Verhalten eines V2-Dienstes zufrieden sind, können Sie schrittweise Erhöhen Sie den Prozentsatz des an den Dienst V2 geleiteten Traffics. Schließlich Traffic kann zu 100% an den neuen Dienst in der VirtualService-Ressource geleitet werden. indem Sie die Traffic-Aufteilung von dieser Ressource entfernt haben.

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 durchführen

Wenn Sie ein Rollback zum v1-Dienst durchführen müssen, wenden Sie einfach destination-vs-v1.yaml von zuvor an. Dadurch wird Traffic nur an Version 1 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

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 Ihren Cluster mit gcloud container fleet memberships bei der Flotte registriert haben (statt --enable-fleet oder --fleet-project bei der Clustererstellung) Entfernen Sie dann die veraltete Mitgliedschaft:

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

Wenn Sie den Cluster für Cloud Service Mesh konfiguriert lassen, aber Folgendes entfernen möchten: Beispiel für Online-Boutique:

  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