Kubernetes para iniciantes – 3: Deployments e Services na prática

Se você chegou até aqui, já sabe o que é um POD, já subiu um cluster local com Kind e já deu os primeiros passos com Kubernetes. Agora é hora de entender duas peças fundamentais que você vai usar toda hora na vida real: Deployments e Services.

Sem eles, o Kubernetes é só um lugar onde os seus containers morrem em paz.

O que é um Deployment?

Pensa assim: você contratou um gerente para cuidar de um time de atendimento. Você fala para ele:

Quero que sempre tenha 3 pessoas disponíveis

Se alguém falta, ele contrata outra. Se alguém sai, ele repõe. Você não precisa ficar olhando, ele cuida disso pra você.

Esse gerente é o Deployment!!!!

Você declara o estado que quer, tipo, “quero 3 réplicas do meu container rodando”, e o Kubernetes garante que aquilo vai acontecer e vai se manter assim. Se um POD morrer, ele sobe outro. Se você atualizar a versão da sua aplicação, ele troca um de cada vez sem derrubar tudo.

É o conceito de estado declarativo: você fala o que quer, não o que fazer.

Criando o primeiro Deployment

Chega de teoria. Vamos criar um Deployment simples com a imagem do `nginx`:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: meu-nginx # nome do deployment
spec:
  replicas: 3 # quantos Pods quero rodando
  selector:
    matchLabels:
      app: nginx # qual label esse Deployment gerencia
  template:
    metadata:
      labels:
        app: nginx # label aplicada em cada Pod criado
    spec:
      containers:
       - name: nginx
         image: nginx:1.25 # imagem e versão
         ports:
           - containerPort: 80 # porta que o container expõe

Aplica no cluster:

kubectl apply -f deployment.yaml

Agora verifica se subiu:

kubectl get deployments

kubectl get pods

Você deve ver 3 Pods com status `Running`. Agora faz um teste: deleta um deles.

kubectl delete pod <nome-do-pod>

Espera alguns segundos e roda `kubectl get pods` de novo. Um novo Pod já apareceu no lugar. O Deployment fez o trabalho dele.

Atualizando sem parar tudo: Rolling Update

Sabe quando você vai reformar um prédio mas não pode fechar o negócio? Você reforma um andar de cada vez, sem interromper o funcionamento.

O Kubernetes faz exatamente isso. Quando você muda a versão da imagem, ele não mata todos os PODs de uma vez, ele vai trocando gradualmente. Isso se chama Rolling Update e já vem habilitado por padrão.

Para atualizar a imagem do seu Deployment:

kubectl set image deployment/meu-nginx nginx=nginx:1.26

Acompanha o progresso:

kubectl rollout status deployment/meu-nginx

E se a nova versão vier com problema? Sem estresse, dá pra desfazer:

kubectl rollout undo deployment/meu-nginx

Simples assim. O Kubernetes guarda o histórico das atualizações e te deixa voltar quando precisar.

O problema que os Services resolvem

Agora imagina que você tem 3 PODs rodando a sua aplicação. Cada POD tem um endereço IP próprio. Ótimo, né?

O problema: PODs morrem e nascem o tempo todo. Quando um Pod morre e sobe outro, o IP muda. Se outra parte do sistema estava usando aquele IP direto, tudo quebra.

É como se toda vez que você fosse ligar para um colega de trabalho, ele tivesse trocado de número. Muito ruim.

O Service resolve isso!!!

Ele é basicamente um número de telefone fixo que sempre redireciona para alguém disponível, não importa quem mudou de lugar ou saiu. Você chama o Service e ele sabe para qual Pod encaminhar a requisição.

Os três tipos de Service que você precisa conhecer

1. ClusterIP (padrão)

Só acessível dentro do cluster. Ideal para comunicação entre serviços internos.

# service-clusterip.yaml
apiVersion: v1
  kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx # aponta para os Pods com essa label
  ports:
   - port: 80 # porta do Service
     targetPort: 80 # porta do container

2. NodePort

Expõe o serviço em uma porta do próprio nó (máquina). Útil para testes locais.

# service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080 # porta acessível de fora do cluster (30000–32767)

Com isso você consegue acessar no browser: `http://localhost:30080`

3. LoadBalancer

Para uso em nuvem (AWS, GCP, Azure). Cria um IP público automaticamente e distribui o tráfego entre os Pods.

# service-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80

No dia a dia em cloud, esse é o que você mais vai usar para expor aplicações para o mundo.

Conectando tudo: Deployment + Service

O segredo está no `selector`. O Service usa o campo `selector` para saber quais Pods ele deve gerenciar — e ele bate com as `labels` definidas no Deployment.

Olha o fluxo:

Deployment cria Pods com label: app: nginx
↓
Service busca Pods com selector: app: nginx
↓
Requisição chega no Service → ele escolhe um Pod disponível e encaminha

Para testar localmente sem precisar de NodePort, você pode usar port-forward:

kubectl port-forward service/nginx-service 8080:80

Agora abre o browser em `http://localhost:8080` e você vai ver o nginx respondendo.

Recapitulando

  • Deployment: garante que o número certo de Pods está sempre rodando e gerencia atualizações com segurança
  • Service: endereço estável que sempre sabe achar os Pods certos, mesmo quando eles mudam
  • O selector é a cola entre os dois — sempre confere se as labels batem

Com esses dois recursos, você já consegue rodar aplicações de verdade no Kubernetes, atualizar sem downtime e expor para outros serviços ou para o mundo.

O que vem a seguir?

Na próxima parte da série, vamos falar sobre ConfigMaps e Secrets, porque deixar configuração e senhas dentro da imagem do container é uma péssima ideia, e o Kubernetes tem uma solução elegante pra isso.

Até lá, experimenta mudar o número de réplicas, matar PODs, fazer um rollback. A melhor forma de aprender Kubernetes é quebrando e consertando! 😀