Back-End

26 jun, 2018

ASP.NET Core + Azure + Kubernetes: orquestração de containers na nuvem – Parte 01

Publicidade

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:

Referências