Cloud Service Mesh por exemplo: implementações de teste

Neste tutorial, vai percorrer um exemplo de utilização comum: implementar uma implementação canary com a malha de serviços na nuvem através das APIs Istio.

O que é uma implementação de teste?

Uma implementação canary encaminha uma pequena percentagem de tráfego para uma nova versão de um microsserviço e, em seguida, aumenta gradualmente essa percentagem enquanto descontinua a versão antiga. Se algo correr mal durante este processo, o tráfego pode ser novamente direcionado para a versão anterior. 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 planeia implementar a Online Boutique. O comando depende de ter aprovisionado o Cloud Service Mesh num cluster do GKE ou num 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 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, implementa 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
    

    Um 2/2 na coluna READY indica que um pod está em funcionamento com um proxy 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 do seu gateway de entrada:

    kubectl get services -n GATEWAY_NAMESPACE
    

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

Veja os seus serviços na Google Cloud consola

  1. Na Google Cloud consola, aceda à página Serviços da edição Google Kubernetes Engine (GKE) Enterprise.

    Aceda aos serviços da edição Enterprise do Google Kubernetes Engine (GKE)

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

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

  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 dos seus serviços passando o cursor sobre eles.

  4. Navegue de volta para a vista de tabela.

  5. Na Tabela de serviços, selecione productcatalogservice. Isto 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.

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 introduz uma latência de 3 segundos em pedidos com o campo EXTRA_LATENCY. Isto 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 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. Use DestinationRule para especificar os subconjuntos de um serviço. Neste cenário, existe um subconjunto para a v1 e, em seguida, um subconjunto separado 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. Use VirtualService para definir 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 acede à v1 de productcatalog e 25% acede à 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, explore a divisão do tráfego na Google Cloud consola.

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

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

  2. Na parte superior direita, clique em Topologia.

    Expanda a carga de trabalho productcatalogservice e tome nota das implementações productcatalogservice e productcatalogservice-v2.

  3. Regresse à vista de tabela.

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

  5. Regresse a Tráfego na barra de navegação do lado esquerdo.

  6. 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 da página, são apresentados os Pedidos, a Taxa de erros e as Métricas de latência. Com a Cloud Service Mesh, cada serviço tem estas métricas descritas para lhe fornecer métricas de observabilidade.

Implemente ou reverta para uma versão

Depois de observar as métricas durante uma implementação canary, pode concluir a implementação da nova versão do serviço ou reverter para a versão original do serviço através do recurso VirtualService.

Implementação

Depois de ficar satisfeito com o comportamento de um serviço v2, pode aumentar gradualmente a percentagem de tráfego direcionado para o serviço v2. Eventualmente, pode direcionar 100% do tráfego para o novo serviço no recurso VirtualService que criou 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 precisar de reverter para o serviço v1, aplique o destination-vs-v1.yaml de anteriormente. Isto 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 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

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 registou o cluster na frota através de gcloud container fleet memberships (em vez de --enable-fleet ou --fleet-project durante a criação do cluster), remova a associação desatualizada:

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

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

  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?