ASP.NET no Kubernetes: Como fazer deploy da sua aplicação localmente

Kubernetes é atualmente a solução mais eficaz para gerenciamento e escalabilidade de infraestruturas baseadas em contêineres, essencial para aplicações .NET modernas. Neste artigo guiaremos você através do processo de configuração, desenvolvimento e deploy de uma aplicação .NET simples usando Kubernetes localmente. Isso não apenas simula o ambiente de produção kubernetes em cloud, mas também é um bom exercício para abordar a transição suave do desenvolvimento para a operação, utilizando ferramentas que garantem a eficiência, resiliência e a disponibilidade do sistema.

Configuração do ambiente local

Para configurar um ambiente Kubernetes local, você precisará das seguintes ferramentas:

  1. Git: instalar Git a partir do site oficial.
  2. Docker: a base para rodar contêineres. Você pode baixá-lo e instalá-lo a partir do site oficial do Docker.
  3. Kind (Kubernetes in Docker): permite executar clusters Kubernetes utilizando contêineres Docker. É ideal para testes rápidos e desenvolvimento local. Instale o Kind seguindo estas instruções.
  4. kubectl: a linha de comando do Kubernetes para gerenciar clusters e contêineres. Instale o kubectl seguindo as instruções disponíveis na documentação oficial do Kubernetes.

Aplicação de exemplo em .NET

Primeiro, baixe o exemplo de aplicação Hello World que utilizaremos:

				
					git clone https://github.com/toolbox-playground/hello-world-com-docker-languages.git
cd hello-world-com-docker-languages/dotnet/
				
			

Este repositório contém um Dockerfile para criar uma imagem docker baseada em uma aplicação .NET, que é um exemplo simples de API REST.

Para que a aplicação funcione, é necessário primeiro construir a imagem Docker localmente e enviá-la para um repositório acessível pelo seu cluster Kubernetes. Aqui estão os passos para fazer isso:

1 – Certifique-se de que Docker Engine está rodando:

				
					docker info
				
			

2 – Buildar a imagem Docker:

				
					docker build -t hello-world-dotnet:latest .
				
			

3 – Taggear a imagem para garantir que ela corresponda ao nome que será usado no Kubernetes:

				
					docker tag hello-world-dotnet:latest localhost/hello-world-dotnet:latest
				
			

Agora temos uma imagem de uma aplicação .NET criada e pronta para usar localmente, você pode checar isso usando o comando `docker images` e verificando a existência da imagem chamada `hello-world-dotnet:latest`.

4 – Por último, verifique se a imagem foi criada corretamente:

				
					docker images localhost/hello-world-dotnet
				
			

Deploy com Kubernetes

Para fazer o deploy no cluster K8s, primeiro vamos criar e configurar o cluster:

1 – Certifique-se de que o Kubernetes e Kind estão rodando.

				
					kubectl version
kind version

				
			

1.1 – Se nenhum dos comandos abaixo funcionar é porque ou não estão instalados ou não foram inicializados corretamente -> Neste caso volte à seção de configuração local e revise a instalação das 3 ferramentas.

2 – Verifique os clusters disponíveis. Se houver um cluster default, você pode usá-lo. Se não, crie um novo cluster e use-o.

				
					# Listar todos os clusters disponíveis
kubectl config get-contexts

# Se não existir nenhum cluster ativo, ou se você preferir criar um novo cluster com Kind
kind create cluster --name <nome-do--novo-cluster>

# Mudar para um contexto de cluster específico
kubectl config use-context <nome-do-cluster>
				
			

3 – [Opcional] Você pode usar o namespace default existente ou criar um novo

				
					
# Listar os namespaces existentes
kubectl get namespaces

# Configurar um dos namespaces como padrão
kubectl config set-context --current --namespace=<namespace-name>

# Se desejar criar e usar um namespace novo chamado 'my-namespace' ao invés de usar um namespace default existente
kubectl create namespace my-namespace
kubectl config set-context --current --namespace=my-namespace
				
			

Agora que temos um cluster e namespace funcionando e configurado, vamos criar o manifesto Kubernetes para fazer o deploy desta aplicação. Crie um arquivo chamado `manifest.yaml` no diretório da aplicação (e.g. `touch manifest.yaml` dentro do diretório `hello-world-com-docker-languages/dotnet/`) e adicione o seguinte conteúdo neste novo arquivo:

				
					apiVersion: apps/v1
kind: Deployment
metadata:
 name: dotnet-hello-world
spec:
 replicas: 1
 selector:
   matchLabels:
     app: dotnet-hello-world
 template:
   metadata:
     labels:
       app: dotnet-hello-world
   spec:
     containers:
     - name: dotnet-hello-world
       image: localhost/hello-world-dotnet:latest
       imagePullPolicy: IfNotPresent
       ports:
       - containerPort: 8080
       resources:
         requests:
           cpu: "250m"
           memory: "256Mi"
         limits:
           cpu: "500m"
           memory: "512Mi"

---
apiVersion: v1
kind: Service
metadata:
 name: dotnet-hello-world-service
spec:
 type: NodePort
 ports:
 - port: 8080
   nodePort: 30000   #Altere a porta do node o quanto você quiser em um range de 30000-32767
 selector:
   app: dotnet-hello-world
				
			

Este arquivo define um Deployment e um Service para a aplicação. O Deployment específica que queremos uma réplica da aplicação rodando, e o Service expõe a aplicação na porta 30000 do nó.

Para aplicar este manifesto e fazer o deploy da aplicação no seu cluster Kubernetes, use o comando:

				
					kubectl apply -f manifest.yaml
				
			

No fim disso, você terá uma aplicação rodando em cima de um container, como mostra a imagem a seguir. Além disso, você poderá acessar a aplicação através de `http://localhost:30000` após o deploy.

[Opcional]  A criação do Deployment e do Serviço também podem ser feito via linha de comando e sem a necessidade da criação do manifesto, mas encorajamos que criem o manifesto por ser uma boa prática.
				
					# Exemplo Criação de Deployment e Service via kubectl command line e sem o manifesto

# Criar um deployment chamado 'my-deployment' com a imagem do Grafana
kubectl create deployment my-deployment --image=localhost/hello-world-dotnet:latest --namespace=my-namespace
# Verificar o Deployment
kubectl get deployments --namespace=my-namespace

# Expor o deployment 'my-deployment' via NodePort
kubectl expose deployment caio-deployment --type=LoadBalancer --port=80 --target-port=3000 --protocol=TCP

# Obter o serviço exposto para encontrar o NodePort atribuído
kubectl get service my-deployment --namespace=my-namespace

				
			

Explicando o manifesto k8s

O manifesto do Kubernetes define a configuração e o comportamento dos recursos no cluster. As partes essenciais do manifesto incluem o tipo de recurso (kind), especificações (spec), e configurações dos contêineres (containers) com detalhes sobre imagens, portas, e recursos de computação.

Diferença entre kubectl apply e kubectl create:

  • kubectl apply: Recomendado para gerenciamento declarativo dos recursos, ou seja quando declaramos um arquivo yaml contendo os recursos do serviço e das pods. Permite atualizar e criar recursos com base no arquivo de manifesto. Mantém um registro dos arquivos aplicados para permitir atualizações contínuas.
  • kubectl create: Usado para criação imperativa. Cria recursos baseando-se em um arquivo ou stdin (linha de comando, como fizemos no exemplo anterior), mas não gerencia mudanças incrementais ou registros.

Usar kubectl apply oferece mais flexibilidade para atualizações contínuas e gerenciamento de estado desejado, enquanto kubectl create é útil para criações simples e diretas sem a necessidade de atualizações futuras.

A seguir, alguns objetos chave do arquivo manifesto:

  1. kind: Deployment
    • O Deployment controla a criação, atualização e remoção de pods de acordo com as definições especificadas. Ele ajuda a manter as instâncias de aplicativos atualizadas.
  2. spec:
    • Define o comportamento desejado do pod, detalhando como os contêineres devem operar.
  3. replicas:
    • Especifica o número de réplicas/pods que o Kubernetes deve manter em execução. O padrão é 1 se não especificado.
  4. containers:
    • Lista de contêineres dentro do pod. A configuração de cada contêiner, incluindo a imagem a ser usada, portas a serem expostas e os recursos necessários.
  5. resources:
    • Define os limites de recursos para os contêineres, como CPU e memória, garantindo que o contêiner não ultrapasse os recursos alocados.
    • requests: Especifica a quantidade mínima de recursos que o contêiner deve ter garantido.
    • limits: Define o máximo de recursos que o contêiner pode usar.

Através desse arquivo Deployment, o Kubernetes pode gerenciar automaticamente a aplicação, escalonando-a ou ajustando-a conforme necessário baseado nas definições de recursos e réplicas. Para mais informações, consulte a documentação oficial.

Testando a App Rodando Após Deploy no Cluster K8S

Com todos os passos anteriores feitos, sua aplicação deve estar rodando localmente sobre um cluster kubernetes. Você pode executar os seguintes comandos para verificar seu deployment, serviço e pods rodando para o seu service. Esta seção vai mostrar como operar seu serviço através de Comandos Kubernetes para:

  • Verificar Deployment, Serviços e pods: 
				
					kubectl get deployment
kubectl describe deployment dotnet-hello-world (opcional)
kubectl get service
kubectl get pods ou docker ps
kubectl describe pod <nome-do-pod>

				
			

Acesso à aplicação: A aplicação pode ser acessada através do endereço http://localhost:30000 após o deploy, dependendo da configuração do NodePort no serviço, e verá que sua aplicação dotnet está Up & Running:

Pods: Logs, Debug, Acesso e Troubleshooting:

				
					kubectl get pods
kubectl logs <my_pod_name>

# Executar um shell interativo em um contêiner específico
kubectl exec -it <nome-do-pod> -- /bin/bash

# Iniciar uma sessão de debug para um pod problemático
kubectl debug -it <nome-do-pod> --image=<imagem-de-debug> --copy-to=<nome-do-pod-debug>

				
			

Visualizar uso de recursos: Deve ter o MetricsServer habilitado.

				
					# Ver uso de CPU e memória dos pods
kubectl top pod

# Ver uso de CPU e memória dos nós
kubectl top nodes

				
			

Listar eventos do cluster:

				
					# Listar eventos recentes
kubectl get events

				
			

[Opcional] Se você tiver o kubernetes lens ou docker desktop instalados localmente, explore também os recursos utilizando a UI que essas ferramentas fornecem, como mostramos a seguir:

Acelere a sua carreira conosco!

A Mentoria DevOps é um programa de mentoria de 12 meses com encontros semanais ao vivo, com um grupo seleto e restrito, onde estaremos do seu lado para mantê-lo relevante e atualizado no mercado de tecnologia, aprendendo e implementando as melhores práticas e ferramentas de DevOps.

Clique aqui para entrar na prioridade pela melhor oferta de lançamento

Conclusão

Ao finalizar este guia prático de deploy de uma aplicação .NET em Kubernetes localmente, você agora tem uma base para explorar mais a fundo o gerenciamento de contêineres e a automação de ambientes e infraestrutura de desenvolvimento e produção. Continuar aprimorando suas habilidades permitirá enfrentar desafios mais complexos e maximizar o potencial das suas aplicações.