Pular para conteúdo

Aula 18 - Orquestração de Contêineres com Kubernetes (K8s) ☸️

Objetivo Pedagógico

Objetivo: Dominar a arquitetura interna do Kubernetes (Control Plane, Kubelet, etcd) e implementar deployments resilientes, serviços, ingress controllers, probes de saúde e auto-scaling horizontal de pods (HPA).


📑 1. Fundamentos Teóricos & Análise Técnica

O Kubernetes tornou-se o padrão da indústria para execução de cargas de trabalho em contêineres em ambientes de missão crítica.

A arquitetura do cluster é fundamentada na reconciliação contínua de estados (Control Loop): 1. Componentes do Control Plane: - kube-apiserver: O único componente que se comunica diretamente com a base de dados do cluster; expõe a API REST declarativa. - etcd: Armazenamento distribuído consistente e altamente disponível baseado no algoritmo Raft, guardando todo o estado do cluster. - kube-scheduler: Avalia restrições de afinidade, tolerations e recursos livres de CPU/memória para alocar novos Pods aos Worker Nodes. - kube-controller-manager: Executa loops de controle que convergem o estado real do cluster para o estado desejado declarado nos manifestos YAML. 2. Ciclo de Vida de Pods e Resiliência: - Liveness Probes: Detectam se a aplicação congelou em deadlock; caso falhe, o Kubelet reinicia o contêiner. - Readiness Probes: Detectam se a aplicação está apta a processar tráfego (ex: inicialização de banco concluída); caso falhe, o Pod é temporariamente removido dos endpoints do Service sem ser reiniciado. - Horizontal Pod Autoscaler (HPA): Ajusta o número de réplicas de Pods automaticamente com base no consumo real de CPU, memória ou métricas customizadas de tráfego.

📐 Arquitetura Conceitual & Diagrama de Fluxo

graph TD
    User["Dev / CI/CD (kubectl apply)"] --> API["kube-apiserver"]
    API --> etcd["etcd (Estado Distribuído Raft)"]
    API --> Scheduler["kube-scheduler (Alocação de Nós)"]
    API --> Controller["kube-controller-manager (Reconciliação)"]
    Scheduler --> WorkerNode["Worker Node"]
    WorkerNode --> Kubelet["Kubelet (Agente do Nó)"]
    Kubelet --> ContainerRuntime["Container Runtime (containerd)"]
    ContainerRuntime --> Pod1["Pod Réplica 1"]
    ContainerRuntime --> Pod2["Pod Réplica 2"]
    HPA["HPA: Monitora Métricas de CPU"] --> API
    style User fill:#e1f5fe,stroke:#01579b
    style API fill:#fff3e0,stroke:#e65100
    style etcd fill:#ffebee,stroke:#c62828
    style WorkerNode fill:#f3e5f5,stroke:#7b1fa2
    style Pod1 fill:#e8f5e9,stroke:#2e7d32
    style Pod2 fill:#e8f5e9,stroke:#2e7d32

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Declarative Reconciliation Loop: O Kubernetes atua ininterruptamente corrigindo desvios para que o estado real corresponda ao manifesto desejado. - Isolamento por Namespaces e Cgroups: Governança de limites rígidos de CPU e memória (Resource Quotas / Limits) evitando que um Pod monopolize o nó. - Zero-Downtime Rolling Updates: Substituição progressiva de instâncias antigas por novas garantindo disponibilidade total durante releases. - Cluster Networking e CNI (Container Network Interface): Atribuição de IP único e roteável para cada Pod dentro da malha de rede do cluster.


🛠️ 2. Implementação Prática em Sistemas Distribuídos e Orquestração com Kubernetes

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// deployment_resiliente.yml (Manifesto de Deployment K8s com Probes e Auto-Scaling)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-pedidos
  namespace: producao
  labels:
    app: api-pedidos
spec:
  replicas: 3
  revisionHistoryLimit: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Permite no máximo 1 Pod extra durante atualização
      maxUnavailable: 0  # Zero indisponibilidade tolerada no rollout
  selector:
    matchLabels:
      app: api-pedidos
  template:
    metadata:
      labels:
        app: api-pedidos
    spec:
      containers:
        - name: app
          image: ghcr.io/empresa/api-pedidos:v2.1.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

💡 Análise Passo a Passo do Código

  1. Estratégia RollingUpdate com maxUnavailable: 0: Garante que o tráfego de usuários nunca seja direcionado para servidores fora do ar.
  2. Declaração Estrita de Recursos: Permite que o scheduler dimensione nós adequadamente e evita OOM (Out-of-Memory) no cluster.
  3. Probes de Liveness e Readiness: Separa a saúde do processo em si da prontidão para receber pacotes de rede.

🎯 3. Próximos Passos & Sequência Didática