Esempio di Cloud Service Mesh: deployment canary


In questo tutorial viene illustrato un caso d'uso comune di implementazione di un deployment canary con Cloud Service Mesh.

Che cos'è un deployment canary?

Un deployment canary indirizza una piccola percentuale di traffico a una nuova versione di un microservizio, quindi ti consente di eseguire il deployment graduale nell'intera base utenti, eliminando gradualmente la vecchia versione. In caso di problemi durante la procedura, è possibile ripristinare la versione precedente del traffico. Con Cloud Service Mesh puoi indirizzare il traffico per assicurarti che i nuovi servizi vengano introdotti in modo sicuro.

Costi

In questo documento utilizzi i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi basata sull'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud potrebbero essere idonei per una prova gratuita.

Al termine del tutorial, puoi evitare i costi continui eliminando le risorse che hai creato. Per maggiori informazioni, vedi Pulizia.

Prima di iniziare

Deployment di Boutique online

  1. Imposta il contesto corrente per kubectl sul cluster in cui hai eseguito il deployment di Online Boutique:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Crea lo spazio dei nomi per l'applicazione di esempio e il gateway di ingresso:

    kubectl create namespace onlineboutique
    
  3. Etichetta lo spazio dei nomi onlineboutique per iniettare automaticamente i proxy Envoy. Segui la procedura descritta in Come attivare l'iniezione automatica di sidecar.

  4. Esegui il deployment dell'app di esempio. Per questo tutorial, eseguirai 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 l'etichetta version=v1 al deployment productcatalog eseguendo questo 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
    

    Tutti i pod dell'applicazione devono essere attivi e in esecuzione, con un valore 2/2 nella colonna READY. Ciò indica che nei pod è stato inserito correttamente un proxy sidecar Envoy.

  6. Esegui il deployment di VirtualService e DestinationRule per la versione 1 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 dell'ingress:

    kubectl get services -n GATEWAY_NAMESPACE
    

La prossima sezione farà un tour della UI di Cloud Service Mesh e mostrerà come visualizzare le metriche.

Esegui il deployment e visualizza i tuoi servizi nella console Google Cloud

  1. Nella console Google Cloud, vai alla pagina Servizi GKE Enterprise.

    Vai a GKE Enterprise Services

  2. Per impostazione predefinita, i servizi vengono visualizzati nella visualizzazione Tabella.

    La panoramica della tabella ti consente di osservare tutti i servizi e le metriche importanti a colpo d'occhio.

    tutti i carichi di lavoro dei servizi

  3. In alto a destra, fai clic su Topologia. Qui puoi visualizzare i tuoi servizi e la loro interazione tra loro.

    Puoi espandere i servizi e visualizzare le richieste al secondo per ciascuno dei tuoi servizi passandoci sopra con il cursore.

    topologia dei carichi di lavoro di tutti i servizi

  4. Torna alla visualizzazione tabella.

  5. Nella tabella Servizi, seleziona productcatalogservice. Verrà visualizzata una panoramica del servizio.

  6. Nella parte sinistra dello schermo, fai clic su Traffico.

  7. Assicurati che il 100% del traffico in entrata verso productcatalogservice vada al servizio dei carichi di lavoro.

    Traffico di svc productcatalog

Nella prossima sezione esamineremo la creazione della versione 2 del servizio productcatalog.

Esegui il deployment della versione 2 di un servizio

  1. Per questo tutorial, productcatalogservice-v2 introdurrà una latenza di 3 secondi nelle richieste con il campo EXTRA_LATENCY.

    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 onlineboutiquespazio dei nomi.

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. Controlla i pod delle applicazioni.

    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. DestinationRule consente di specificare i sottoinsiemi di un servizio. In questo scenario, esiste un sottoinsieme per la versione 1 e la versione 2 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 vengono distinte dopo che il traffico è instradato da VirtualService.

    Applica il DestinationRule:

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

Suddividi il traffico tra la versione 1 e la versione 2

  1. Un VirtualService ti consente di introdurre una piccola percentuale del traffico da indirizzare alla versione 2 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 e il campo ponderazione indica la suddivisione percentuale del traffico. Il 75% del traffico va alla versione 1 del catalogo prodotti e il 25% alla versione 2.

    Applica il VirtualService:

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

Se visiti EXTERNAL_IP del traffico in entrata del cluster, noterai che periodicamente il caricamento del frontend è più lento.

Nella sezione successiva, esplorerai la suddivisione del traffico nella console Google Cloud di GKE Enterprise.

Osserva la suddivisione del traffico nella console Google Cloud

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

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

    Espandi il carico di lavoro productcatalogservice. Vedrai productcatalogservice e productcatalogservice-v2 deployment.

    productcatalog svc v1 v2 traffic tpoplogy

  3. Torna alla Visualizzazione tabella. Fai clic su productcatalogservice nella tabella Servizi. Torna a Traffico nella barra di navigazione a sinistra.

  4. Tieni presente che il traffico in entrata viene suddiviso tra v1 e v2 in base alla percentuale specificata nel file VirtualService e che esistono due carichi di lavoro del servizio productcatalog.

    Sul lato destro dello schermo vedrai le metriche Richieste, Percentuale di errori e Latenza. Con Cloud Service Mesh, ogni servizio avrà queste metriche delineate per fornirti l'osservabilità.

    catalogo prodotti svc v1 v2 traffico

Implementazione o rollback a una versione

Dopo aver osservato le metriche durante un deployment canary, puoi eseguire l'implementazione nel nuovo servizio o eseguire il rollback al servizio precedente utilizzando la risorsa VirtualService.

Implementazione

Quando il comportamento di un servizio v2 ti soddisfa, aumenta in modo incrementale il comportamento del traffico verso il servizio v2. Alla fine, il traffico può essere indirizzato al 100% al nuovo servizio.

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 alla versione 2 di productcatalogservice:

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

Esegui il rollback

Se devi eseguire il rollback al servizio v1, applica semplicemente il destination-vs-v1.yaml precedente. In questo modo il traffico verrà indirizzato solo alla versione 1 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 alla versione 1 di productcatalogservice:

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

Esegui la pulizia

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 usate in questo tutorial, puoi eliminare il progetto le singole risorse.

Elimina il progetto

  1. 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 vuoi conservare il cluster e 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