Beispiel eines Cloud Service Mesh: Canary-Deployments


In dieser Anleitung wird ein häufiger Anwendungsfall behandelt: das Bereitstellen einer Canary-Bereitstellung mit Cloud Service Mesh mithilfe von Istio-APIs.

Was ist ein Canary-Deployment?

Ein Canary-Deployment leitet einen kleinen Prozentsatz des Traffics an eine neue Version eines Mikrodiensts weiter und erhöht diesen Prozentsatz dann allmählich, während die alte Version auslaufen und eingestellt wird. Wenn bei diesem Vorgang ein Fehler auftritt, kann der Traffic wieder auf die frühere Version umgestellt werden. Mit Cloud Service Mesh können Sie Traffic weiterleiten und so dafür sorgen, dass neue Dienste sicher eingeführt werden.

Weitere Informationen zu Canary-Tests finden Sie unter Strategien für das Deployment und das Testen von Anwendungen.

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 Online Boutique bereitstellen möchten. Der Befehl hängt davon ab, ob Sie Cloud Service Mesh in einem GKE-Cluster oder 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. Für diese Anleitung stellen Sie Online Boutique bereit, eine Mikrodienst-Demoanwendung.

    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 productcatalog-Deployment das Label version=v1 hinzu. Führen Sie dazu den folgenden Befehl aus:

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

    Sehen Sie sich die von Ihnen bereitgestellten Dienste an:

    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-Proxy ausgeführt wird, der erfolgreich injiziert wurde.

  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 mit der externen IP-Adresse Ihres Ingress-Gateways auf:

    kubectl get services -n GATEWAY_NAMESPACE
    

Im nächsten Abschnitt wird die Cloud Service Mesh-UI vorgestellt und es wird gezeigt, wie Sie Ihre Messwerte aufrufen können.

Dienste in der Google Cloud Console ansehen

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

    Zu den GKE Enterprise-Diensten (Google Kubernetes Engine)

  2. Standardmäßig werden Ihre 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.

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

  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 Ihren 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.

Im nächsten Abschnitt wird beschrieben, wie Sie Version 2 des Dienstes productcatalog erstellen.

v2 eines Dienstes bereitstellen

  1. In dieser Anleitung sorgt productcatalogservice-v2 für eine Latenz von 3 Sekunden bei Anfragen mit dem Feld EXTRA_LATENCY. 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. Verwenden Sie DestinationRule, um die Teilmengen eines Dienstes anzugeben. 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 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 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 Bereitstellungen 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 zur Verfügung zu stellen.

Roll-out oder Rollback auf eine Version durchführen

Nachdem Sie die Messwerte während einer Canary-Bereitstellung beobachtet haben, können Sie das Roll-out der neuen Dienstversion abschließen oder ein Rollback auf die ursprüngliche Dienstversion durchführen, indem Sie die Ressource VirtualService nutzen.

Roll-out durchführen

Wenn Sie mit dem Verhalten eines V2-Dienstes zufrieden sind, können Sie den Prozentsatz des an den V2-Dienst weitergeleiteten Traffics schrittweise erhöhen. Schließlich kann der Traffic zu 100% an den neuen Dienst in der zuvor erstellten VirtualService-Ressource geleitet werden. Dazu wird die Trafficaufteilung von dieser Ressource entfernt.

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 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 bei der Flotte mit gcloud container fleet memberships (anstatt mit --enable-fleet oder --fleet-project beim Erstellen des Clusters) registriert haben, entfernen Sie die veraltete Mitgliedschaft:

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

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

  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