ASP.NET Core + Azure + Kubernetes: orquestração de containers na nuvem – Parte 01
O autor dá início a série sobre a utilização combinada do ASP.NET Core, Azure e Kubernetes para a implementação de projetos que dependam da orquestração de containers e apresenta os principais conceitos envolvendo o Kubernetes.
Inúmeras são as vantagens obtidas ao empregar containers Docker em projetos de software. Isolamento de aplicações, utilização mais racional de recursos computacionais, velocidade no deployment e uma menor dependência em relação aos ambientes operacionais estão entre os fatores que contribuem para o crescimento no uso desta tecnologia.
Por mais que as vantagens trazidas pelo Docker sejam inegáveis, existem também dificuldades decorrentes de sua adoção:
- Como escalar containers?
- Como garantir o trabalho coordenado entre os diferentes containers de uma aplicação?
- Como detectar containers com falhas e corrigir isso automaticamente?
As respostas a tais questões estão em soluções voltadas ao gerenciamento e uso orquestrado de containers Docker. Dentre as alternativas mais populares neste segmento, temos o Kubernetes, o Docker Swarm e o DC/OS da Mesosphere. O próprio Microsoft Azure não ficou alheio a este tipo de demanda, contando com um serviço conhecido como Azure Container Service e que suporta essas três tecnologias.
Mais recentemente (Outubro/2017) a Microsoft disponibilizou uma nova opção no Azure, voltada ao uso de Kubernetes: trata-se do Azure Kubernetes Service (AKS), solução que visa simplificar o gerenciamento e operação de ambientes baseados em Kubernetes.
Este artigo é a primeira parte de uma série na qual abordarei a utilização combinada do ASP.NET Core, do Microsoft Azure e do Kubernetes (através do serviço AKS) para a implementação de projetos que dependam da orquestração de containers. Neste artigo estão os principais conceitos envolvendo o Kubernetes, bem como descrita a aplicação ASP.NET Core, que servirá de base para os testes com o AKS.
Kubernetes: uma visão geral
Também conhecido como K8s ou kube, o Kubernetes é um projeto open source escrito na linguagem Go e desenvolvido originalmente pela Google. Mantido atualmente pela Cloud Native Computing Foundation, o Kubernetes conta com recursos de gerenciamento que viabilizam a orquestração, auto recuperação, reinício, replicação e escalonamento de containers Docker.
Assim como acontece com outras tecnologias populares na atualidade, o Kubernetes possui também uma ferramenta de linha de comando: o kubectl, utilitário que permite a execução de instruções voltadas ao gerenciamento de clusters e containers.
As diferentes estruturas controladas via Kubernetes serão criadas a partir de arquivos no formato YAML e por meio da execução de comandos via kubectl. Um ambiente para testes pode ser disponibilizado através da instalação do Minikube (software que possibilita a criação de um cluster local para uso do Kubernetes).
Dentro da arquitetura adotada pelo Kubernetes, merecem destaque os seguintes elementos:
- Master;
- Nodes;
- Pod;
- Deployment;
- Service;
- Replication Controller;
- Kubelet.
Um cluster no Kubernetes está dividido em:
- Master: máquina que controla e tem por responsabilidade a atribuição de tarefas aos diferentes Nodes;
- Nodes (nós): uma ou mais máquinas que realizam as tarefas atribuídas pelo Master.

Já um Pod é uma estrutura que agrupa um ou mais containers. A implantação deste elemento (Pod) acontece em algum dos Nodes disponíveis, com os containers que compõem o mesmo, compartilhando o mesmo endereço de IP, nome de host e outros recursos.
A figura a seguir traz a representação esquemática de um Pod:

Um objeto Deployment é uma abstração de um Pod, contando ainda com recursos adicionais:
A essa estrutura está associado um mecanismo de gerenciamento de estados controlado pelo Kubernetes, o qual permitirá a recuperação automática de um objeto deste tipo (Deployment) quando o mesmo se encontrar em um estado de falha;
Ao se falar da criação de um Pod, do ponto de vista prático, estamos, na verdade, definindo a geração de um novo objeto do tipo Deployment.
Na próxima imagem temos a representação de um objeto Deployment:

Um objeto do tipo Service é uma estrutura que funciona como um Load Balancer, cuidando assim do acesso aos diferentes Pods de uma aplicação. Trata-se de um elemento mais estável, até porque Pods são criados ou removidos continuamente ao se escalar uma aplicação.
Dentro da arquitetura do Kubernetes, o elemento conhecido como Replication Controller determinará quantas cópias idênticas de um Pod serão executadas e em quais locais (Nodes) do cluster. Já o Kubelet, é o serviço que garante a inicialização e execução dos containers nos diferentes Nodes.
A imagem a seguir traz mais uma representação do Kubernetes, com Pods distribuídos entre os diferentes Nodes de um cluster:

Implementando a aplicação para testes
Para os testes envolvendo o uso do Kubernetes a partir do Microsoft Azure, será criada uma API REST baseada no ASP.NET Core 2.0. Esta aplicação produzirá como retorno a quantidade de acessos à API, além de exibir o nome do host/máquina e do sistema operacional utilizado pelo container Docker.
Na próxima listagem está a implementação da classe Contador, a qual armazenará a contagem de acessos à API REST de testes:
namespace APIContagem
{
public class Contador
{
private int _valorAtual = 0;
public int ValorAtual { get => _valorAtual; }
public void Incrementar()
{
_valorAtual++;
}
}
}
Já o tipo ContadorController receberá solicitações HTTP através da Action Get, controlando a utilização sincronizada de uma instância de Contador (via instrução lock) e devolvendo o número de acessos à API, o nome da máquina/host e a versão do sistema operacional em uso:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace APIContagem.Controllers
{
[Route("api/[controller]")]
public class ContadorController : Controller
{
private static Contador _CONTADOR = new Contador();
[HttpGet]
public object Get()
{
lock (_CONTADOR)
{
_CONTADOR.Incrementar();
return new
{
_CONTADOR.ValorAtual,
Environment.MachineName,
Sistema = Environment.OSVersion.VersionString
};
}
}
}
}
A seguir, temos um exemplo de execução desta API por meio do Visual Studio 2017:

As demais etapas envolvendo a publicação da aplicação no Kubernetes serão detalhadas na segunda parte desta série. Os fontes deste projeto de testes já estão disponíveis no GitHub:








