Kubernetes - Deploy de aplicação ASP .NET Core


 Hoje vamos fazer o deploy de uma aplicação ASP .NET Core MVC no Kubernetes usando o  minikube e aplicando os conceitos sobre Pods,  Replicaset, Deployment e Service que já apresentamos.

O objetivo deste artigo é fixar os conceitos apresentados nos artigos anteriores fazendo uma aplicação pratica a um nível básico.


Para realizar essa tarefa iremos usar os seguintes recursos:

Assim vamos partir de uma aplicação ASP.NET Core MVC criada no VS 2022 usando o .NET 6 que apresenta informações sobre Pizzas. 

A aplicação é bem simples e não usa um banco de dados criando apenas uma lista de objetos com informações sobre Pizzas que exibimos em uma View.

A seguir vamos criar um arquivo Dockerfile para esta aplicação e a partir deste arquivo vamos gerar uma imagem que iremos enviar para o Docker Hub.

Depois vamos criar um Deployment com base nesta imagem e aplicar no cluster Kubernetes usando o minikube onde teremos o container com nossa aplicação em um Pod sendo executado no cluster Kubernetes.

A seguir vamos criar um Service para poder acessar nossa aplicação usando o navegador padrão :

A figura acima mostra o fluxo básico com as tarefas que iremos realizar para fazer o deploy da aplicação no Kubernetes e acessar a aplicação no Navegador.

Vamos partir da aplicação ASP .NET Core MVC que você pode obter do meu repositório no github : https://github.com/macoratti/frontend

Com o projeto aberto, para criar o arquivo Dockerfile vamos usar o ambiente do Visual Studio 2022; vamos clicar com o botão direito sobre o nome do projeto e selecionar a opção Add->Docker Support;

Será apresentada a janela abaixo onde vamos marcar a opção Linux e clicar em OK:

Com isso teremos o arquivo Dockerfile gerado no projeto com o código abaixo:

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["frontend/frontend.csproj", "frontend/"]
RUN dotnet restore "frontend/frontend.csproj"
COPY . .
WORKDIR "/src/frontend"
RUN dotnet build "frontend.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "frontend.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "frontend.dll"]

Para gerar a imagem a partir deste arquivo vamos clicar com o botão direito sobre o nome do projeto e selecionar a opção : Open in terminal

Será aberta uma janela usando o PowerShell na pasta do nosso projeto.

Vamos retroceder um nível nos posicionando na pasta \frontend,  isso é necessário pois o arquivo Dockerfile faz a cópia dos arquivos a partir da pasta frontend.

A seguir vamos emitir o seguinte comando para criar a imagem:

docker build -f frontend\Dockerfile -t pizzafrontend .
 

Com isso teremos a imagem pizzafrontend criada, e podemos conferir isso usando o dashboard do Docker Desktop for Windows:

Agora temos que enviar a imagem gerada para o repositório no Docker Hub. Para isso você tem que ter uma conta privada no Docker Hub.

As instruções para criar e a conta você encontra neste link:  https://docs.docker.com/docker-id/

Vou usar a minha conta privada no Docker Hub identificada pelo login macoratti.

Assim teremos que fazer o login na conta no Docker Hub e enviar as imagens. Para isso podemos fazer usar os comandos:

1- Fazer o login :  docker login

2- Taguear a imagem :  docker tag pizzafrontend [DOCKER USER NAME]/pizzafrontend

3- Enviar a imagem para o repositório no Docker Hub : docker push [DOCKER USER NAME]/pizzafrontend

Em [DOCKER USER NAME] você deve informar o seu login. Para a minha conta os comandos ficaram assim:

docker login
docker tag pizzafrontend
macoratti/pizzafrontend
docker push
macoratti/pizzafrontend

Com isso temos a imagem enviada para o repositório no Docker Hub onde o Kubernetes poderá obter a imagem para realizar o deployment.

Abaixo o meu repositório no Docker Hub com a imagem enviada:

Agora vamos criar o arquivo de Deployment para implantar a nossa aplicação no cluster Kubernetes.

Para isso vamos criar o arquivo frontend-deploy.yml com o seguinte código:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pizzafrontend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: pizzafrontend
    spec:
      containers:
      - name: pizzafrontend
        image: macoratti/pizzafrontend:latest
        ports:
        - containerPort: 80
        env:
        - name: ASPNETCORE_URLS
          value: http://*:80
  selector:
    matchLabels:
        app: pizzafrontend

Neste arquivo de definimos o seguinte:

Para aplicar este deployment no Kubernetes usamos o comando:  kubectl apply -f frontend-deploy.yml

Para verificar o ambiente no minikube podemos usar os comandos :

kubectl get deploy
kubectl describe deploy pizzafrontend

kubectl get all

Acima vemos o Pod , o Deployment e o Replicaset criados no kubernetes.

Agora vamos criar o Service para expor nossa aplicação ao mundo externo e poder acessá-la usando o navegador.

Vamos criar o arquivo YAML frontend-service.yml :

apiVersion: v1
kind: Service
metadata:
  name: pizzafrontend
spec:
  type: NodePort
  selector:
     app: pizzafrontend   
  ports:
    - port: 8080
      targetPort: 80

Neste serviço definimos o seguinte:

Vamos aplicar o serviço no kubernetes usando o comando: kubectl apply -f frontend-service

Para conferir o resultado podemos emitir os comandos:

kubectl get svc
kubectl describe svc pizzafrontend

kubectl get all

Podemos ver o serviço pizzafrontend criado e agora podemos acessar nossa aplicação em execução no Pod.

Usando o minikube para acessar a aplicação podemos usar o comando:  minikube service <nome_do_service>

Acontece que dependendo da versão do minikube usada este comando não funciona. (Veja esta thread no stackoverflow : https://stackoverflow.com/questions/61305722/why-cant-i-access-a-service-exposed-from-minikube-on-windows )

Uma alternativa para testar o acesso à aplicação é usar o comando Kubelect port-forward.

Este comando faz uma solicitação específica para a API do Kubernetes, e, isso significa que o sistema em execução precisa de acessar a API Server e assim qualquer tráfego será encapsulado em uma única conexão HTTP. Com isso a API Server se torna, de certa forma, um gateway temporário entre sua porta local e o cluster Kubernetes.
 

O comando kubectl port-forward é útil para fins de teste/depuração para que você possa acessar seu serviço localmente sem expô-lo.

 

Vamos usar o comando :  kubectl port-forward service/pizzafrontend 7080:8080
 

Aqui estamos direcionando o tráfego da porta do host 7080  para a porta de serviço 8080, e assim poderemos acessar a aplicação na porta 7080 do host local.

Acessando o navegador em: localhost://7080 obtemos o resultado abaixo:

E assim estamos acessando nossa aplicação ASP .NET Core MVC em execução no container em um Pod implantado em um cluster Kubernetes.

Pegue o projeto aqui : https://github.com/macoratti/frontend

"Como também nos elegeu nele antes da fundação do mundo, para que fôssemos santos e irrepreensíveis diante dele em amor;"
Efésios 1:4

Referências:


José Carlos Macoratti