O Kubernetes se tornou o padrao da industria para orquestracao de conteineres, impulsionando desde pequenas startups ate as maiores plataformas nativas de nuvem do planeta. Se voce esta gerenciando conteineres com Docker ou Docker Compose e chegou ao ponto onde precisa de escalamento automatico, auto-recuperacao, atualizacoes progressivas e implantacoes em multiplos nos, o Kubernetes e o proximo passo. Este guia leva voce do zero a um cluster Kubernetes funcional usando kubeadm no Ubuntu Server, cobrindo a arquitetura, instalacao, primeira implantacao, exposicao de servicos e comandos de gerenciamento diario.
Pre-requisitos
Antes de comecar, certifique-se de ter:
- Duas ou mais maquinas com Ubuntu Server 22.04 ou 24.04 (fisicas ou virtuais)
- Cada maquina com pelo menos 2 GB de RAM e 2 CPUs
- Conectividade de rede completa entre todas as maquinas (rede privada recomendada)
- Hostname, endereco MAC e product_uuid unicos em cada no
- Acesso ao terminal com privilegios sudo em todos os nos
- Swap desabilitado em todos os nos
O Que e Kubernetes?
Kubernetes (frequentemente abreviado como k8s) e uma plataforma de orquestracao de conteineres de codigo aberto, originalmente projetada pelo Google e agora mantida pela Cloud Native Computing Foundation (CNCF). Ela automatiza a implantacao, o escalamento e o gerenciamento de aplicacoes em conteineres.
Em sua essencia, o Kubernetes resolve um problema fundamental: quando voce tem dezenas ou centenas de conteineres executando em multiplos servidores, voce precisa de um sistema que decida onde cada conteiner executa, reinicie conteineres que falham, os escale para cima ou para baixo com base na demanda, e gerencie a rede entre eles. O Kubernetes faz tudo isso de forma declarativa — voce descreve o estado desejado da sua aplicacao, e o Kubernetes trabalha continuamente para que o estado atual corresponda.
Conceitos-chave:
- Pod — a menor unidade implantavel, envolvendo um ou mais conteineres
- Service — um endpoint de rede estavel que roteia trafego para um conjunto de Pods
- Deployment — uma forma declarativa de gerenciar Pods com replicas e atualizacoes progressivas
- Namespace — uma particao logica para isolar recursos dentro de um cluster
- Node — uma maquina fisica ou virtual no cluster
Arquitetura do Kubernetes
Um cluster Kubernetes consiste em dois tipos de nos:
Plano de Controle (No Mestre)
O plano de controle gerencia o estado geral do cluster e toma decisoes de agendamento. Seus componentes incluem:
- kube-apiserver — a porta de entrada do cluster; toda comunicacao passa pelo servidor API
- etcd — um armazenamento distribuido de chave-valor que contem toda a configuracao e estado do cluster
- kube-scheduler — atribui Pods a nos com base em requisitos e restricoes de recursos
- kube-controller-manager — executa controladores que lidam com tarefas rotineiras como manter o numero correto de replicas de Pods
- cloud-controller-manager — integra-se com APIs de provedores de nuvem (opcional, para implantacoes em nuvem)
Nos Worker
Os nos worker executam seus conteineres de aplicacao. Cada worker executa:
- kubelet — o agente que se comunica com o plano de controle e gerencia Pods no no
- kube-proxy — lida com regras de rede para que os Pods possam se comunicar entre si e com trafego externo
- Runtime de conteineres — o software que realmente executa os conteineres (containerd e o padrao)
┌─────────────────────────────────────────┐
│ No do Plano de Controle │
│ ┌───────────┐ ┌──────────────────┐ │
│ │ API Server│ │ Controller Mgr │ │
│ └───────────┘ └──────────────────┘ │
│ ┌───────────┐ ┌──────────────────┐ │
│ │ etcd │ │ Scheduler │ │
│ └───────────┘ └──────────────────┘ │
└─────────────────────────────────────────┘
│ │
┌────┴────┐ ┌───┴─────┐
│ Worker 1│ │ Worker 2│
│ kubelet │ │ kubelet │
│ kube- │ │ kube- │
│ proxy │ │ proxy │
│ runtime │ │ runtime │
└─────────┘ └─────────┘
Preparacao de Todos os Nos
Os seguintes passos devem ser realizados em cada no do cluster (plano de controle e workers igualmente).
Desabilitar Swap
O Kubernetes requer que o swap esteja desabilitado. O kubelet nao iniciara se o swap estiver ativo:
# Desabilitar swap imediatamente
sudo swapoff -a
# Remover entradas de swap do fstab para persistir entre reinicializacoes
sudo sed -i '/ swap / s/^/#/' /etc/fstab
# Verificar que o swap esta desativado
free -h
Carregar Modulos do Kernel Necessarios
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
Configurar Parametros sysctl
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
# Aplicar sem reiniciar
sudo sysctl --system
Verifique que as configuracoes foram aplicadas:
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
Todos os tres valores devem retornar 1.
Instalacao do Runtime de Conteineres (containerd)
O Kubernetes precisa de um runtime de conteineres que implemente a Interface de Runtime de Conteineres (CRI). O containerd e o padrao da industria e a opcao recomendada:
# Instalar containerd
sudo apt update
sudo apt install -y containerd
# Gerar a configuracao padrao
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# Habilitar SystemdCgroup (necessario para kubeadm)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# Reiniciar e habilitar containerd
sudo systemctl restart containerd
sudo systemctl enable containerd
Verifique que o containerd esta em execucao:
sudo systemctl status containerd
A saida deve mostrar active (running).
Instalacao do kubeadm, kubelet e kubectl
Estas tres ferramentas sao a base de um cluster baseado em kubeadm:
- kubeadm — inicializa o cluster
- kubelet — executa em cada no e gerencia Pods
- kubectl — a ferramenta de linha de comando para interagir com o cluster
# Instalar pacotes necessarios
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg
# Adicionar a chave de assinatura do repositorio APT do Kubernetes
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# Adicionar o repositorio APT do Kubernetes
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
# Instalar os pacotes
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
# Prevenir atualizacoes automaticas (critico para a estabilidade do cluster)
sudo apt-mark hold kubelet kubeadm kubectl
Verifique a instalacao:
kubeadm version
kubectl version --client
Inicializacao do Plano de Controle
Execute o seguinte comando apenas no no do plano de controle:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
O flag --pod-network-cidr especifica o intervalo de IPs para os Pods. O valor 10.244.0.0/16 e o padrao para Flannel. Se voce planeja usar Calico, use 192.168.0.0/16 em vez disso.
Apos a inicializacao ser concluida, voce vera uma saida similar a:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:abc123...
Salve o comando kubeadm join — voce precisara dele para adicionar nos worker.
Configure o kubectl para seu usuario:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Verifique que o plano de controle esta em execucao:
kubectl get nodes
A saida mostrara o no do plano de controle com status NotReady — isso e esperado ate que voce instale um complemento de rede para Pods.
Instalacao de um Complemento de Rede para Pods
Os Pods precisam de um plugin de rede (CNI — Container Network Interface) para se comunicar entre si atraves dos nos. Sem ele, o cluster nao e funcional.
Opcao A: Instalar Flannel
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
Opcao B: Instalar Calico
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml
Aguarde ate que todos os Pods do sistema estejam prontos:
kubectl get pods -n kube-system
Apos um ou dois minutos, todos os Pods devem mostrar status Running. Agora verifique o status do no novamente:
kubectl get nodes
O no do plano de controle agora deve mostrar Ready.
Ingressar Nos Worker
Em cada no worker, execute o comando kubeadm join que voce salvou da inicializacao do plano de controle:
sudo kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:abc123...
Se voce perdeu o comando de ingresso, pode regenera-lo no plano de controle:
kubeadm token create --print-join-command
Apos o ingresso, verifique todos os nos a partir do plano de controle:
kubectl get nodes
Saida esperada:
NAME STATUS ROLES AGE VERSION
control-plane Ready control-plane 10m v1.31.0
worker-01 Ready <none> 2m v1.31.0
worker-02 Ready <none> 1m v1.31.0
Para rotular seus nos worker para melhor identificacao:
kubectl label node worker-01 node-role.kubernetes.io/worker=worker
kubectl label node worker-02 node-role.kubernetes.io/worker=worker
Implantando Sua Primeira Aplicacao
Agora que o cluster esta funcionando, vamos implantar um servidor web nginx simples.
Criar um Deployment
kubectl create deployment nginx --image=nginx:latest --replicas=3
Isso diz ao Kubernetes: “Quero 3 instancias de nginx executando o tempo todo.” O Kubernetes agendara Pods atraves dos seus nos worker.
Verifique o deployment:
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 30s
Visualize os Pods individuais:
kubectl get pods -o wide
O flag -o wide mostra em qual no cada Pod esta executando.
Usando um Manifesto YAML
Para cargas de trabalho em producao, voce deve definir recursos em arquivos YAML. Crie um arquivo chamado nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Aplique-o:
kubectl apply -f nginx-deployment.yaml
Exposicao de Servicos
Os Pods sao efemeros e recebem novos enderecos IP quando reiniciam. Os Services fornecem um endpoint estavel para alcancar sua aplicacao.
ClusterIP (Apenas Interno)
O tipo de Service padrao. Acessivel apenas de dentro do cluster:
kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=ClusterIP
kubectl get services
NodePort (Acesso Externo via IP do No)
Expoe o Service em uma porta estatica no IP de cada no:
kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=NodePort --name=nginx-nodeport
kubectl get services nginx-nodeport
Agora voce pode acessar a aplicacao em http://<ip-de-qualquer-no>:31234.
LoadBalancer (Ambientes em Nuvem)
Em ambientes de nuvem (AWS, GCP, Azure), o tipo LoadBalancer provisiona um balanceador de carga externo automaticamente:
kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=LoadBalancer --name=nginx-lb
Para clusters em bare-metal, voce pode usar MetalLB para fornecer funcionalidade de LoadBalancer.
Manifesto YAML de Service
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
type: NodePort
Escalamento e Atualizacoes Progressivas
Escalar Replicas
# Escalar para 5 replicas
kubectl scale deployment nginx-deployment --replicas=5
# Reduzir para 2 replicas
kubectl scale deployment nginx-deployment --replicas=2
# Verificar
kubectl get deployment nginx-deployment
Atualizacoes Progressivas
Atualize a imagem do conteiner sem tempo de inatividade:
# Atualizar a imagem
kubectl set image deployment/nginx-deployment nginx=nginx:1.27-alpine
# Acompanhar o progresso da implantacao
kubectl rollout status deployment/nginx-deployment
O Kubernetes substituira gradualmente os Pods antigos por novos, garantindo que a aplicacao permaneca disponivel durante toda a atualizacao.
Reversao
Se algo der errado:
# Ver historico de implantacoes
kubectl rollout history deployment/nginx-deployment
# Reverter para a versao anterior
kubectl rollout undo deployment/nginx-deployment
# Reverter para uma revisao especifica
kubectl rollout undo deployment/nginx-deployment --to-revision=2
Inspecao e Depuracao de Cargas de Trabalho
Visualizar Logs de Pods
# Logs de um Pod especifico
kubectl logs nginx-deployment-abc123
# Seguir logs em tempo real
kubectl logs -f nginx-deployment-abc123
# Logs de todos os Pods em um Deployment
kubectl logs -l app=nginx
Executar Comandos em um Pod
# Abrir um shell dentro de um Pod em execucao
kubectl exec -it nginx-deployment-abc123 -- /bin/bash
# Executar um unico comando
kubectl exec nginx-deployment-abc123 -- cat /etc/nginx/nginx.conf
Descrever Recursos
# Informacao detalhada sobre um Pod
kubectl describe pod nginx-deployment-abc123
# Informacao detalhada sobre um no
kubectl describe node worker-01
Solucao de Problemas
Pods Presos no Estado Pending
Isso tipicamente significa que o scheduler nao consegue encontrar um no com recursos suficientes:
kubectl describe pod <nome-do-pod>
Observe a secao Events no final. Causas comuns:
- CPU ou memoria insuficiente nos nos worker
- Taints de no impedindo o agendamento
- Regras de afinidade de Pod que nao podem ser satisfeitas
Pods em CrashLoopBackOff
O conteiner inicia mas encerra imediatamente:
# Verificar os logs
kubectl logs <nome-do-pod>
kubectl logs <nome-do-pod> --previous
# Verificar eventos
kubectl describe pod <nome-do-pod>
Causas comuns:
- Erro de aplicacao ou configuracao incorreta
- Variaveis de ambiente ou config maps ausentes
- Probes de readiness ou liveness falhando
Nos Mostram NotReady
# Verificar condicoes do no
kubectl describe node <nome-do-no>
# No no afetado, verificar logs do kubelet
sudo journalctl -u kubelet -f
Causas comuns:
- Plugin CNI nao instalado ou falhando
- kubelet nao consegue alcancar o servidor API
- Pressao de disco, pressao de memoria ou pressao de PID
Nao e Possivel Alcancar Servicos
# Verificar endpoints do Service
kubectl get endpoints <nome-do-servico>
# Testar conectividade de dentro do cluster
kubectl run debug --image=busybox --rm -it -- wget -qO- http://<nome-do-servico>
Regenerar Tokens de Ingresso
Se o token de ingresso expirou (tokens sao validos por 24 horas por padrao):
kubeadm token create --print-join-command
Referencia de Comandos kubectl
| Comando | Descricao |
|---|---|
kubectl get nodes | Listar todos os nos do cluster |
kubectl get pods | Listar Pods no namespace atual |
kubectl get pods -A | Listar Pods em todos os namespaces |
kubectl get services | Listar todos os Services |
kubectl get deployments | Listar todos os Deployments |
kubectl describe pod <nome> | Mostrar informacao detalhada do Pod |
kubectl logs <pod> | Visualizar logs do Pod |
kubectl exec -it <pod> -- /bin/bash | Abrir shell em um Pod |
kubectl apply -f <arquivo> | Aplicar um manifesto YAML |
kubectl delete -f <arquivo> | Excluir recursos de um manifesto YAML |
kubectl scale deployment <nome> --replicas=N | Escalar um Deployment |
kubectl rollout status deployment/<nome> | Verificar progresso da implantacao |
kubectl rollout undo deployment/<nome> | Reverter um Deployment |
kubectl top nodes | Mostrar uso de recursos dos nos |
kubectl top pods | Mostrar uso de recursos dos Pods |
kubectl config get-contexts | Listar contextos de cluster disponiveis |
kubectl cluster-info | Exibir informacao do endpoint do cluster |
Resumo
Agora voce tem um cluster Kubernetes funcional implantado com kubeadm, completo com um plano de controle, nos worker, um plugin de rede CNI e sua primeira aplicacao executando com servicos expostos. Esta e a mesma arquitetura fundamental utilizada em ambientes de producao Kubernetes em todo o mundo.
Pontos-chave:
- O Kubernetes orquestra conteineres atraves de multiplos nos com agendamento, escalamento e auto-recuperacao automatizados
- O plano de controle (API server, etcd, scheduler, controller manager) gerencia o estado do cluster enquanto os nos worker executam suas cargas de trabalho
- kubeadm e a ferramenta oficial para inicializar clusters de nivel de producao
- Deployments fornecem gerenciamento declarativo de Pods com atualizacoes progressivas e reversoes
- Services (ClusterIP, NodePort, LoadBalancer) dao aos Pods endpoints de rede estaveis
- Sempre use manifestos YAML para cargas de trabalho em producao para habilitar controle de versao e reprodutibilidade
Para fundamentos de conteinerizacao que complementam este guia, consulte nossos tutoriais sobre Como Instalar Docker no Ubuntu e Docker Compose: Guia Pratico para Administradores de Sistemas.