Cloud Service Mesh por exemplo: implantações canário

Neste tutorial, você vai conferir um caso de uso comum: a implantação canário com o Cloud Service Mesh usando APIs do Istio.

O que é uma implantação canário?

Uma implantação canário encaminha uma pequena porcentagem do tráfego para uma nova versão de um microsserviço e depois aumenta gradualmente essa porcentagem, eliminando e desativando a versão antiga. Se ocorrer algum erro durante esse processo, será possível retornar o tráfego à versão anterior. Com o Cloud Service Mesh, é possível rotear o tráfego para garantir que novos serviços sejam introduzidos com segurança.

Custos

Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso, use a calculadora de preços.

Novos Google Cloud usuários podem estar qualificados para um teste sem custo financeiro.

Ao concluir este tutorial, exclua os recursos criados para evitar custos contínuos. Para mais informações, consulte Limpeza.

Antes de começar

Implantar Boutique on-line

  1. Defina o contexto atual de kubectl no cluster em que você planeja implantar o Online Boutique. O comando depende se você provisionou o Cloud Service Mesh em um cluster do GKE ou em um cluster do Kubernetes fora do GKE:

    GKE no Google Cloud

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

    GKE fora do Google Cloud

    kubectl config use-context CLUSTER_NAME 
    
  2. Crie o namespace para o aplicativo de amostra e o gateway de entrada:

    kubectl create namespace onlineboutique
    
  3. Rotule o namespace onlineboutique para injetar automaticamente proxies do Envoy. Siga as etapas para ativar a injeção automática de arquivo secundário.

  4. Implante o app de exemplo. Neste tutorial, você vai implantar o Online Boutique, um 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 um rótulo version=v1 à implantação do productcatalog executando o seguinte comando:

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

    Confira os serviços que você implantou:

    kubectl get pods -n onlineboutique
    

    Resposta esperada:

    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
    

    Um 2/2 na coluna READY indica que um pod está em execução com um proxy do Envoy injetado.

  6. Implante VirtualService e DestinationRule para a 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

    Observe que apenas v1 está presente nos recursos.

    Confira a Destination Rule criada.

      kubectl get destinationrules -n onlineboutique
    

    Resposta esperada:

      NAME                    HOST                    AGE
      productcatalogservice   productcatalogservice   2m
    

    Confira o VirtualService criado.

      kubectl get virtualservices -n onlineboutique
    

    Resultado esperado:

      NAME                    GATEWAYS   HOSTS                       AGE
      productcatalogservice              ["productcatalogservice"]   2m
    
  7. Acesse o aplicativo no navegador usando o endereço IP externo do seu gateway de entrada:

    kubectl get services -n GATEWAY_NAMESPACE
    

Na próxima seção, você vai conhecer a interface do Cloud Service Mesh e aprender a visualizar suas métricas.

Conferir seus serviços no Google Cloud console do

  1. No Google Cloud console do, acesse a página Serviços do Google Kubernetes Engine (GKE) Enterprise Edition.

    Acessar os serviços do Google Kubernetes Engine (GKE) Enterprise Edition

  2. Por padrão, os serviços são exibidos na visualização de Lista.

    A Visão geral da tabela permite que você observe todos seus serviços, bem como métricas importantes rapidamente.

  3. No canto superior direito, clique em Topologia. Aqui você pode ver seus serviços e a interação entre eles.

    É possível expandir os Serviços e ver as Solicitações por segundo de cada um deles. Para isso, passe o cursor sobre eles.

  4. Volte para a Visualização em tabela.

  5. Na Tabela de serviços, selecione productcatalogservice. Você vai acessar uma visão geral do serviço.

  6. No lado esquerdo da tela, clique em Tráfego.

  7. Verifique se 100% do tráfego de entrada para productcatalogservice vai para o serviço de carga de trabalho.

A próxima seção explica como criar uma v2 do serviço productcatalog.

Implantar a v2 de um serviço

  1. Para este tutorial, productcatalogservice-v2 introduz uma latência de 3 segundos em solicitações com o campo EXTRA_LATENCY. Isso simula uma regressão na nova versão do serviço.

    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 namespace onlineboutique.

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. Verifique os pods do aplicativo.

    kubectl get pods -n onlineboutique
    

    Resposta esperada:

    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
    

    Observe que agora há dois productcatalogservices listados.

  3. Use DestinationRule para especificar os subconjuntos de um serviço. Neste cenário, há um subconjunto para a v1 e outro 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

    Observe o campo labels. As versões do productcatalogservice são diferenciadas depois que o tráfego é roteado pelo VirtualService.

    Aplique o DestinationRule:

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

Dividir o tráfego entre v1 e v2

  1. Use VirtualService para definir uma pequena porcentagem do tráfego a ser direcionado 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 de subconjunto indica a versão e o campo de peso indica a divisão percentual do tráfego. 75% do tráfego vai para a v1 do catálogo de produtos, e 25% vai para a v2.

    Aplique o VirtualService:

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

Se você acessar o EXTERNAL_IP da entrada do cluster, observe que, periodicamente, o carregamento do front-end está mais lento.

Na próxima seção, você vai conferir a divisão de tráfego no Google Cloud console do.

Observar a divisão de tráfego no Google Cloud console do

  1. Volte ao Google Cloud console do e acesse a página de serviços do GKE Enterprise. Acessar serviços do GKE Enterprise

  2. No canto superior direito, clique em Topologia.

    Expanda a carga de trabalho productcatalogservice e observe as implantações productcatalogservice e productcatalogservice-v2.

  3. Volte para a Visualização em tabela.

  4. Clique em productcatalogservice na tabela de serviços.

  5. Volte para Tráfego na barra de navegação à esquerda.

  6. Observe que o tráfego de entrada é dividido entre v1 e v2 pela porcentagem especificada no arquivo VirtualService, e que há duas cargas de trabalho do serviço productcatalog.

    No lado direito da página, você verá Solicitações, Taxa de erros e Métricas de latência. Com o Cloud Service Mesh, cada serviço tem essas métricas descritas para fornecer métricas de observabilidade.

Lançar ou reverter para uma versão

Depois de observar as métricas durante uma implantação canário, faça o lançamento da nova versão do serviço ou reverter para a versão original do serviço usando o VirtualService recurso.

Lançar

Depois de se familiarizar com o comportamento de um serviço da v2, você pode aumentar gradualmente a porcentagem de tráfego direcionado ao serviço da v2. Em algum momento, o tráfego poderá ser direcionado 100% para o novo serviço no recurso VirtualService criado acima, removendo a divisão de tráfego desse recurso.

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

Reverter

Se você precisar reverter para o serviço v1, aplique o destination-vs-v1.yaml anteriormente. Isso direciona o tráfego apenas para a v1 de 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 cobranças na sua conta do Google Cloud pelos recursos usados neste tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Para evitar cobranças recorrentes na sua Google Cloud conta pelos recursos usados neste tutorial, é possível excluir o projeto ou excluir os recursos individuais.

Excluir o projeto

No Cloud Shell, exclua o projeto:

gcloud projects delete PROJECT_ID

Excluir os recursos

Se quiser evitar cobranças adicionais, exclua o cluster:

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

Se você registrou o cluster na frota usando gcloud container fleet memberships (em vez de --enable-fleet ou --fleet-project durante a criação do cluster), remova a assinatura desatualizada:

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

Se quiser manter o cluster configurado para o Cloud Service Mesh, mas remover o exemplo do Online Boutique:

  1. Exclua os namespaces do aplicativo:

    kubectl delete -f namespace onlineboutique
    

    Saída esperada:

    namespace "onlineboutique" deleted
    
  2. Exclua 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
    

    Resposta esperada:

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

A seguir