Pular para o conteúdo
devops

Kubernetes para Backend: Conceitos Essenciais e Deploy na Prática

Guia prático de Kubernetes para desenvolvedores backend: Pods, Deployments, Services, Ingress, ConfigMaps, Secrets e deploy de aplicação Node.js.

Douglas M. Pereira4 min de leitura
kubernetesk8sdevopsdeploybackendcontainerscluster

Por que Kubernetes se tornou padrão para backend em produção

Kubernetes resolve o problema de gerenciar múltiplos containers em escala: scheduling (onde cada container roda), scaling (quantas instâncias), healing (reiniciar containers que falharam), rolling updates (atualizar sem downtime) e service discovery (como containers se encontram).

Para times de backend, Kubernetes virou pré-requisito na maioria das empresas de médio e grande porte. Este guia cobre os conceitos práticos que você precisa dominar.

Arquitetura de um cluster Kubernetes

┌─────────────────────────────────────────────────┐
│                  CONTROL PLANE                   │
│  API Server │ etcd │ Scheduler │ Controller Mgr  │
└─────────────────────────────────────────────────┘
          │              │               │
    ┌─────▼─────┐  ┌─────▼─────┐  ┌─────▼─────┐
    │  Node 1   │  │  Node 2   │  │  Node 3   │
    │           │  │           │  │           │
    │ kubelet   │  │ kubelet   │  │ kubelet   │
    │ kube-proxy│  │ kube-proxy│  │ kube-proxy│
    │           │  │           │  │           │
    │ Pod A     │  │ Pod B     │  │ Pod C     │
    │ Pod D     │  │ Pod E     │  │ Pod B     │
    └───────────┘  └───────────┘  └───────────┘

Você não gerencia Pods diretamente — você declara o estado desejado via Deployments, e o K8s garante que o cluster alcance e mantenha esse estado.

Os recursos essenciais

Deployment

Define quantas réplicas de um container devem rodar e como atualizar:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-backend
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-backend
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # sobe 1 novo antes de derrubar o antigo
      maxUnavailable: 0  # zero downtime update
  template:
    metadata:
      labels:
        app: api-backend
    spec:
      containers:
        - name: api
          image: minha-empresa/api:v1.2.3
          ports:
            - containerPort: 3000
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          env:
            - name: NODE_ENV
              value: "production"
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: url
          readinessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 15
            periodSeconds: 30

Service — Expondo pods internamente

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: api-backend-svc
  namespace: production
spec:
  selector:
    app: api-backend
  ports:
    - port: 80
      targetPort: 3000
  type: ClusterIP  # apenas interno ao cluster

Outros tipos: LoadBalancer (provisiona LB no cloud), NodePort (expõe em porta do node — para dev/teste).

Ingress — Expondo para a internet

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    nginx.ingress.kubernetes.io/rate-limit: "100"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  tls:
    - hosts: [api.minha-empresa.com]
      secretName: api-tls
  rules:
    - host: api.minha-empresa.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-backend-svc
                port:
                  number: 80

ConfigMaps e Secrets

# ConfigMap para configurações não sensíveis
apiVersion: v1
kind: ConfigMap
metadata:
  name: api-config
data:
  LOG_LEVEL: "info"
  CACHE_TTL: "300"
  ALLOWED_ORIGINS: "https://app.minha-empresa.com"

---
# Secret para dados sensíveis (base64)
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  url: cG9zdGdyZXNxbDovL3VzZXI6cGFzc0BkYjozNTQzL3Byb2Q=  # base64

Nunca commite Secrets no Git — use External Secrets Operator com AWS Secrets Manager, HashiCorp Vault ou similar.

HorizontalPodAutoscaler — Autoscaling

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-backend-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-backend
  minReplicas: 3
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

Comandos essenciais do dia-a-dia

# Ver status dos pods
kubectl get pods -n production
kubectl describe pod api-backend-6d8f7b59c9-xk2p7 -n production

# Logs
kubectl logs api-backend-6d8f7b59c9-xk2p7 -n production --tail=100 -f

# Executar comando no container
kubectl exec -it api-backend-6d8f7b59c9-xk2p7 -n production -- sh

# Deploy nova versão
kubectl set image deployment/api-backend api=minha-empresa/api:v1.2.4 -n production

# Rollback
kubectl rollout undo deployment/api-backend -n production

# Escalar manualmente
kubectl scale deployment/api-backend --replicas=5 -n production

# Verificar eventos
kubectl get events -n production --sort-by=.lastTimestamp

Pipeline de deploy CI/CD

# .github/workflows/deploy.yml (simplificado)
deploy:
  needs: test
  runs-on: ubuntu-latest
  steps:
    - name: Build e push imagem
      run: |
        docker build -t ghcr.io/empresa/api:${{ github.sha }} .
        docker push ghcr.io/empresa/api:${{ github.sha }}
    
    - name: Deploy no cluster
      run: |
        kubectl set image deployment/api-backend \
          api=ghcr.io/empresa/api:${{ github.sha }} \
          -n production
        kubectl rollout status deployment/api-backend -n production

Checklist antes de ir para produção

  • [ ] Readiness e Liveness probes configurados
  • [ ] Resources requests e limits definidos
  • [ ] HPA configurado para autoscaling
  • [ ] Secrets via External Secrets, não hardcoded
  • [ ] Namespace separado por ambiente (dev, staging, production)
  • [ ] Network policies para isolar serviços
  • [ ] Pod Disruption Budget para garantir mínimo de réplicas durante manutenção
  • [ ] Monitoramento com Prometheus + Grafana
  • [ ] Alertas no Alertmanager ou equivalente