K3s no Ubuntu Server: Kubernetes leve, passo a passo
Um cluster Kubernetes completo — API server, scheduler, controller-manager, kubelet, containerd e datastore — cabe em um único binário. É o que entrega o K3s: segundo os requisitos oficiais do projeto (linha de release v1.36.x), um nó server roda com apenas 2 vCPU e 2 GB de RAM, e um nó agente com 1 vCPU e 512 MB. Dá pra rodar num mini PC de homelab, numa VM pequena de VPS ou numa Raspberry Pi, mantendo a API padrão do Kubernetes — o que você aprende aqui funciona igual num cluster gigante. Este guia instala um cluster K3s single-node no Ubuntu Server, publica um serviço real e explica o porquê de cada passo.
Por que K3s em vez de kubeadm
O Kubernetes “completo” via kubeadm exige montar separadamente o datastore (etcd), o runtime de containers, o CNI e o ingress controller — e cada peça tem seu próprio ciclo de upgrade. O K3s empacota tudo isso num único binário mantido pela Rancher/SUSE:
- Datastore embutido: usa SQLite por padrão num cluster single-node, e dispensa operar um etcd separado. Para alta disponibilidade, dá pra trocar para etcd embutido ou um banco externo (MySQL, PostgreSQL) sem reinstalar o cluster.
- Rede e ingress inclusos: vem com Flannel (CNI), Traefik (ingress controller) e um load balancer de serviço leve (ServiceLB) já configurados — não precisa escolher e instalar cada um à parte.
- containerd embutido: não depende de instalar Docker ou outro runtime separadamente.
A troca é justamente essa simplicidade: para produção em grande escala com equipe dedicada de plataforma, kubeadm dá mais controle peça por peça. Para infraestrutura pequena e média — filial, homelab, edge, ambiente de teste — o K3s entrega a mesma API com muito menos operação.
Pré-requisitos
- Ubuntu Server 22.04 ou 24.04, atualizado.
- Mínimo 2 vCPU e 2 GB de RAM na máquina que vai ser o server (1 vCPU e 512 MB bastam para cada agente, se for adicionar depois).
- Acesso root ou sudo.
- Porta 6443/TCP liberada para quem for acessar a API, e 8472/UDP entre os nós se você adicionar mais de um (é a porta que o Flannel usa em modo VXLAN).
É recomendado desabilitar o swap antes de instalar. O Kubernetes assume que tem controle total sobre a memória alocada aos pods; com swap ativo, o kubelet pode subestimar o uso real de memória e deixar de despejar pods no momento certo, o que trava o dimensionamento de recursos do cluster.
sudo swapoff -a sudo sed -i '/ swap / s/^/#/' /etc/fstab
Passo a passo
1. Instalar o K3s no nó server
O script oficial detecta a distribuição, baixa o binário e sobe o K3s como serviço systemd, já configurado para reiniciar sozinho se o processo cair ou o servidor reiniciar:
curl -sfL https://get.k3s.io | sh -
Junto do binário, o script também instala kubectl, crictl, ctr e os scripts k3s-killall.sh e k3s-uninstall.sh — este último é o jeito limpo de remover o cluster inteiro se o teste não der certo.
2. Conferir se o cluster subiu
sudo k3s kubectl get nodes
O nó deve aparecer com status Ready. Se preferir usar o kubectl sem precisar de sudo toda hora, copie o kubeconfig gerado para o seu usuário:
mkdir -p ~/.kube sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config sudo chown $(id -u):$(id -g) ~/.kube/config kubectl get nodes
O K3s escreve esse kubeconfig automaticamente em /etc/rancher/k3s/k3s.yaml — é o mesmo formato que qualquer outra distribuição Kubernetes usa, então ferramentas como Lens, k9s ou Helm funcionam sem adaptação.
3. Testar com uma carga real
Suba um deployment de exemplo e exponha via NodePort para confirmar que a rede do cluster está roteando tráfego de verdade, não só respondendo à API:
kubectl create deployment teste-nginx --image=nginx kubectl expose deployment teste-nginx --port=80 --type=NodePort kubectl get svc teste-nginx
O comando get svc mostra a porta alta (na faixa 30000–32767) que o Kubernetes reservou. Acesse http://IP-DO-SERVIDOR:PORTA e a página padrão do Nginx deve responder — isso confirma que o Flannel, o kube-proxy e o ServiceLB estão funcionando juntos.
4. Liberar o firewall, se o ufw estiver ativo
sudo ufw allow 6443/tcp sudo ufw allow from 10.42.0.0/16 sudo ufw allow from 10.43.0.0/16
As faixas 10.42.0.0/16 e 10.43.0.0/16 são, por padrão, as redes internas de pods e de serviços do K3s. Sem liberar essas rotas no firewall do host, os pods sobem mas não conseguem se comunicar entre si nem alcançar os Services.
5. Adicionar um nó agente (opcional)
Para dar mais capacidade ao cluster, pegue o token do server e rode o mesmo script no segundo servidor, apontando para o primeiro:
sudo cat /var/lib/rancher/k3s/server/node-token
curl -sfL https://get.k3s.io | K3S_URL=https://IP-DO-SERVER:6443 K3S_TOKEN=TOKEN_COPIADO sh -
O agente entra automaticamente no cluster e passa a receber pods. Cada máquina precisa de hostname único — se estiver clonando VMs de uma mesma imagem, ajuste o hostname antes ou use a variável K3S_NODE_NAME para forçar um nome diferente por nó.
Perguntas frequentes
K3s serve para produção ou só para teste?
Serve para produção. É o mesmo Kubernetes certificado pela CNCF por baixo, só que empacotado de forma mais enxuta. A ressalva é escala: para clusters muito grandes, o guia oficial recomenda trocar o datastore SQLite por etcd embutido ou um banco externo antes de crescer além de um punhado de nós.
Preciso instalar Docker antes?
Não. O K3s já traz containerd embutido como runtime de containers, então não há dependência de Docker instalado na máquina.
Como eu removo o K3s se o teste não der certo?
Rode o script que o próprio instalador deixou pronto: /usr/local/bin/k3s-uninstall.sh no server, ou /usr/local/bin/k3s-agent-uninstall.sh em cada agente. Ele para o serviço, remove os binários e limpa os dados do cluster.
Dá para rodar em ARM, tipo Raspberry Pi?
Sim, o K3s suporta x86_64, armhf e arm64/aarch64 oficialmente. Em Raspberry Pi é recomendado usar um SSD externo em vez do cartão SD, porque o datastore do cluster grava com frequência e cartões SD não aguentam bem esse padrão de escrita.
Qual a diferença entre K3s e o Kubernetes “normal”?
A API e o comportamento dos objetos (Deployment, Service, Pod etc.) são idênticos — é Kubernetes certificado, não um clone. A diferença está na empacotagem: K3s troca componentes plugáveis por versões mais leves (SQLite no lugar de etcd para um nó só, containerd embutido, Flannel e Traefik já inclusos) para reduzir a pegada de memória e a complexidade operacional.
Conclusão
Com o server no ar e um agente conectado, você tem um cluster Kubernetes funcional rodando em menos hardware do que a maioria dos ambientes de homelab já tem sobrando. O próximo passo natural é colocar as cargas de trabalho reais atrás do Traefik com um Ingress, e — se o cluster crescer — migrar o datastore de SQLite para etcd embutido antes de passar de uma dezena de nós.