Cloud Service Mesh am Beispiel: Canary-Deployments


In dieser Anleitung wird ein häufiger Anwendungsfall behandelt: das Roll-out eines Canary-Deployment mit Cloud Service Mesh unter Verwendung von Istio APIs durchführen

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 dabei ein Fehler auftritt, auf die frühere Version zurückgewechselt werden kann. 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.

Hinweis

Online Boutique bereitstellen

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

    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. In dieser Anleitung stellen Sie Online-Boutique eine Mikrodienst-Demo-App.

    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 lernen Sie die Cloud Service Mesh-UI kennen und erfahren, wie Sie Messwerte aufrufen.

Dienste in der Google Cloud Console aufrufen

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

    Zu den Google Kubernetes Engine (GKE) Enterprise Edition-Diensten

  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.

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

  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 ein in der neuen Version des Dienstes.

    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. Mit VirtualService können Sie einen kleinen Prozentsatz des Traffics definieren, der an v2 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 „GKE Enterprise-Dienste“ auf. Zu GKE Enterprise-Diensten

  2. Klicken Sie oben rechts 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 Dienstleistungstabelle auf productcatalogservice.

  5. Kehren Sie links in der Navigationsleiste zu Verkehr 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.

    Rechts auf der Seite werden Anfragen, Fehlerrate und Latenzmesswerte angezeigt. Bei Cloud Service Mesh werden diese Messwerte für jeden Dienst beschrieben, um Ihnen Beobachtbarkeitsmesswerte bereitzustellen.

Roll-out oder Rollback auf eine Version durchführen

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

Roll-out durchführen

Wenn Sie mit dem Verhalten eines v2-Dienstes zufrieden sind, können Sie den Prozentsatz des Traffics, der an den v2-Dienst weitergeleitet wird, schrittweise erhöhen. Schließlich kann der Traffic zu 100 % an den neuen Dienst in der VirtualService-Ressource weitergeleitet werden, die Sie oben erstellt haben, indem Sie die Trafficaufteilung aus dieser Ressource entfernen.

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 ein Rollback auf den Dienst v1 erforderlich ist, wenden Sie die 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

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 (und nicht --enable-fleet oder --fleet-project bei der Clustererstellung), entfernen Sie die veraltete Mitgliedschaft:

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

Wenn Sie Ihren Cluster für Cloud Service Mesh konfiguriert lassen, aber 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