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:

  1. CPU ou memoria insuficiente nos nos worker
  2. Taints de no impedindo o agendamento
  3. 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:

  1. Erro de aplicacao ou configuracao incorreta
  2. Variaveis de ambiente ou config maps ausentes
  3. 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:

  1. Plugin CNI nao instalado ou falhando
  2. kubelet nao consegue alcancar o servidor API
  3. 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

ComandoDescricao
kubectl get nodesListar todos os nos do cluster
kubectl get podsListar Pods no namespace atual
kubectl get pods -AListar Pods em todos os namespaces
kubectl get servicesListar todos os Services
kubectl get deploymentsListar todos os Deployments
kubectl describe pod <nome>Mostrar informacao detalhada do Pod
kubectl logs <pod>Visualizar logs do Pod
kubectl exec -it <pod> -- /bin/bashAbrir 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=NEscalar um Deployment
kubectl rollout status deployment/<nome>Verificar progresso da implantacao
kubectl rollout undo deployment/<nome>Reverter um Deployment
kubectl top nodesMostrar uso de recursos dos nos
kubectl top podsMostrar uso de recursos dos Pods
kubectl config get-contextsListar contextos de cluster disponiveis
kubectl cluster-infoExibir 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.