Cloud Service Mesh tramite esempi: deployment canary

In questo tutorial, analizzerai uno scenario d'uso comune: l'implementazione di un deployment canary con Cloud Service Mesh utilizzando le API Istio.

Che cos'è un deployment canary?

Un deployment canary indirizza una piccola percentuale di traffico a una nuova versione di un microservizio, quindi aumenta gradualmente questa percentuale eliminando e ritirando la vecchia versione. Se qualcosa va storto durante questo processo, il traffico può essere ripristinato alla versione precedente. Con Cloud Service Mesh puoi instradare il traffico per garantire l'introduzione sicura di nuovi servizi.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero essere idonei a usufruire di una prova gratuita.

Al termine di questo tutorial, puoi evitare l'addebito di costi ricorrenti eliminando le risorse create. Per saperne di più, consulta Esegui la pulizia.

Prima di iniziare

Esegui il deployment di Online Boutique

  1. Imposta il contesto corrente per kubectl sul cluster in cui prevedi di eseguire il deployment di Online Boutique. Il comando dipende dal fatto che tu abbia eseguito il provisioning di Cloud Service Mesh su un cluster GKE o su un cluster Kubernetes al di fuori di GKE:

    GKE su Google Cloud

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

    GKE al di fuori di Google Cloud

    kubectl config use-context CLUSTER_NAME 
    
  2. Crea lo spazio dei nomi per l'applicazione di esempio e il gateway in entrata:

    kubectl create namespace onlineboutique
    
  3. Etichetta lo spazio dei nomi onlineboutique per inserire automaticamente i proxy Envoy. Segui i passaggi su come attivare l'inserimento automatico di sidecar.

  4. Esegui il deployment dell'app di esempio. Per questo tutorial, esegui il deployment di Online Boutique, un'app demo di microservizi.

    kubectl apply \
    -n onlineboutique \
    -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/shared/online-boutique/kubernetes-manifests.yaml
    
  5. Aggiungi un'etichetta version=v1 al deployment di productcatalog eseguendo il seguente comando:

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

    Visualizza i servizi di cui hai eseguito il deployment:

    kubectl get pods -n onlineboutique
    

    Output previsto:

    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
    

    Un 2/2 nella colonna READY indica che un pod è attivo e in esecuzione con un proxy Envoy inserito correttamente.

  6. Esegui il deployment di VirtualService e DestinationRule per v1 di 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

    Tieni presente che nelle risorse è presente solo v1.

  7. Visita l'applicazione nel browser utilizzando l'indirizzo IP esterno del tuo gateway in entrata:

    kubectl get services -n GATEWAY_NAMESPACE
    

La sezione successiva illustra l'UI di Cloud Service Mesh e mostra come visualizzare le metriche.

Visualizza i tuoi servizi nella console Google Cloud

  1. Nella console Google Cloud , vai alla pagina Servizi di Google Kubernetes Engine (GKE) Enterprise.

    Vai a Servizi di Google Kubernetes Engine (GKE) Enterprise

  2. Per impostazione predefinita, i servizi vengono mostrati nella visualizzazione Elenco.

    La panoramica della tabella ti consente di osservare tutti i tuoi servizi, insieme a un riepilogo delle metriche importanti.

  3. In alto a destra, fai clic su Topologia. Qui sono visualizzati i tuoi servizi e il modo in cui interagiscono tra loro.

    Puoi espandere i Servizi e visualizzare le Richieste al secondo per ciascun servizio passando il mouse sopra di essi.

  4. Torna alla Visualizzazione tabella.

  5. Nella tabella Servizi, seleziona productcatalogservice. Viene visualizzata una panoramica del tuo servizio.

  6. Sul lato sinistro dello schermo, fai clic su Traffico.

  7. Assicurati che il 100% del traffico in entrata a productcatalogservice venga indirizzato al servizio del workload.

La sezione successiva descrive la creazione di una v2 del servizio productcatalog.

Esegui il deployment della v2 di un servizio

  1. Per questo tutorial, productcatalogservice-v2 introduce una latenza di 3 secondi nelle richieste con il campo EXTRA_LATENCY. In questo modo viene simulata una regressione nella nuova versione del servizio.

    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

    Applica questa risorsa allo spazio dei nomi onlineboutique.

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. Controlla i pod dell'applicazione.

    kubectl get pods -n onlineboutique
    

    Output previsto:

    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
    

    Tieni presente che ora sono elencati due productcatalogservices.

  3. Utilizza DestinationRule per specificare i sottoinsiemi di un servizio. In questo scenario, è presente un sottoinsieme per v1 e poi un sottoinsieme separato per v2 di 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

    Prendi nota del campo labels. Le versioni di productcatalogservice si distinguono dopo che il traffico viene indirizzato da VirtualService.

    Applica DestinationRule:

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

Suddividi il traffico tra v1 e v2

  1. Utilizza VirtualService per definire una piccola percentuale del traffico da indirizzare a v2 di 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

    Il campo Sottoinsieme indica la versione, mentre il campo Ponderazione indica la percentuale di suddivisione del traffico. Il 75% del traffico va a v1 di productcatalog e il 25% a v2.

    Applica VirtualService:

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

Se visiti l'EXTERNAL_IP dell'ingresso del cluster, noterai che periodicamente il caricamento del frontend è più lento.

Nella sezione successiva, esaminerai la suddivisione del traffico nella console Google Cloud .

Osserva la suddivisione del traffico nella console Google Cloud

  1. Torna alla console Google Cloud e vai alla pagina Servizi GKE Enterprise. Vai a Servizi GKE Enterprise

  2. In alto a destra, fai clic su Topologia.

    Espandi il workload productcatalogservice e prendi nota dei deployment productcatalogservice e productcatalogservice-v2.

  3. Torna alla Visualizzazione tabella.

  4. Fai clic su productcatalogservice nella tabella Servizi.

  5. Torna a Traffico nella barra di navigazione a sinistra.

  6. Tieni presente che il traffico in entrata è suddiviso tra v1 e v2 in base alla percentuale specificata nel file VirtualService e che sono presenti due workload del servizio productcatalog.

    Sul lato destro della pagina, vedrai Richieste, Tasso di errore e Metriche di latenza. Con Cloud Service Mesh, ogni servizio è accompagnato dalla descrizione di queste metriche per fornirti metriche di osservabilità.

Implementa o esegui il rollback a una versione

Dopo aver osservato le metriche durante un deployment canary, puoi completare l'implementazione della nuova versione del servizio o eseguire il rollback alla versione originale del servizio sfruttando la risorsa VirtualService.

Implementazione

Se il comportamento di un servizio v2 ti soddisfa, puoi aumentare gradualmente la percentuale di traffico indirizzato al servizio v2. Alla fine, sarà possibile reindirizzare il 100% del traffico al nuovo servizio nella risorsa VirtualService creata in precedenza rimuovendo la suddivisione del traffico da questa risorsa.

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

Per indirizzare tutto il traffico a v2 di productcatalogservice:

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

Rollback

Se devi eseguire il rollback al servizio v1, applica destination-vs-v1.yaml precedente. In questo modo, il traffico verrà indirizzato solo a v1 di productcatalogservice.

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

Per indirizzare tutto il traffico a v1 di productcatalogservice:

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

Libera spazio

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Per evitare che al tuo account Google Cloud vengano addebitati costi continui per le risorse utilizzate in questo tutorial, puoi eliminare il progetto o le singole risorse.

Elimina il progetto

In Cloud Shell, elimina il progetto:

gcloud projects delete PROJECT_ID

Elimina le risorse

Se vuoi evitare addebiti aggiuntivi, elimina il cluster:

gcloud container clusters delete  CLUSTER_NAME  \
  --project=PROJECT_ID \
  --zone=CLUSTER_LOCATION 

Se hai registrato il cluster nel parco risorse utilizzando gcloud container fleet memberships (anziché --enable-fleet o --fleet-project durante la creazione del cluster), rimuovi l'abbonamento inattivo:

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

Se vuoi mantenere il cluster configurato per Cloud Service Mesh, ma rimuovere l'esempio Online Boutique:

  1. Elimina gli spazi dei nomi dell'applicazione:

    kubectl delete -f namespace onlineboutique
    

    Output previsto:

    namespace "onlineboutique" deleted
    
  2. Elimina le voci di servizio:

    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
    

    Output previsto:

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

Passaggi successivi