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

1. Visão geral

O ASP.NET Core é um framework de código aberto e multiplataforma para criação de aplicativos modernos baseados em nuvem e conectados à Internet usando a linguagem de programação C#.

O Kubernetes é um sistema de código aberto para automatizar a implantação, o escalonamento e o gerenciamento de aplicativos em contêineres. Istio é um framework aberto para conectar, proteger, gerenciar e monitorar serviços.

Nesta primeira parte do laboratório, você implantará um aplicativo simples do ASP.NET Core no Kubernetes em execução no Google Kubernetes Engine (GKE) e o configurará para ser gerenciado pelo Istio.

Na segunda parte do laboratório, você vai conhecer melhor os recursos do Istio, como métricas, rastreamento, gerenciamento de tráfego dinâmico, injeção de falhas e muito mais.

O que você vai aprender

  • Como criar e empacotar um aplicativo simples do ASP.NET Core em um contêiner do Docker
  • Como criar um cluster do Kubernetes com o Google Kubernetes Engine (GKE).
  • Como instalar o Istio em um cluster do Kubernetes no GKE
  • Como implantar o aplicativo ASP.NET Core e configurar o tráfego para ser gerenciado pelo Istio.

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 conta do Gmail ou do Google Workspace, se ainda não tiver uma.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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 custo financeiro.

Inicie o Cloud Shell

Embora o Google Cloud possa ser operado remotamente em um 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 Shell4292cbf4971c9786.png.

bce75f34b2c53987.png

Se você nunca iniciou o Cloud Shell antes, uma tela intermediária (abaixo da dobra) será exibida com a descrição dele. Se esse for o caso, clique em Continuar (e você não verá mais esse aviso). Esta é a aparência dessa tela única:

70f315d7b402b476.png

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

fbe3a0674c982259.png

Essa máquina virtual tem 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`
  1. Execute o seguinte comando no Cloud Shell para confirmar que o comando gcloud sabe sobre seu projeto:
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. Crie um aplicativo do ASP.NET Core no Cloud Shell

No prompt do Cloud Shell, verifique a versão da ferramenta de linha de comando dotnet para confirmar se ela já está instalada. Isso deve imprimir a versão da ferramenta de linha de comando dotnet instalada:

dotnet --version

Em seguida, crie uma nova estrutura para o app da Web ASP.NET Core.

dotnet new mvc -o HelloWorldAspNetCore

Esse comando cria um projeto e restaura as dependências dele. Você verá uma mensagem semelhante ao exemplo abaixo.

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. Execute o aplicativo do ASP.NET Core

Estamos quase prontos para executar o app. Navegue até a pasta do app.

cd HelloWorldAspNetCore

Por fim, execute o app.

dotnet run --urls=http://localhost:8080

O aplicativo começará a ouvir na porta 8080.

Hosting environment: Production
Content root path: /home/atameldev/HelloWorldAspNetCore
Now listening on: http://[::]:8080
Application started. Press Ctrl+C to shut down.

Para verificar se o app está em execução, clique no botão de visualização da Web, no canto superior direito, e selecione "Visualizar na porta 8080".

Capture.PNG

Você verá a página da Web padrão do ASP.NET Core:

f579a9baedc108a9.png

Depois de verificar se o app está em execução, pressione Ctrl+C para encerrá-lo.

5. Empacotar o aplicativo do ASP.NET Core em um contêiner do Docker

Em seguida, prepare o app para ser executado como um contêiner. O primeiro passo é definir o contêiner e o conteúdo dele.

No diretório base do app, crie um Dockerfile para definir a imagem Docker.

touch Dockerfile

Adicione o código a seguir a Dockerfile usando seu editor favorito (vim, nano,emacs ou o editor de código do Cloud Shell).

# Use Microsoft's official build .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-sdk/
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /app

# Install production dependencies.
# Copy csproj and restore as distinct layers.
COPY *.csproj ./
RUN dotnet restore

# Copy local code to the container image.
COPY . ./
WORKDIR /app

# Build a release artifact.
RUN dotnet publish -c Release -o out

# Use Microsoft's official runtime .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-aspnet/
FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS runtime
WORKDIR /app
COPY --from=build /app/out ./

# Make sure the app binds to port 8080
ENV ASPNETCORE_URLS http://*:8080

# Run the web service on container startup.
ENTRYPOINT ["dotnet", "HelloWorldAspNetCore.dll"]

Uma importante configuração incluída no seu Dockerfile é a porta em que o aplicativo escuta o tráfego de entrada (8080). Isso é feito configurando a variável de ambiente ASPNETCORE_URLS, que os aplicativos do ASP.NET Core usam para determinar qual porta detectar.

Salvar esta Dockerfile. Agora, vamos criar a imagem:

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

Depois que o processo for concluído (o download e a extração levar um tempo), você vai perceber que a imagem foi criada e salva localmente:

docker images

REPOSITORY                             TAG   
gcr.io/yourproject-XXXX/hello-dotnet   v1            

Teste a imagem localmente com o seguinte comando, que vai executar um contêiner do Docker localmente na porta 8080 usando a imagem de contêiner recém-criada:

docker run -p 8080:8080 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

E mais uma vez, aproveite o recurso de visualização da Web do Cloud Shell :

Captura de tela de 2015-11-03 17:20:22.png

A página da Web padrão do ASP.NET Core vai aparecer em uma nova guia.

f579a9baedc108a9.png

Depois de verificar se o app está funcionando bem localmente em um contêiner do Docker, interrompa o contêiner em execução usando Ctrl-> C.

Agora que a imagem funciona como esperado, envie-a para o Google Container Registry. Ele é um repositório privado para imagens do Docker que todos os projetos do Google Cloud podem acessar, além de estar disponível também fora do Google Cloud Platform.

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

Se tudo correr bem e depois de um tempo, você verá a imagem do contêiner listada na seção do Container Registry. Agora, você tem uma imagem Docker para todo o projeto disponível que o Kubernetes pode acessar e orquestrar, como você verá em alguns minutos.

73558f3a54ce1c0c.png

Se quiser, navegue pelas imagens de contêiner armazenadas no Google Cloud Storage neste link: https://console.cloud.google.com/storage/browser/ (o link resultante completo deve estar neste formato: https://console.cloud.google.com/project/PROJECT_ID/storage/browser/).

6. Criar um cluster do Kubernetes/GKE com o Istio

Primeiro, verifique se a API Kubernetes Engine está ativada:

gcloud services enable container.googleapis.com

Criar um cluster do Kubernetes É possível mudar a região para algum lugar próximo a você, se quiser:

gcloud container clusters create hello-istio \
  --cluster-version=latest \
  --machine-type=n1-standard-2 \
  --num-nodes=4 \
  --region europe-west1

Aguarde até que o cluster esteja configurado. Ele fica visível na seção "Kubernetes Engine" do console do Google Cloud Platform.

e46fd9c6ee82bcc4.png

Neste codelab, você vai fazer o download e a instalação do Istio em istio.io. Há outras opções de instalação, incluindo o complemento do Istio para GKE e o Anthos Service Mesh. As etapas do aplicativo após esta funcionarão em qualquer instalação do Istio.

Primeiro, vamos fazer o download do cliente e das amostras do Istio. A página de versão do Istio permite fazer o download de artefatos para vários sistemas operacionais. No nosso caso, podemos usar um comando conveniente para fazer o download e extrair a versão mais recente da plataforma atual:

curl -L https://istio.io/downloadIstio | sh -

O script informará a versão do Istio que foi baixada:

Istio has been successfully downloaded into the istio-1.8.1 folder on your system.

O diretório de instalação contém aplicativos de exemplo e o binário de cliente istioctl. Mude para este diretório:

cd istio-1.8.1

Copie e cole o comando fornecido para adicionar o diretório bin ao seu PATH, para que você possa usar istioctl:

export PATH="$PATH:/home/<YOURHOMEID>/istio-1.8.1/bin"

Para verificar se istioctl está disponível, verifique se o cluster está pronto para o Istio:

istioctl x precheck

Você verá uma mensagem dizendo Install Pre-Check passed! The cluster is ready for Istio installation.

Instale o Istio com o perfil de demonstração:

istioctl install --set profile=demo

Agora o Istio está instalado no cluster.

Injeção automática de arquivos secundários

Para começar a usar o Istio, não é necessário fazer mudanças no aplicativo. Quando você configura e executa os serviços, os arquivos secundários do Envoy são injetados automaticamente em cada pod do serviço.

Para que isso funcione, é necessário ativar a injeção do arquivo secundário para o namespace ("padrão") usado nos seus microsserviços. Para isso, aplique um rótulo:

kubectl label namespace default istio-injection=enabled

Para verificar se o rótulo foi aplicado, execute o seguinte comando:

kubectl get namespace -L istio-injection

A saída confirma que a injeção do arquivo secundário está ativada para o namespace padrão:

NAME              STATUS   AGE    ISTIO-INJECTION
default           Active   3m     enabled
istio-system      Active   63s    disabled
...

7. Verifique a instalação

O Istio vem com três serviços: o plano de controle istiod e gateways de entrada e saída (que você pode considerar como "proxies secundários para o restante da Internet") chamados istio-ingressgateway e istio-egressgateway, respectivamente.

kubectl get svc -n istio-system

A saída será parecida com esta:

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                                                     AGE
istio-egressgateway    ClusterIP      10.55.252.182   <none>
istio-ingressgateway   LoadBalancer   10.55.250.185   35.233.118.42
istiod                 ClusterIP      10.55.253.217   <none>

O gateway de entrada tem um tipo LoadBalancer, para que seja acessível pela Internet. os outros só precisam ser acessíveis de dentro do cluster.

Em seguida, verifique se os pods correspondentes do Kubernetes estão implantados e se todos os contêineres estão funcionando:

kubectl get pods -n istio-system

Quando todos os pods estiverem em execução, será possível continuar.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod: o plano de controle do Istio. Gerencia a configuração e a programação dos arquivos secundários de proxy, descoberta de serviços, distribuição de certificados e injeção de arquivos secundários
  • ingress gateway: processa solicitações recebidas de fora do cluster.
  • egress gateway: lida com as solicitações de saída para endpoints fora do cluster.

8. Implantar o aplicativo

Depois de confirmar que o Istio está instalado e em execução, implante o aplicativo ASP.NET Core.

Implantação e serviço

Primeiro, crie um arquivo aspnetcore.yaml usando seu editor favorito (vim, nano,emacs ou o editor de código do Cloud Shell) e defina a implantação e o serviço do Kubernetes para o aplicativo:

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

O conteúdo do arquivo apresenta implantações e serviços padrão para implantar o aplicativo e não contém nada específico do Istio.

Implante os serviços no namespace padrão com kubectl:

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

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

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s

Gateway e VirtualService

Para permitir que o tráfego de entrada chegue à malha, você precisa criar um Gateway e um VirtualService.

O gateway configura um balanceador de carga para o tráfego HTTP/TCP, normalmente operando na borda da malha para permitir o tráfego de entrada de um aplicativo. Um VirtualService define as regras que controlam como as solicitações para um serviço são roteadas dentro de uma malha de serviços do Istio.

Crie um arquivo aspnetcore-gateway.yaml para definir o gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: aspnetcore-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

Crie um arquivo aspnetcore-virtualservice.yaml para definir o VirtualService:

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

Execute o comando kubectl para implantar o gateway com:

kubectl apply -f aspnetcore-gateway.yaml

O comando produz a seguinte saída:

gateway.networking.istio.io "aspnetcore-gateway" created

Em seguida, execute o seguinte comando para implantar o VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

O comando produz a seguinte saída:

virtualservice.networking.istio.io "aspnetcore-virtualservice" created

Verifique se tudo está em execução:

kubectl get gateway
NAME                      AGE
aspnetcore-gateway   28s
kubectl get virtualservice
NAME                             AGE
aspnetcore-virtualservice   33s

Parabéns! Você acabou de implantar um aplicativo com o Istio ativado. Em seguida, o aplicativo será usado.

9. Testar o aplicativo

Por fim, o aplicativo estará em ação. Você precisa saber o IP externo e a porta do gateway. Ela está listada em EXTERNAL-IP:

kubectl get svc istio-ingressgateway -n istio-system

Exporte o IP externo e a porta para uma variável GATEWAY_URL:

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')

export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

Use curl para testar o app. O serviço responderá com um código de resposta 200:

curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/

Como alternativa, você pode abrir o navegador e navegar até http://<gatewayurl> para ver o app:

f579a9baedc108a9.png

10. Parabéns!

Você acabou de implantar um app simples do ASP.NET Core no Kubernetes em execução no Google Kubernetes Engine (GKE) e o configurou para ser gerenciado pelo Istio.

Talvez você esteja se perguntando: "Qual é a vantagem do Istio?". Essa é uma ótima pergunta. Até agora, não há vantagem em ter o Istio gerenciando esse aplicativo. Na segunda parte do laboratório, vamos conhecer melhor os recursos do Istio, como métricas, rastreamento, gerenciamento de tráfego dinâmico, visualização de serviços e injeção de falhas.

Próximas etapas

Licença

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

11. Limpeza

Se você não continuar para a segunda parte do laboratório, poderá excluir o app e desinstalar o Istio ou simplesmente excluir o cluster do Kubernetes.

Excluir o app

Para excluir o aplicativo, siga estas etapas:

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

Para confirmar se o app desapareceu:

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

Desinstalar o Istio

Para excluir o Istio:

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

Para confirmar se o Istio desapareceu:

kubectl get pods -n istio-system

Excluir cluster do Kubernetes

gcloud container clusters delete hello-istio