Entenda Containers e Kubernetes e construa uma aplicação na prática
Neste artigo, você entenderá o que é container, conceitos sobre Kubernetes e como executar uma aplicação completa dentro de containers orquestrados pelo Kubernetes em um ambiente local utilizando Docker e Minikube.
O que são containers
Um container é uma unidade que empacota o código e todas as suas dependências para que o aplicativo seja executado e transportado de forma rápida e confiável de um ambiente de computação para outro.
Outro conceito importante é a imagem do container. Ela é um pacote de software leve, autônomo e executável que inclui tudo o que é necessário para executar um aplicativo: código, runtime, ferramentas do sistema, bibliotecas do sistema e configurações. A imagem se torna container durante o runtime.
Múltiplos containers podem rodar em um mesmo sistema operacional, compartilhando o mesmo Kernel. Eles são muito rápidos e leves, podendo comportar uma aplicação inteira e ocupar apenas 10MB de memória, além de permitir uma inicialização quase que instantânea.
Eles são a base para uma arquitetura baseada em micro serviços, chamada de Cloud-Native Application. Esta consiste em uma coleção de pequenos serviços independentes, que permite uma alta disponibilidade da aplicação.
Quanto mais containers são utilizados cooperativamente, mais difícil fica gerenciá-los e configurá-los para funcionarem juntos. É aí que o Kubernetes entra em ação.
Kubernetes
Kubernetes é um sistema open-source de orquestração de containers, criado para automatizar deploys, escalonamento e gerenciamento de aplicações. Ele é muito útil para prover escalabilidade, performance e otimização dos recursos utilizados para rodar as aplicações.
Este orquestrador é capaz de adicionar ou remover containers em um cluster de acordo com a demanda de requisições.
Imagine a seguinte situação: você possui um e-commerce e está chegando um grande feriado que costuma ter diversas promoções. É esperado que seu site tenha mais acessos do que o comum.
O Kubernetes consegue adicionar mais Pods para aumentar os recursos disponíveis para atender a nova demanda de requisições. Assim que ela diminuir, o orquestrador pode removê-los automaticamente para evitar consumo indesejado de recursos.
Ficou confuso com algum termo utilizado até aqui? Não se preocupe, pois agora vou explicar alguns termos relacionados para entendermos o funcionamento do orquestrador.
Pods
Pod é a unidade que o Kubernetes gerencia. É nada mais do que um grupo de containers que compartilham os mesmos recursos de memória e armazenamento. Isso permite que diferentes containers Linux possam ser tratados como uma única aplicação, com um único IP.
Deployments
Um deployment verifica a saúde do seu Pod e reinicia o contêiner do Pod caso este seja finalizado. O uso dele é recomendado para gerenciar a criação e escalonamento dos Pods.
Services
Um service pode nomear grupos de Pods, permitindo agir como Load Balancers para direcionar o tráfego para executar os containers.
Nodes
Um node do Kubernetes é a máquina (física ou virtual) que executa o trabalho determinado, além de gerenciar e rodar os pods. Eles agrupam pods que funcionam juntos, assim como os pods agrupam containers.
Cluster
Um cluster é um conjunto de todos os itens tratados até aqui reunidos como uma única unidade.
Como rodar uma API e um banco de dados PostgreSQL no Kubernetes
A seguir, você verá um tutorial de como rodar uma simples API que armazena posts e os retorna.
Instalações Necessárias
Git Bash: terminal de comandos;
Docker Desktop: gerenciador de containers;
kubectl: ferramenta de linha de comandos do Kubernetes;
Minikube: ferramenta para executar o Kubernetes localmente.
Este tutorial foi escrito com base em uma máquina Windows, então sua instalação será um pouco diferente caso o ambiente escolhido seja outro.
1- Git Bash: siga as instruções do instalador.
2- Docker Desktop: siga as instruções do instalador.
3- kubectl: acesse o link disponibilizado acima e baixe a última versão:

3.1- Crie uma pasta chamada kube em algum lugar de fácil acesso e coloque o arquivo .exe baixado na pasta criada. Neste exemplo, foi criado no seguinte caminho: "E:\kube\kubectl.exe".
4- Minikube: acesse o link disponibilizado acima, baixe a última versão minikube-windows-amd64.exe e altere o nome do arquivo para minikube.exe:
4.1- Acesse a mesma pasta chamada kube, criada no passo 3.1, coloque o arquivo baixado e renomeado nesta pasta. Neste exemplo, ficou salvo no seguinte caminho: "E:\kube\minikube.exe".
5- Para concluir a instalação dos itens 3 e 4 siga os seguintes passos:
5.1- Pesquise por Editar as variáveis de ambiente do sistema no windows:

5.2- Clique em Variáveis de Ambiente...:

5.3- Selecione a variável Path e clique em Editar...:

5.4- Clique em Novo e digite o caminho da sua pasta criada, neste exemplo é E:\kube\:

Pronto, você tem o ambiente configurado para começar.
Crie a aplicação desejada
Neste tutorial, foi criada uma simples aplicação Node.js e um banco de dados PostgreSQL. É uma API de um hipotético site de publicações que possui duas chamadas:
GET /posts
: busca todos os posts armazenados no banco;
POST /post
: não recebe nenhum parâmetro e cria uma post genérico com textos gerados a partir da biblioteca faker.js.
A publicação gerada pela API é parecida com:
{
"id": 1,
"title": "quasi et totam",
"body": "Asperiores eum minima voluptas porro voluptas eaque ducimus aut et. Eos sint omnis aliquid assumenda. Aut fugiat ipsa fugiat provident. Qui ex nobis ut aut aspernatur laborum voluptatem incidunt quae. Totam eius maiores sit perspiciatis laborum aliquid.\n \rEaque similique officiis ut aut non aut qui omnis. Aut sed nisi voluptas et quo officiis accusamus nobis. Ducimus est non possimus libero. Voluptatibus consequuntur pariatur. Vel sint iusto placeat dicta. Libero nihil autem omnis dicta at.\n \rTemporibus non consequatur nam sit. Quia eveniet aut veritatis voluptates nesciunt facere sit aut. Nostrum non eos ratione qui quasi. Est enim repellat unde repudiandae.",
"createdAt": "2021-08-02T20:44:14.100Z",
"updatedAt": "2021-08-02T20:44:14.100Z"
}
Você pode baixar o projeto através do repositório do github.
Configure o Kubernetes
No projeto disponibilizado no github, há a aplicação em si e os arquivos de configuração do Docker. A configuração presente deve criar 2 containers: o nodejs-artigo com a aplicação Node.js e o postgres-artigo com o banco de dados PostgreSQL. O Dockerfile extenderá a última versão alpine da imagem oficial do node e executará a build da aplicação e sua configuração inicial.
A configuração do Kubernetes pode ser feita somente a partir de linhas de comando com o kubectl ou com o auxílio de arquivos .yaml, que permitem criar esta configuração apenas uma vez e transportar/executar em outras máquinas de forma fácil e rápida.
Neste tutorial, a configuração será feita com linhas de comando kubectl auxiliados por arquivos .yaml. Eles serão armazenados numa pasta chamada k8s dentro da pasta raiz do projeto (no exemplo, esta pasta se chama kubernetes-example).
Comece criando o arquivo kubernetes-example/k8s/services/app-service.yaml de configuração do Service que executará o Pod com o container da aplicação Node.js:
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: nodejs-artigo
ports:
- port: 4000
targetPort: 4000
Crie o arquivo kubernetes-example/k8s/services/postgres-service.yaml de configuração do Service responsável pelo banco de dados:
apiVersion: v1
kind: Service
metadata:
name: postgres-service
spec:
selector:
app: postgres-artigo
ports:
- port: 5432
targetPort: 5432
Crie o arquivo kubernetes-example/k8s/deployments/postgres.yaml de configuração de Deployment do banco de dados. É aqui que são configuradas as variáveis de ambiente com as credenciais do PostgreSQL:
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-artigo
labels:
app: postgres-artigo
spec:
selector:
matchLabels:
app: postgres-artigo
replicas: 1
template:
metadata:
labels:
app: postgres-artigo
spec:
containers:
- name: postgres
image: postgres
env:
- name: POSTGRES_PASSWORD
value: postgres
- name: POSTGRES_DB
value: postgres-artigo
- name: POSTGRES_USER
value: postgres-artigo
Crie o arquivo kubernetes-example/k8s/deployments/deployment.yaml de configuração de Deployment da aplicação. Aqui são definidas as variáveis de ambiente da aplicação Node.js, como o URL do banco de dados que será consultado na API. Além disso, há a configuração de dependência do deployment do postgres:
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-example
spec:
replicas: 1
selector:
matchLabels:
app: kubernetes-example
template:
metadata:
labels:
app: kubernetes-example
spec:
initContainers:
- name: init-wait
image: alpine
command:
[
'sh',
'-c',
'for i in $(seq 1 300); do nc -zvw1 postgres-service 5432 && exit 0 || sleep 3; done; exit 1',
]
containers:
- name: kubernetes-example
image: kubernetes-example:v1
env:
- name: 'POSTGRES_HOST'
value: 'postgres-service'
- name: 'POSTGRES_PORT'
value: '5432'
- name: DATABASE_URL
value: postgresql://postgres-artigo:postgres@postgres-service:5432/postgres-artigo?schema=public
Pronto! Os arquivos de configuração do Kubernetes estão prontos. Agora é hora de colocá-los em ação no ambiente de testes que será configurado no Minikube.
Usando o Minikube para executar o Kubernetes localmente
Neste tutorial, a imagem Docker será "buildada" e disponibilizada localmente, excluindo a necessidade do Docker Hub.
Antes de tudo, lembre-se de iniciar o Docker Desktop na sua máquina, pois ele será a engine do Minikube.
1- Comece abrindo o Git Bash na pasta do projeto. Para isto, basta clicar com o botão direito na pasta e em Git Bash Here:

2- Execute o comando minikube start
para iniciar o Minikube;
3- Configure o kubectl para utilizar o contexto do Minikube com o comando kubectl config use-context minikube
;
4- No momento, caso rode o comando docker images
, serão retornados as imagens Docker que estão rodando na sua máquina, mas você precisa configurar para que o Minikube utilize o Docker interno dele. O comando eval $(minikube docker-env)
permite isso. Rodando docker images
novamente, é possível ver as imagens que o Minikube utiliza:

5- "Builde" a imagem do Docker que está configurada na pasta do projeto com o comando docker build -t kubernetes-example:v1 .
. O que está acontecendo neste comando é o seguinte: está sendo criada uma imagem com o nome kubernetes-example com a tag v1 a partir das configurações encontradas no caminho "." (pasta onde o bash está sendo executado). Executando docker images
novamente, é possível visualizar a imagem criada:

6- Execute o comando kubectl apply -f k8s/services
para criar os Services. Isso aplicará as configurações definidas nos arquivos de configurações criados na pasta kubernetes-example/k8s/services. Com o comando kubectl get services
, é possível visualizar todos os Services:

7- Execute o comando kubectl apply -f k8s/deployments
para criar os Deployments. Isso aplicará as configurações definidas nos arquivos de configurações criados na pasta kubernetes-example/k8s/deployments. Com o comando kubectl get deployments
, é possível visualizar todos os Deployments:

Quando ambos estiverem prontos e disponíveis, é possível visualizar os Pods criados e gerenciados pelos Deployments. Basta executar o comando kubectl get pods
:

8- Sua aplicação já está rodando, agora para testá-la você pode disponibilizar a porta 4000 (porta onde a API foi configurada para ser executada) com o comando kubectl port-forward <nome-do-pod> 4000:4000.
Você precisa substituir <nome-do-pod> pelo nome do Pod gerado pelo deployment e retornado no passo anterior.
Neste exemplo, o Pod criado é o kubernetes-example-65b4775cf6-7cr5s. Se estiver tudo certo, ao fazer uma requisição GET ao recurso /posts a API retornará um array vazio, pois ainda não há nada cadastrado no bando de dados:

9- Faça uma requisição POST ao recurso /post sem enviar nenhum body ou qualquer parâmetro. Isso criará um artigo genérico no banco de dados:

10- Ao fazer uma requisição GET ao recurso /posts a API novamente, ela retornará um array com o post criado anteriormente:

Prontinho! Agora você possui uma API completa com um banco de dados PostgreSQL rodando em containers orquestrados pelo Kubernetes.
Neste tutorial, tudo está sendo executado pelo Minikube para termos um ambiente de testes local, excluindo a necessidade de configurar as máquinas e os Clusters.
Não utilize o Minikube para subir alguma aplicação em produção, ele foi desenvolvido para executar testes e aprender a utilizar o Kubernetes.
Este artigo foi escrito por Henry Kimura e publicado originalmente em Prensa.li.