Implantar o app ASP.NET Core no Google Kubernetes Engine com o Istio (parte 2)

1. Visão geral

Na primeira parte do laboratório, você criou um aplicativo ASP.NET Core, o conteinerizou e o implantou no Google Kubernetes Engine (GKE), além de configurar o tráfego para ser gerenciado pelo Istio.

Esta segunda parte do laboratório pressupõe que você já tenha o cluster do Kubernetes e o aplicativo do primeiro laboratório em execução. Você vai aprender como o Istio pode ajudar a gerenciar, monitorar e proteger seus serviços com mudanças mínimas no código. Especificamente, você vai conhecer recursos do Istio, como métricas, rastreamento, visualização de serviços, gerenciamento dinâmico de tráfego, injeção de falhas e muito mais.

O que você vai aprender

  • Como consultar métricas com o Prometheus.
  • Como visualizar métricas com o Grafana.
  • Como criar uma nova versão do seu serviço.
  • Como fixar um serviço em uma versão específica.
  • Como dividir o tráfego entre diferentes versões.
  • Como injetar falhas em chamadas de serviço.

O que é necessário

Como você usará este tutorial?

Apenas leitura Leitura e exercícios

Como você classificaria sua experiência com o Google Cloud Platform?

Iniciante Intermediário Proficiente

2. Configuração e requisitos

Configuração de ambiente autoguiada

  1. Faça login no Console do Cloud e crie um novo projeto ou reutilize um existente. Crie uma se você ainda não tiver uma conta do Gmail ou do G Suite.

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID.

  1. Em seguida, será necessário ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.

A execução deste codelab não será muito cara, se for o caso. Siga todas as instruções na seção "Limpeza", que orienta você sobre como encerrar recursos para não incorrer em cobranças além deste tutorial. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

Inicie o Cloud Shell

Embora o Google Cloud possa ser operado remotamente em seu laptop, neste codelab você vai usar o Google Cloud Shell, um ambiente de linha de comando executado no Google Cloud.

Ativar o Cloud Shell

  1. No Console do Cloud, clique em Ativar o Cloud ShelldnDTxS9j60RcXdTjea12HLB9paS9Gzf7PfFLE9RW8g0Qx1bz7nmCzyCu4rjluX3bOEwavOpDwioXEkzOf6xtZp6-ZbJa08jwJqtmeeW8jZ1tYfi2lyXqvW3WFHP0eAxDkQDfpO9Ljw.

yzBQBp2RC1EFvSSLYVkMA2m6LHqGsp22O81rUS5tGb9Y1FqlVhoRj_ka8V_uEjtpcirZRULMy1IjNr848uYvb9mC9RcGGqeayaLcXFfRwUGeXWChZPtWkHzUshTcqx_wJHis0X8viA

Se você nunca tiver iniciado o Cloud Shell, verá uma tela intermediária (abaixo da dobra) com a descrição do que ele é. Se esse for o caso, clique em Continuar e você não o verá novamente. Esta é a aparência dessa tela única:

VgsaqGbKPRiqK24CqAKjSXjepuJT96PmiDqQMcySmWKx8QyW5F3G2D8JH2d08ek-YM77wWKxPvggpOFER8Hbq3aaZipTDU2o0il7A0kS3FXY_NzuujjEqDF1nsbDKkNMThrqcdMGtQ

Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.

7RuYr-LCKzdiE1veTFmL_lYrVxsMZ6-xDoxAnfwPPc5uFA0utmFGejvu81jGmTdbqnqxrytW3KcHT6xrMIRc3bskctnDZC5nJdpqw-LRxu3r35hL4A0BSBTtbtirfh3PKv-eOKt8Rg

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Praticamente todo o seu trabalho neste codelab pode ser feito em um navegador ou no seu Chromebook.

Depois de se conectar ao Cloud Shell, você já estará autenticado e o projeto já estará configurado com seu ID do projeto.

  1. Execute o seguinte comando no Cloud Shell para confirmar que você está autenticado:
gcloud auth list

Resposta ao comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

Resposta ao comando

[core]
project = <PROJECT_ID>

Se o projeto não estiver configurado, configure-o usando este comando:

gcloud config set project <PROJECT_ID>

Resposta ao comando

Updated property [core/project].

3. Testar o aplicativo

Antes de iniciar o laboratório, verifique se o aplicativo ainda está funcionando do laboratório anterior. Para lembrar, veja como encontrar o IP externo e a porta do gateway, que estão listados em EXTERNAL-IP:

kubectl get svc istio-ingressgateway -n istio-system

Para ver o aplicativo, abra o navegador e acesse http://<gatewayurl>:

f579a9baedc108a9.png

Se o aplicativo não aparecer, volte ao laboratório anterior para verificar se você seguiu todas as etapas e se o aplicativo e o Istio estão instalados e funcionando corretamente.

Neste ponto, talvez você esteja se perguntando: "Qual é o benefício do Istio?". Ao permitir que o Istio gerencie o tráfego do seu aplicativo, você recebe recursos como métricas, rastreamento, gerenciamento dinâmico de tráfego, visualização de serviços, injeção de falhas e muito mais sem custos financeiros.

Você vai começar analisando as métricas na próxima etapa.

4. Métricas com o Grafana e o Prometheus

Por padrão, o Istio gera algumas métricas. É possível usar complementos para consultar e visualizar essas métricas padrão.

Prometheus

O Prometheus é uma solução de monitoramento de código aberto. É possível usar o Prometheus para consultar métricas geradas pelo Istio, mas primeiro é necessário instalar o complemento do Prometheus.

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yaml

Verifique se o Prometheus está em execução:

kubectl get svc prometheus -n istio-system

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
prometheus   ClusterIP   10.31.243.62   <none>        9090/TCP   1d

Envie algum tráfego para o aplicativo acessando http://<gatewayurl> algumas vezes ou executando o comando curl.

Configure o encaminhamento de portas para a interface do Prometheus:

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 8080:9090

Agora você pode executar uma consulta clicando no botão "Visualização da Web", no canto superior direito do Cloud Shell, e em Visualizar na porta 8080:

772a5248aa493025.png

A interface do Prometheus vai aparecer em uma nova guia:

272ee63c1fe0be16.png

Para saber mais sobre o Prometheus, consulte Como consultar métricas com o Prometheus.

Grafana

O Grafana é outro complemento para visualizar métricas.

Instale o Grafana. Substitua istio-version pela sua versão atual do Istio,por exemplo, 1.0.3-gke.3:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/grafana.yaml

Verifique se o Grafana está em execução:

kubectl get svc grafana -n istio-system

NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
grafana   ClusterIP   10.31.248.230   <none>        3000/TCP   1d

Envie algum tráfego para o aplicativo acessando http://<gatewayurl> algumas vezes ou executando o comando curl.

Configure o encaminhamento de portas para a interface do Grafana:

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 8080:3000

Para acessar os painéis do Grafana, acesse a Prévia da Web:

806d696d85267a37.png

524cb9f6d66f8655.png

Para saber mais sobre o Grafana, consulte Visualizar métricas com o Grafana.

5. Criar uma nova versão do aplicativo

Em algum momento, o aplicativo implantado na produção exigirá correções de bugs ou recursos adicionais. Vamos ver como é esse processo.

Primeiro, vamos modificar o aplicativo. Abra o editor de código no Cloud Shell.

mxrggIJ2Zz8E47ULCEo4NywjM-EpSkZF5c3TQgfGx4nODwP2obiQXrwQjEEaXuBhJDA2jJ5evR7TuHIy1gsqqDRFm0Wh3xhZUu9tn_xb1ygFlBm1HKJqLdfz_aK7WJS33u2IBDO2oQ

Acesse Index.cshtml em HelloWorldAspNetCore > Views > Home e atualize uma das mensagens do carrossel.

Encontre a seguinte linha:

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core 

E modifique a mensagem para:

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core on Google Cloud

Salve as mudanças e volte para o Cloud Shell. Em HelloWorldAspNetCore,, crie a imagem do Docker:

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 . 

E envie para o Container Registry:

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 

Depois de enviar a imagem do contêiner, você poderá implantar a nova versão na próxima etapa.

6. Criar a nova implantação

Para implantar a nova versão, primeiro crie uma nova implantação para ela no Kubernetes. Adicione o seguinte ao final do arquivo aspnetcore.yaml:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v2
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v2
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

Implante a nova versão no namespace padrão com kubectl:

kubectl apply -f aspnetcore.yaml
service "aspnetcore" unchanged
deployment.extensions "aspnetcore-v1" unchanged
deployment.extensions "aspnetcore-v2" created

Verifique se os pods esperados estão em execução:

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s
aspnetcore-v2-5d765db-l9xmg   2/2       Running   0          1m

Agora, teste o aplicativo novamente. Consulte o IP externo do gateway:

kubectl get svc istio-ingressgateway -n istio-system

Ele está listado em EXTERNAL-IP. Abra um navegador anônimo e acesse http://<replace-with-external-ip>.

Ao atualizar, às vezes, você vai encontrar a mensagem "Saiba como criar apps da Web com o ASP.NET Core":

11d528132dbb6cee.png

Em outros momentos, você vai encontrar a mensagem "Saiba como criar apps da Web com o ASP.NET Core no Google Cloud":

3eb0d5be1b4cb40b.png

Isso ocorre porque as implantações v1 e v2 são expostas por trás do mesmo serviço do Kubernetes (aspnetcore-service), e o VirtualService criado no laboratório anterior (aspnetcore-virtualservice) usa esse serviço como um host.

Na próxima etapa, você vai fixar o serviço na implantação v2 usando uma DestinationRule.

7. Fixar seu serviço na nova versão

Nesta etapa, você fixa seu serviço para usar a implantação v2, o que pode ser feito com uma DestinationRule. Uma DestinationRule configura o conjunto de políticas a serem aplicadas a uma solicitação depois que uma operação de roteamento do VirtualService é realizada.

Uma DestinationRule também define subconjuntos endereçáveis, ou seja, versões nomeadas, do host de destino correspondente. Esses subconjuntos são usados em especificações de rota do VirtualService ao enviar tráfego para versões específicas do serviço.

Crie um novo arquivo com o nome aspnetcore-destinationrule.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: aspnetcore-destinationrule
spec:
  host: aspnetcore-service
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

Em seguida, crie a DestinationRule. Isso cria dois subconjuntos (v1 e v2) que podem ser usados no VirtualService:

kubectl apply -f aspnetcore-destinationrule.yaml
destinationrule.networking.istio.io "aspnetcore-destionationrule" created

Agora, volte ao arquivo aspnetcore-virtualservice.yaml para atualizar o VirtualService e usar o subconjunto v2:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v2

Atualize o VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

Abra o navegador e acesse http://<replace-with-external-ip>. Mesmo depois de várias atualizações, a mensagem "Saiba como criar apps da Web com ASP.NET Core no Google Cloud" vai aparecer:

3eb0d5be1b4cb40b.png

8. Dividir o tráfego entre versões

Às vezes, convém dividir o tráfego entre versões para teste. Por exemplo, é possível enviar 75% do tráfego para a v1 e 25% para a v2 do serviço. Isso é fácil de fazer com o Istio. Crie um arquivo aspnetcore-virtualservice-weights.yaml para se referir aos dois subconjuntos com pesos diferentes:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v1
      weight: 75
    - destination:
        host: aspnetcore-service
        subset: v2
      weight: 25

Atualize o VirtualService:

kubectl apply -f aspnetcore-virtualservice-weights.yaml

Agora, ao atualizar o navegador, você vai ver as versões v1 e v2 veiculadas com uma proporção de aproximadamente 3:1.

Para saber mais, consulte divisão de tráfego no Istio.

9. Injetar falhas

Outra tarefa de desenvolvimento útil para testes é injetar falhas ou atrasos no tráfego e ver como os serviços se comportam em resposta.

Por exemplo, talvez você queira retornar uma resposta de solicitação inválida (HTTP 400) para 50% do tráfego da versão v1. Crie um arquivo aspnetcore-virtualservice-fault-abort.yaml que corresponda ao seguinte:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      abort:
        percentage:
          value: 50
        httpStatus: 400
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

Atualize o VirtualService:

kubectl apply -f aspnetcore-virtualservice-fault-abort.yaml

Agora, ao atualizar o navegador, você vai notar que metade das vezes o serviço v1 retorna um código de resposta HTTP 400.

Ou talvez você queira adicionar um atraso de 5 segundos às solicitações. Crie um arquivo aspnetcore-virtualservice-fault-delay.yaml que corresponda ao seguinte:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      delay:
        fixedDelay: 5s
        percentage:
          value: 100
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

Atualize o VirtualService:

kubectl apply -f aspnetcore-virtualservice-fault-delay.yaml

Agora, ao atualizar o navegador, você vai notar que as solicitações estão atrasadas em 5 segundos.

Para saber mais sobre os recursos do Istio, como tempos limite, novas tentativas, regras condicionais, disjuntores e muito mais, consulte recursos de gerenciamento de tráfego.

10. Parabéns!

Esperamos que este laboratório tenha oferecido uma visão geral do que o Istio pode fazer pelos seus serviços de imediato. Para saber mais sobre o Istio e o GKE.

Próximas etapas

Licença

Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.

11. Limpeza

Você pode excluir o app e desinstalar o Istio ou simplesmente excluir o cluster do Kubernetes.

Excluir o aplicativo

Para excluir o aplicativo:

kubectl delete -f aspnetcore-gateway.yaml
kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore-destinationrule.yaml
kubectl delete -f aspnetcore.yaml

Para confirmar que o aplicativo foi removido:

kubectl get gateway 
kubectl get virtualservices
kubectl get destinationrule
kubectl get pods

Desinstalar o Istio

Para excluir o Istio:

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

Para confirmar que o Istio foi removido:

kubectl get pods -n istio-system

Excluir o cluster do Kubernetes

gcloud container clusters delete hello-dotnet-cluster