Este é o segundo artigo da série sobre Kubernetes. Se você está chegando agora para a mesma, recomendo fortemente visitar a página onde todos os artigos estão sendo listados, disponível através deste link. Se você preferir efetuar a leitura do primeiro artigo diretamente, você poderá fazê-lo seguindo este outro link.
Como você pôde perceber, no primeiro artigo me concentrei em apresentar Kubernetes como um todo. O que é, como funciona, visão geral do modelo operacional e ainda, preparamos um ambiente local para que pudéssemos nos artigos posteriores, executar “coisas” práticas com a solução de orquestração que aqui estamos estudando.
O artigo de hoje é, portanto, uma continuação deste processo evolutivo de aprendizagem. Hoje, faremos o deploy de nossa primeira aplicação (ASP.NET Core) “containerizada” com docker para um cluster de containers utilizando o Kubernetes. Para isso, vou dividir o artigo em duas partes: 1) iremos criar uma aplicação ASP.NET Core básica (MVC) e iremos adicioná-la a um container docker. Após realizarmos esta operação, iremos testar seu funcionamento localmente. 2) Faremos o deploy para o cluster de containers utilizando o kubectl.
Etapa 1: Criando a aplicação de exemplo
Como existem vários aspectos que podem ser explorados ao longo desta série sobre Kubernetes, achei interessante criar uma aplicação ASP.NET Core que poderá ao longo de todo este caminho de aprendizagem, ser a aplicação de apoio para explorarmos tais conceitos. Dessa forma, na primeira parte deste post, irei apresentar os passos que segui para criar e conteinerizar a mesma.
Pré-requisitos
Irei utilizar o docker para conteinerizar a aplicação, portanto, um pré-requisito básico para que você consiga reproduzir este exemplo é ter o docker localmente instalado. Para visualizar um guia sobre como instalar o Docker em sua máquina de trabalho, por favor, siga este link.
Você também irá precisar do .NET Core instalado em sua máquina, uma vez que iremos criar uma aplicação ASP.NET Core como exemplo. Dessa maneira, se você não possui a instalação da versão mais recente do .NET Core, vá até o repositório de downloads do framework (disponível neste link) e pegue a sua.
Estou fazendo todo este processo de criação da aplicação no Mac utilizando o Yoman. Se você estiver em outro ambiente operacional e quiser criar a aplicação seguindo seu próprio modelo de trabalho, por favor, fique a vontade. Se quiser seguir exatamente o modelo que estou propondo aqui, você precisará instalar o Yoman. Para ver como fazer isso, por favor, siga este link.
Criando a aplicação com Yoman
Conforme mencionado anteriormente, estou criando a minha aplicação a partir do Mac OS. Portanto, preferi instalar o Yoman e após isso, criar a mesma. Para criar a aplicação, simplesmente fui até meu terminal e digitei o comando yo
. O Yoman então me mostrou dois geradores que ele possui em minha máquina (ver Figura 1).
Figura 1. Chamando o gerador de aplicações com Yoman
Selecione então a opção “Aspnet”, conforme ilustra a Figura 1. Ao fazê-lo, recebi do Yoman a resposta apresentada pela Figura 2, pedindo para que eu selecione o tipo de projeto que pretendo criar.
Figura 2. Selecionando o projeto que será criado
Para nosso exemplo, estou criando uma aplicação de frontend com MVC sem membership e authorization por enquanto. Vamos evoluir com isso mais tarde na série. Ao realizar esta seleção, o Yoman me questiona sobre qual framework de frontend eu gostaria de utilizar, me dando duas opções de escolha: Bootstrap e Semantic UI (veja a Figura 3).
Figura 4. Selecionando o framework de frontend para a aplicação
Ao selecionar “Bootstrap”, o Yoman me fez então uma pergunta sobre o nome da minha aplicação (nada mais óbvio, certo?!). Como é possível visualizar na Figura 5, ao informar o nome “App01-HelloWorld”, pressionar enter e, após isso, digitar o comando ls
na pasta local, um novo diretório com todos os arquivos da aplicação foi criado.
Figura 5. Visualizando a aplicação criada na listagem de diretórios
Agora, afim de verificar o funcionamento de sua aplicação localmente, navegue até o diretório root da mesma, e execute na sequência, os comandos:
dotnet restore
dotnet run
Se tudo correu bem, você deverá estar visualizando em seu navegador algo semelhante aquilo que apresenta a Figura 6.
Figura 5. Executando a aplicação ASP.NET Core recém criada
Pronto! Aplicação já de pé. Como você pode observar, fiz algumas pequenas alterações na aplicação só para ficar mais personalizada para nossa série de posts. Mas isso não importa. Se você preferir seguir outro caminho, a aplicação de exemplo já encontra-se disponível no meu GitHub. Você pode clonar o repositório para usar de acordo com sua necessidade.
Containerizando a aplicação
Agora que temos a aplicação já funcional, vamos criar um ambiente conteinerizado para que ela possa rodar em ambiente produtivo e o primeiro passo para isso, é realizar a publicação da aplicação que criamos para o ambiente local. Para isso, vá até o terminal e no diretório root da aplicação, digite o seguinte comando:
Ao fazer isso, o .NET irá criar dentro da pasta “bin/Debug/{sua versão de .net core}” uma pasta chamada “publish”. Esta pasta possui sua aplicação pronta para ir ao ambiente produtivo. Com isso, estamos prontos para submeter a aplicação ao container produtivo.
Ok, estamos prontos para publicar nossa aplicação no container. Para isso, iremos utilizar o docker como engine de virtualização. Como você deve saber, o elemento chave para que possamos criar um container para uma aplicação com docker é o arquivo Dockerfile. Você poderá encontrar mais detalhes sobre este arquivo e sua relevância para um projeto de containers seguindo este link. Para iniciar, crie um arquivo chamado “Dockerfile” no root da aplicação criada anteriormente e em seu interior, adicione o conteúdo apresentado pela Listagem 1.
Listagem 1. Dockerfile da solução de exemplo
Segue uma breve explicação do que estamos fazendo com este Dockerfile:
- Linha 2: Estamos fazendo o pulling (baixando) da imagem específica do ASP.NET Core de produção que vai de encontro as necessidades de nossa aplicação. No caso, estamos utilizando a versão 1.0.4 do .NET Core (versão mais recente do Yoman).
- Linha 5: Estamos “dizendo” ao docker que o diretório “app” criado a partir da raiz do container, será nosso diretório root para a aplicação.
- Linha 8: Estamos copiando todo o conteúdo de nossa aplicação recém publicada (lembra-se do comando dotnet publish?) para o diretório raiz. O “.” indica que este fato. Vale lembrar que é considerado diretório raiz pelo docker, o diretório que armazena o arquivo Dockerfile.
- Linhas 11 e 12: Estamos expondo o container para acesso público através da porta 80 e dizendo que a comunicação irá ocorrer sobre HTTP.
- Linha 15: Estamos executando a aplicação de fato através da aplicação do comando “dotnet” sobre a DLL “App01-HelloWorld” gerada pelo publish.
Pronto. Configuração pronta. Agora podemos avançar e de fato, criar nosso container. Fazemos isso através da utilização do comando “docker build”. Para saber os detalhes de utilização desta diretiva, por favor, siga este link.
Uma informação importante aqui: logo mais, quando formos despachar este container no cluster do Kubernetes, precisaremos apontar o processo de deploy do kubectl para o registry de imagens docker. Para nossos exemplos aqui, irei utilizar o próprio repositório do docker, isto é, o docker hub. Portanto, precisamos pensar já agora no momento de “buildar” nosso container, em como iremos nomear e “tagear” o mesmo para posterior publicação e download do/para o docker hub. Dessa forma, fui ao terminal e executei o build da seguinte maneira (Listagem 2).
Listagem 2. “Buildando” o container localmente
Se tudo correu bem, você deverá estar visualizando uma resposta semelhante àquela apresentada pela Figura 6, indicando o sucesso do processo de construção do container em seis etapas.
Figura 6. Visualizando o retorno (positivo) da construção de nosso container
Ok. Agora, nos resta testar se este container recém criado está funcionando corretamente. Para isso, vá até o terminal e digite a sentença apresentada pela Listagem 3.
Listagem 3. Executando o container recém criado
Se tudo correu bem, você visualizará uma mensagem indicando que o servidor está sendo ouvido na porta “http://+:80”. Se você for até o navegador de sua preferência e digitar a URL “http://localhost:8080”, você deverá visualizar a aplicação em execução já dentro do container, conforme apresenta a Figura 7.
Figura 7. Verificando o funcionamento do container dentro do container docker local
Agora, para finalizar o processo da aplicação, nos resta publicar a mesma no docker hub para posterior consumo no processo de deploy do Kubernetes.
Para que seja possível publicar um container no docker hub, algumas premissas precisam ser respeitadas:
- É preciso ter uma conta no docker hub;
- É preciso ter o repositório para o qual se deseja publicar o container;
- É preciso ter a imagem com a(s) tag(s) que irão facilitar sua identificação;
O ítem 3 já respeitamos, uma vez que, no momento de build, nomeamos a imagem e adicionamos uma tag de identificação. No meu caso, os ítens 1 e 2 também já estão satisfeitos, uma vez que já tenho uma conta do docker hub e da mesma maneira, já possuo o repositório criado (estou chamando aqui de “LearningKubernetes”). Se você não possui uma conta no docker hub, você pode criá-la seguindo este link. Se você já possui a conta mas não o repositório, para criar um novo, siga o procedimento descrito neste link.
Com todos os requisitos a disposição, para publicar o container no repositório recém criado, siga os seguintes passos:
Autentique-se no docker hub: para isso, vá até o terminal e digite a expressão apresentada pela Listagem 4. Se tudo correu bem, você visualizará em seu terminal a seguinte mensagem “Login Succeeded“.
Listagem 4. Autenticando-se no docker hub
Faça o push do container: agora, para publicar o container no docker hub, vá até o terminal e digite a expressão apresentada pela Listagem 5. Se tudo der certo, você verá no terminal uma mensagem de sucesso e após isso, poderá ir na interface gráfica do docker hub e verificar sua publicação já disponível para uso para outros usuários (veja a Figura 8).
Listagem 5. Publicando o container para o docker hub
Figura 8. O container publicado no repositório no docker hub
Etapa 2: Publicando o container com Kubernetes
Agora que já temos a aplicação de referência, estamos prontos para iniciar o processo de publicação deste container em nosso cluster. Entretanto, antes de seguirmos com o processo de deployment propriamente dito, precisamos entender de maneira conceitual, como funciona um processo de deploy gerenciado pelo Kubernetes.
Em termos de deploy, Kubernetes possui um módulo principal de operação – Kubernetes deployment. Sempre que um novo deployment deve ocorrer em um cluster Kubernetes, o deployment entra em ação para orquestrar todo o processo de dispatch do(s) container(s) no ambiente. É responsabilidade do deployment, por exemplo, cuidar do agendamento da publicação dos containers nas instâncias (nós) do cluster de acordo com a disponibilidade de cada Pod (não se preocupe, falaremos disso mais tarde). Também é responsabilidade do mecanismo de deploy atualizar instâncias (containers) da aplicação, de modo a prover updates para estas quando eles estiverem disponíveis, etc.
Outra importante atuação do mecanismo de deploy está no monitoramento constante e efetivo das instâncias (containers) da aplicação. Se por alguma razão um ou mais nós que executam os containers da aplicação saírem de operação, será responsabilidade do mecanismo de deploy garantir que outra instância destes containers sejam automaticamente transferidas para nós disponíveis no sentido de garantir a alta disponibilidade dos serviços da aplicação.
A Figura 9 a seguir apresenta uma visão gráfica sobre a distribuição dos serviços no cluster Kubernetes.
Figura 9. Deployment rodando no master do cluster Kubernetes
Vamos então realizar nosso primeiro deployment. Para isso, utilizaremos a aplicação que criamos e containerizamos na primeira metade deste post. Para realizar o deployment, vá até o terminal e digite a expressão apresentada pela Listagem 6 e pressione enter.
Listagem 6. Criando um deployment da aplicação ASP.NET Core de exemplo
Se tudo correu bem, você deverá visualizar a seguinte mensagem de confirmação: “deployment ‘kubernetes-frontend’ created“, indicando o sucesso da criação do processo de deployment. Para confirmar que o deployment foi criado, no seu terminal você pode digitar ainda “kubectl get deployments"
. Este comando deverá retornar uma lista de deployments ativos e um deles deverá ser “kubernetes-frontend”, conforme nossa parametrização.
Uma pequena explicação sobre a linha de comando apresentada pela Listagem 6:
- kubectl run: ordena ao kubernetes que um novo processo (neste caso, deployment) ocorra.
- kubernetes-frontend: nome dado ao deployment que estamos requisitando.
- –image=docker.io/fabriciosanchez/learningkubernetes:kubernetes-frontend-104: indicamos ao kubernetes onde ele deverá buscar a imagem base para a construção do container no cluster. Repare que estamos passando a informação completa, isto é, usuário do docker hub + nome do repositório no docker hub + a tag do mesmo.
- –port=8080: a porta na qual este container poderá responder publicamente.
Além disso, é importante mencionar que, ao executar a linha de comando apresentada pela Listagem 6, você terceirizou para o kubernetes as seguintes operações: 1) busca por um nó do cluster com capacidade suficiente para rodar o container solicitado; 2) agendamento da execução no nó recém descoberto; 3) monitoramento e atualização do container quando necessário.
Testando a aplicação
Nós ainda não estudamos o processo de expor os containers responsáveis por executar as aplicações de maneira pública. Faremos isso em um post em um futuro próximo. Isso porque, por padrão, quando um container é entregue para o ambiente do cluster, ele somente é visível de maneira interna ao mesmo. Dessa maneira, para que possamos testar nossa aplicação (não poderíamos fechar este post sem isso), iremos utilizar um mecanismo conhecido como proxy, que cria um túnel direto entre nosso terminal e a instância dentro do Pod. A sequência de comandos para isso segue.
- Crie o túnel digitando “
kubectl proxy
“ - Após isso, em uma nova instância de terminal, obtenha a instância do Pod onde o container já está rodando e coloque-a em uma variável de ambiente com o comando “
export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') echo Nome do Pod $POD_NAME
“ - Finalmente, teste a aplicação chamando a seguinte url: “
curl http://localhost:8001/api/v1/proxy/namespaces/default/pods/$POD_NAME/
“
Pronto. Container rodando nossa aplicação dentro do cluster Kubernetes. Bacana, não? No próximo post entenderemos o conceito de Pods e sua importância para fazer com que os containers possam enxergar uns aos outros dentro do cluster.
Até a próxima!
Pingback: Kubernetes – Pods – Fabrício Sanchez