Cloud Service Mesh por exemplo: implementações canárias

Neste tutorial, vai percorrer um exemplo de utilização comum da implementação canary com a Cloud Service Mesh.

O que é uma implementação de teste?

Uma implementação canária encaminha uma pequena percentagem do tráfego para uma nova versão de um microsserviço e, em seguida, permite-lhe implementá-la gradualmente para toda a base de utilizadores, ao mesmo tempo que descontinua a versão antiga. Se algo correr mal durante este processo, o tráfego pode ser revertido para a versão antiga. Com a Cloud Service Mesh, pode encaminhar o tráfego para garantir que os novos serviços são introduzidos em segurança.

Custos

Neste documento, usa os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custos com base na sua utilização projetada, use a calculadora de preços.

Os novos Google Cloud utilizadores podem ser elegíveis para uma avaliação gratuita.

Quando terminar este tutorial, pode evitar custos contínuos eliminando os recursos que criou. Para mais informações, consulte o artigo Limpe.

Antes de começar

Implemente a loja online

  1. Defina o contexto atual de kubectl para o cluster onde implementou a Online Boutique:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Crie o espaço de nomes para a aplicação de exemplo e a gateway de entrada:

    kubectl create namespace onlineboutique
    
  3. Etiquete o espaço de nomes onlineboutique para injetar automaticamente proxies do Envoy. Siga os passos sobre como ativar a injeção automática de sidecar.

  4. Implemente a app de exemplo. Para este tutorial, vai implementar a Online Boutique, uma app de demonstração de microsserviços.

    kubectl apply \
    -n onlineboutique \
    -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/shared/online-boutique/kubernetes-manifests.yaml
    
  5. Adicione uma etiqueta version=v1 à implementação productcatalog executando o seguinte comando:

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

    Veja os serviços que implementou:

    kubectl get pods -n onlineboutique
    

    Resultado esperado:

    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
    

    Todos os pods da sua aplicação devem estar em funcionamento, com um 2/2 na coluna READY. Isto indica que os pods têm um proxy sidecar do Envoy injetado com êxito.

  6. Implemente VirtualService e DestinationRule para a versão v1 de 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

    Tenha em atenção que apenas v1 está presente nos recursos.

  7. Visite a aplicação no seu navegador através do endereço IP externo da entrada:

    kubectl get services -n GATEWAY_NAMESPACE
    

A secção seguinte vai apresentar a IU do Cloud Service Mesh e mostrar como pode ver as suas métricas.

Implemente e veja os seus serviços na Google Cloud consola

  1. Na Google Cloud consola, aceda à página GKE Enterprise Services.

    Aceda aos serviços do GKE Enterprise

  2. Por predefinição, vê os seus serviços na vista de tabela.

    A vista geral da tabela permite-lhe observar todos os seus serviços, bem como métricas importantes rapidamente.

    todas as cargas de trabalho dos serviços

  3. Na parte superior direita, clique em Topologia. Aqui, pode ver os seus serviços e a respetiva interação entre si.

    Pode expandir os serviços e ver os pedidos por segundo de cada um deles passando o cursor do rato sobre os mesmos.

    topologia de cargas de trabalho de todos os serviços

  4. Navegue de volta para a vista de tabela.

  5. Na Tabela de serviços, selecione productcatalogservice. Esta ação permite aceder a uma vista geral do seu serviço.

  6. No lado esquerdo do ecrã, clique em Tráfego.

  7. Certifique-se de que 100% do tráfego de entrada para productcatalogservice é direcionado para o serviço de carga de trabalho.

    productcatalog svc traffic

A secção seguinte explica como criar uma v2 do serviço productcatalog.

Implemente a v2 de um serviço

  1. Para este tutorial, o productcatalogservice-v2 vai introduzir uma latência de 3 segundos nos pedidos com o 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

    Aplique este recurso ao espaço de nomes onlineboutique.

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. Verifique os pods da aplicação.

    kubectl get pods -n onlineboutique
    

    Resultado esperado:

    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
    

    Repare que existem agora 2 productcatalogservices listados.

  3. O DestinationRule é a forma de especificar os subconjuntos de um serviço. Neste cenário, existe um subconjunto para a v1 e para a v2 de 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

    Repare no campo labels. As versões do productcatalogservice são distinguidas depois de o tráfego ser encaminhado pelo VirtualService.

    Aplique o DestinationRule:

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

Divida o tráfego entre a v1 e a v2

  1. Um VirtualService é a forma de introduzir uma pequena percentagem do tráfego a direcionar para a v2 do 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

    O campo subset indica a versão e o campo weight indica a divisão percentual do tráfego. 75% do tráfego vai para a v1 de productcatalog e 25% vai para a v2.

    Aplique o VirtualService:

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

Se visitar o EXTERNAL_IP do acesso do cluster, deve reparar que, periodicamente, o carregamento do frontend é mais lento.

Na secção seguinte, vai explorar a divisão do tráfego na consola do GKE Enterprise Google Cloud .

Observe a divisão de tráfego na Google Cloud consola

  1. Regresse à Google Cloud consola e aceda à página Serviços GKE Enterprise Aceda aos serviços GKE Enterprise

  2. Na parte superior direita, clique em Topologia.

    Expanda a carga de trabalho productcatalogservice. Vai ver implementações productcatalogservice e productcatalogservice-v2.

    productcatalog svc v1 v2 traffic tpoplogy

  3. Regresse à vista de tabela. Clique em productcatalogservice na tabela de serviços. Regresse a Tráfego na barra de navegação do lado esquerdo.

  4. Tenha em atenção que o tráfego recebido é dividido entre a v1 e a v2 pela percentagem especificada no ficheiro VirtualService e que existem 2 cargas de trabalho do serviço productcatalog.

    No lado direito do ecrã, são apresentadas as métricas de pedidos, taxa de erro e latência. Com a Cloud Service Mesh, cada serviço tem estas métricas descritas para lhe oferecer a observabilidade.

    productcatalog svc v1 v2 traffic

Implemente ou reverta para uma versão

Depois de observar as métricas durante uma implementação canary, pode implementar o novo serviço ou reverter para o serviço antigo através do recurso VirtualService.

Implementação

Quando estiver satisfeito com o comportamento de um serviço v2, aumente gradualmente o comportamento do tráfego para o serviço v2. Eventualmente, o tráfego pode ser direcionado 100% para o novo serviço.

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

Para direcionar todo o tráfego para a v2 de productcatalogservice:

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

Reversão

Se precisar de reverter para o serviço v1, basta aplicar o destination-vs-v1.yaml anterior. Esta ação direciona o tráfego apenas para a v1 do productcatalogservice.

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

Para direcionar todo o tráfego para a v1 de productcatalogservice:

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

Limpar

Para evitar incorrer em custos na sua conta do Google Cloud pelos recursos usados neste tutorial, elimine o projeto que contém os recursos ou mantenha o projeto e elimine os recursos individuais.

Para evitar incorrer em encargos contínuos na sua Google Cloud conta pelos recursos usados neste tutorial, pode eliminar o projeto ou eliminar os recursos individuais.

Elimine o projeto

  1. No Cloud Shell, elimine o projeto:

    gcloud projects delete PROJECT_ID
    

Elimine os recursos

  • Se quiser evitar cobranças adicionais, elimine o cluster:

    gcloud container clusters delete  CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  • Se quiser manter o cluster e remover o exemplo da loja online:

    1. Elimine os espaços de nomes da aplicação:

      kubectl delete -f namespace onlineboutique
      

      Resultado esperado:

      namespace "onlineboutique" deleted
      
    2. Elimine as entradas de serviço:

      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
      

      Resultado esperado:

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

O que se segue?