Pular para o conteúdo
NyverraNyverra
Artigos
⌘K
InícioArtigosSite institucional
🇧🇷

Nyverra

Canal editorial

Artigos sobre tecnologia, operações e parceiros — infraestrutura, monitoramento e ambientes críticos.

Explorar

  • Início
  • Artigos
  • Categorias
  • Tags
  • Autores
  • Sobre
  • Contato
  • RSS
  • Site institucional

© 2026 Nyverra. Todos os direitos reservados.

blog.nyverra.com

  1. Início
  2. Kubernetes
  3. Curso Kubernetes 02 — Montando o laboratório: 6 VMs e um cluster que cabe no bolso
Kubernetes
#Homelab#Kubeadm#Proxmox#Curso Kubernetes#K8S#Kubernetes

Curso Kubernetes 02 — Montando o laboratório: 6 VMs e um cluster que cabe no bolso

Wedson LopesWedson Lopes
30 de outubro de 20265 min de leitura

A maioria dos tutoriais de Kubernetes começa com um cluster gerenciado na nuvem. Aqui é diferente: vamos montar o cluster em VMs, na sua rede, para você ver o encanamento. Isso dói um pouco — e é exatamente por isso que ensina.

O laboratório deste curso tem 3 masters e 3 workers. No capítulo 05 vamos deixar o control plane em HA; por enquanto, um master já é suficiente para aprender.

Selo do curso: testado em Ubuntu Server 24.04, Kubernetes 1.35 e containerd 2.x. IPs abaixo são fictícios (192.168.56.x).

Topologia

Nome IP vCPU RAM Disco Papel
k8s-master-01 192.168.56.10 2 4 GB 50 GB control plane
k8s-master-02 192.168.56.11 2 4 GB 50 GB control plane (HA, cap. 05)
k8s-master-03 192.168.56.12 2 4 GB 50 GB control plane (HA, cap. 05)
k8s-worker-01 192.168.56.21 4 16 GB 100 GB worker
k8s-worker-02 192.168.56.22 4 16 GB 100 GB worker
k8s-worker-03 192.168.56.23 4 16 GB 100 GB worker

Por que 16 GB nos workers? Porque vamos rodar banco, mensageria, object storage e observabilidade. Em laboratório, 8 GB funciona até você começar a testar carga e failover — e aí o OOM killer aparece. Aprendi isso da forma difícil.

Se você não tem 6 VMs, comece com 1 master + 1 worker. O importante é o processo.

1. Preparando as VMs

Crie as VMs no Proxmox (ou VirtualBox/UTM) com Ubuntu Server 24.04. Durante a instalação:

  • Usuário com sudo.
  • OpenSSH habilitado.
  • Nada de swap (vamos desabilitar de qualquer forma).

Depois, em todas as VMs:

sudo hostnamectl set-hostname k8s-master-01   # ajuste por VM
sudo timedatectl set-timezone America/Sao_Paulo
sudo apt update && sudo apt upgrade -y

Configure /etc/hosts em todas (ou use DNS interno):

192.168.56.10 k8s-master-01
192.168.56.11 k8s-master-02
192.168.56.12 k8s-master-03
192.168.56.21 k8s-worker-01
192.168.56.22 k8s-worker-02
192.168.56.23 k8s-worker-03

Teste a resolução e o relógio. Relógio errado quebra TLS e o join:

getent hosts k8s-master-01
timedatectl

2. Pré-requisitos do nó

Em todas as VMs:

# swap off (agora e no boot)
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

# módulos de kernel
sudo tee /etc/modules-load.d/k8s.conf >/dev/null <<'EOF'
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

# sysctl de rede
sudo tee /etc/sysctl.d/k8s.conf >/dev/null <<'EOF'
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sudo sysctl --system

Verifique:

free -h          # swap deve ser 0
lsmod | grep -E 'overlay|br_netfilter'
sysctl net.ipv4.ip_forward

Não pule o swap. O kubelet se recusa a subir com swap ativo por padrão. É o erro nº 1 de quem monta o primeiro cluster.

3. containerd

O Kubernetes não fala com o Docker diretamente; ele fala com um runtime via CRI. Vamos usar o containerd.

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

Edite /etc/containerd/config.toml e garanta:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
  SystemdCgroup = true

Reinicie:

sudo systemctl restart containerd
sudo systemctl enable containerd
systemctl status containerd --no-pager

4. kubeadm, kubelet e kubectl

sudo apt install -y apt-transport-https ca-certificates curl gpg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key \
  | sudo gpg --dearmor -o /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.35/deb/ /' \
  | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Confira:

kubeadm version
kubelet --version
kubectl version --client

5. kubeadm init

No master-01:

sudo kubeadm init \
  --pod-network-cidr=10.244.0.0/16 \
  --apiserver-advertise-address=192.168.56.10 \
  --control-plane-endpoint=192.168.56.10

Ao final, ele imprime o comando de join. Guarde-o. Configure o kubeconfig do seu usuário:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

O master aparecerá NotReady até instalarmos a CNI. É normal.

6. CNI (flannel)

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
kubectl -n kube-flannel get pods -o wide
kubectl get nodes

Quando o flannel estiver Running em todos os nós, o master fica Ready.

Aviso: flannel resolve a rede, mas não aplica NetworkPolicy. Se você precisa de segmentação, o capítulo 06 explica Cilium/Calico. Descobri isso da pior forma: a política existia, mas não fazia efeito.

7. Join dos workers

No master, gere um novo token se precisar:

kubeadm token create --print-join-command

Rode o comando nos workers (como root):

sudo kubeadm join 192.168.56.10:6443 --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

Valide:

kubectl get nodes -o wide
kubectl get pods -A

Todos os nós devem estar Ready.

8. O primeiro “não subiu”

Alguns erros que você vai encontrar:

Sintoma Causa provável Como resolver
kubelet não sobe swap ativo swapoff -a + /etc/fstab
Node NotReady CNI ausente ou pod flannel com erro kubectl -n kube-flannel logs <pod>
join falha por TLS relógio dessincronizado timedatectl, NTP
connection refused no 6443 firewall ou apiserver fora ss -lntp, crictl ps
flannel sem subnet.env após reboot /run limpo e flannel subiu antes reinicie o DaemonSet/aguarde; verifique logs do flannel
pods em Pending nó com taint ou poucos recursos kubectl describe node

9. Limpeza (quando precisar refazer)

sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d /var/lib/cni /var/lib/kubelet
sudo systemctl restart containerd kubelet

Faça isso em todos os nós e comece de novo. Laboratório é para isso.

Checklist

  • [ ] 6 VMs com hostname, IP fixo e /etc/hosts corretos.
  • [ ] Swap desativado e módulos carregados em todos os nós.
  • [ ] containerd com SystemdCgroup = true.
  • [ ] kubeadm/kubelet/kubectl na mesma versão.
  • [ ] kubeadm init concluído e kubeconfig copiado.
  • [ ] CNI aplicada e master Ready.
  • [ ] Workers com join concluído e Ready.
  • [ ] kubectl get pods -A sem pods quebrados.

Glossário

  • kubeadm: ferramenta de bootstrap do cluster.
  • CRI: interface entre kubelet e runtime.
  • CNI: plugin de rede dos pods.
  • taint/toleration: regra de afinidade/repulsão entre pods e nós.
  • join: comando que adiciona um nó ao cluster.

Próximo

Com o cluster no ar, vamos criar o primeiro Deployment, expor um Service e aprender a diagnosticar quando o pod não sobe.

Próximo: Curso Kubernetes 03 — O primeiro pod e o primeiro deploy

Compartilhar

Continuar a ler

Leia também

  • Kubernetes de Verdade — do zero ao cluster em produção
    Kubernetes

    Kubernetes de Verdade — do zero ao cluster em produção

    Uma trilha prática para entender, montar e operar um cluster Kubernetes — do primeiro pod ao failover do Postgres.

    30 de outubro de 20264 min de leitura
  • Curso Kubernetes 28 — DR e capstone: provar que o cluster volta
    Kubernetes

    Curso Kubernetes 28 — DR e capstone: provar que o cluster volta

    RPO, RTO e drills reais: cenários de desastre, runbook, restore medido e o capstone que fecha o curso com um cluster que se recupera.

    30 de outubro de 20265 min de leitura
  • Curso Kubernetes 27 — SLO/SLI, on-call e postmortem blameless
    Kubernetes

    Curso Kubernetes 27 — SLO/SLI, on-call e postmortem blameless

    O que prometer, como medir e o que fazer quando o erro estoura: SLI, SLO, error budget, alertas que acordam alguém e postmortem sem caça às bruxas.

    30 de outubro de 20264 min de leitura

Comentários

Ainda sem comentários

Seja o primeiro a compartilhar sua opinião sobre este artigo.

Deixe um comentário

Newsletter

Receba novos artigos

Inscreva-se para receber publicações do blog Nyverra no seu e-mail. Enviaremos um link de confirmação.

​