sábado, 3 de outubro de 2026

Kubernetes do Zero - Parte 2: Preparando nosso laboratório e subindo nosso cluster


Fala pessoal, tudo bem?

Hoje vamos para a parte 2, da nossa sequência de postagens Kubernetes do Zero.

Vamos preparar nosso ambiente que servirá de laboratório para começarmos a colocar um pouco a mão na massa.

O ambiente

Para o laboratório eu vou utilizar a seguinte infraestrutura:

  • Meu notebook rodando Windows
  • Hypervisor – VirtualBox
  • 3 VMs com Ubuntu server instalado (versão 26.04)

o   1 VM será o control plane

§  2 vCPUs

§  3 GB memória (pela documentação do kubernetes.io , pode ser apenas 2GB)

§  20 GB de disco

o   2 VMs serão os workers

§  2 vCPUs

§  3 GB memória (pela documentação do kubernetes.io , pode ser apenas 2GB)

  • Placas em modo Bridge, assim as VMs receberão um IP da minha rede DHC.

Importante: Não precisamos instalar o Ubuntu nas 3 VMs. Podemos fazer a instalação de uma VM e depois usar o recurso de clone do VirtualBox. Assim poupamos um pouco de tempo de instalação. Apenas a parte da instalação e criação do cluster kubernetes que iremos fazer em cada uma devido a particularidade.

Preparação

Com as VMs criadas e com sistema operacional instalado, vamos agora fazer a preparação necessária antes de instalar o kubernetes e começar a subir nosso cluster.

Desativar o swap

O kubernetes exige que a memória swap seja desativada. Nas 3 máquinas vamos executar o seguinte comando:

sudo swapoff -a

É necessário com o vim, deletar a linha do swap no /etc/fstab e assim não fazer com que suba novamente caso o servidor reinicie.


Obs.: Isso deve ser feito nos workers também.

Carregar módulos do kernel

Para o kubernetes funcionar corretamente, precisamos carregar os módulos overlay e br_netfilter.

  • Overley – sistema de arquivos de sobreposição que permitirá unir múltiplos diretórios ou partições em uma única estrutura de arquivos virtual e transparente.
  • Br_netfilter – vai permitir que o tráfego de rede que passar por nossa interface de rede seja processado pelas regras do firewall Iptables.

No terminal, vamos executar o seguinte bloco de comandos:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

       Ativar o encaminhamento do IP (Sysctl)

Isso é necessário para que nosso Linux, seja capaz de funcionar como um roteador, repassando pacotes de dados de uma rede para outra.

No terminal, execute o seguinte bloco de comandos:

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl –system


Instalar o containerd

Como falamos na primeira parte, o kubernetes não executa nativamente, por assim dizer os containers, então para isso vamos instalar o containerd. Ele será o nosso container runtime.

Novamente no terminal, execute o seguinte bloco de comandos:

sudo apt update
sudo apt install containerd -y
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

·        O kubernetes trabalha com cgroups.

Cgroups – ou control groups (grupos de controle), é um recurso do kernel do Linux que permite limitar, contabilizar e isolar o uso de recursos de hadware, como CPU, memória, I/O de disco e rede para um determinado grupo de processos.

Para isso funcionar, vamos permitir que o containerd use cgroups. No arquivo de configuração /etc/containerd/config.toml, o parâmetro SystemdCgroup será alterado de false para true.

Novamente no terminal, execute o seguinte bloco de comandos:

sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/'
/etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd


Pronto!!!

O que era pré-requisito já foi feito.

Só lembrando ... reforçando ... Esses procedimentos precisam ser feitos em todos os nós do cluster. No nosso caso, no nó 1 que é o control plane e no nó 2 e 3 que são os workers.

Agora, vamos adicionar o repositório do kubernetes nos 3 nós e instalar os pacotes necessários.

Instalando os pacotes base e os pacotes do kubernetes

Para adicionar o repositório e o certificado, vamos executar o bloco de comandos abaixo:

sudo apt install apt-transport-https ca-certificates curl gnupg
conntrack
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.37/deb/Release.key |
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.37/deb/
/' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo chmod 644 /etc/apt/sources.list.d/kubernetes.list


Para instalar o kubeadm, kubelet e kubectl, o bloco de comandos abaixo:

sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

 

O apt-mark hold serve para que toda vez que alguém executar o update/upgrade no servidor, não corra o risco de atualizar automaticamente o kubernetes também. Isso evita muita dor de cabeça para nada quebrar durante uma atualização não planejada.

Finalmente, vamos subir nosso cluster =]

Subindo nosso primeiro cluster kubernetes

Agora, esse comando será executado apenas no control plane. Que no nosso laboratório será a VM kub-node1

sudo kubeadm init --pod-network-cidr=10.244.0.0/16
--apiserver-advertise-address=<O IP QUE VAI FALAR COM OS NODES>

Veja que podemos informar o endereçamento de rede que queremos usar na comunicação interna (rede escolhida 10.244.0.0/16), entre os pods e também informar o IP do nosso apiserve que nada mais é do que nosso control plane (192.168.0.62)

Então no nosso caso, o comando ficaria assim:

sudo kubeadm init --pod-network-cidr=10.244.0.0/16
--apiserver-advertise-address=192.168.0.62

Essa parte pode demorar um pouco, mediante a performance do ambiente e também da conectividade de rede/internet. Uma vez que começa toda a preparação de validar pré-requisitos e baixar tudo que é necessário para criar a estrutura do cluster.

Dando tudo certo, ao final teremos uma saída assim:


Veja que temos duas informações importantes aqui.

1° - Para podermos usar o cluster, com um usuário regular, temos alguns comandos a serem executados no control plane.

  • Criar o diretório para o arquivo de configuração do kubernetes no nosso diretório home
  • Copiar o arquivo de configuração do kubernetes para essa diretório criado no home do nosso usuário

·         Trocar o grupo e o dono para nosso usuário neste arquivo de configuração

2° - Não menos importante, veja que ele trás o comando que vamos precisar executar nos nodes workers para eles serem membros do nosso cluster efetivamente. Lembrando que para dar certo, precisamos executar com o sudo. Então ficaria assim, de acordo com nosso exemplo:

Sudo kubeadm join 192.168.0.62:6443 --token 48trth.zgu9q9l8t0tve24v
--discovery-token-ca-cert-hash sha256:0674a4a83bd943e86fc5a1784cd5d410c7571336bdb417dbb5b264bbb2876aa5

Dando tudo certo (que é o esperado), devemos receber um log semelhante a esse:


E por fim, para validar, no shell do servidor do control plane:

$ kubectl get nodes

 


Prontinho!!!

Nosso cluster está pronto, certo?

Só que não rs...

Veja que na coluna STATUS ainda temos tudo como NotReady. Mas por que será?

Ainda falta instalarmos nosso CNI para kubernetes e assim ele conseguir proporcionar a comunicação entre os pods. E aí sim, tudo estará funcional em nosso cluster para ele ficar pronto ... ou no caso, Ready.

Mas o que é CNI?

CNI (Container Network Interface) é uma especificação e conjunto de bibliotecas para as configurações de rede em containers. É através dele que temos a comunicação entre os pods e serviços facilitada.

Existem várias opções de CNI, como Calico, Flannel, Cilium e etc...

Eu gosto do Cilium, então ele será o CNI escolhido para o nosso ambiente.

Segue o site do projeto https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/ contendo todas informações e documentações.

De acordo com a página de documentação do Cilium, para instalarmos no nosso ambiente Linux que já contém um cluster, devemos rodar o seguinte bloco de comandos:

CILIUM_CLI_VERSION=$(curl -s
https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64;
fi
curl -L --fail --remote-name-all
https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}

 

Isso fará o download do binário do Cilium e o moverá para o diretório /usr/local/bin permitindo que você consiga executa-lo com seu usuário.

Após o download, vamos rodar a instalação com o comando:

$ cilium install

E vamos acompanhar o processo com o comando:

$ cilium status

Ou

$ cilium status -w

(isso fará com que o shell fique informando a cada atualização, sem que seja necessário executar o comando de status várias vezes)


É normal olharmos o status e aparecerem alguns erros durante o processo de subida. Isso ocorre devido ao cilium estar preparando o ambiente.

Se você tiver mais curiosidade e for impaciente como eu, o cilium faz o deploy dos seus serviços no namespace do kube-system. Para acompanhar podemos ver tudo com o comando:

$ kubectl get pods -n kube-system


Na coluna STATUS, iremos ver status de Init, ContainerCreating e dando tudo certo ... Running.

Assim que tudo estiver running, podemos validar novamente o status dos nodes:

$ kubectl get nodes


Agora sim. Nosso cluster está funcional no que diz respeito a todos os nodes estarem como Ready, com comunicação e visíveis para o control plane.

Fazendo um teste subindo nosso primeiro deployment

Para fazermos um teste bem rápido se está tudo OK, podemos rodar o seguinte comando:

$ kubectl create deployment nginx --image=nginx --replicas 4

Isso vai instruir a criação de um deploy do serviço do nginx, com 4 réplicas. Ou seja, 4 pods espalhados pelos workers.


O processo de subida dos pods pode demorar um pouco também, algo entre de 1 – 4 minutos. Mas vale levar em consideração que o kubernetes vai precisar baixar a imagem, fazer as criações e inicializações dos pods, então isso pode levar esse tempinho ou um pouco a mais.


Tudo como Running!

Que demais!!!

Mas será que o scheduler trabalhou direitinho e balanceou as réplicas pra gente? Já que ele é o responsável por este trabalho?

Vamos validar e para isso vamos executar o comando:

$ kubectl get pods -o wide


Veja que na coluna NODE, temos a informação de onde cada pod está rodando.

Como pedimos 4 réplicas, o scheduler colocou 2 réplicas no kub-node3 e 2 no kub-node2.

- Mas por que ele não usou o control plane, se ele é um node também?

Por via de regra, não teremos nossos pods em execução no control plane. É possível habilitar isso? Sim. Mas não é recomendado.

É até recomendado termos mais de um nó só para o control plane por questões de redundância e resiliência do nosso cluster.

- Eu consigo pegar mais informações dos nossos nodes?

Consegue sim. Basta executar o comando describe, da seguinte forma:

$ kubectl describe node kub-node2

Este é um exemplo do describe do node2


Aqui é apenas um trecho, pois a saída de informações é muito maior.

- Consigo fazer o describe também nos pods?

Sim!!!

$ kubectl describe pods nginx-69b9cdbbdd-bb8lj


Então, para reforçar:

  •          Usamos o get quando queremos pegar alguma informação
  •          Usamos o describe quando queremos pegar mais informações com detalhes

Finalizando a parte 2

Hoje aprendemos como preparar nosso ambiente para receber a instalação do kubernetes e como subir nosso primeiro cluster, contemplando a instalação do nosso CNI para permitir a comunicação entre os pods no ambiente e também como podemos validar se os nodes estão funcionando corretamente através de um deploy da aplicação do nginx.

Vamos ver o que nos espera na parte 3 ..., mas posso garantir pra vocês que essa jornada está apenas começando e ainda tem muita coisa legal para aprendermos.

Abs e até a próxima.

Nenhum comentário:

Postar um comentário