Dominando a Arquitetura de Kubernetes
Entenda como as partes do cluster conversam, por que cada componente existe e como isso impacta deployment, operação e confiabilidade no dia a dia.
1) O “cérebro” do cluster: controle central, API e etcd
Kubernetes é, essencialmente, um sistema de controle baseado em estado desejado. Você declara o que quer (manifests), e o cluster trabalha para que o estado real converja para o desejado. Para isso, existe um caminho claro: API Server → persistência (etcd) → control loops.
kube-apiserver
É a “porta de entrada”. Processa requisições REST/JSON, valida objetos, aplica RBAC e orquestra leitura/escrita do estado. Pense nele como a camada que garante que tudo que entra no cluster segue regras consistentes.
etcd
Armazena o estado do cluster de forma consistente (chave/valor). Controlar mudanças e manter histórico de revisões é crucial para que reconciliadores sejam determinísticos.
Control Plane (controladores)
Componentes como o controller-manager implementam loops de reconciliação. Ex.: Estado de Deployments → criação/atualização de ReplicaSets → Pods correspondentes.
Scheduler
Decide onde rodar Pods. Ele não “cria” Pods: ele seleciona um nó alvo conforme recursos, afinidades, taints/tolerations e políticas.
Quando você aplica um manifest, o kube-apiserver grava a intenção no etcd. Em seguida, os controladores reagem a mudanças e executam operações até o estado real bater com o desejado. Esse modelo é o que torna Kubernetes previsível em larga escala — desde que você entenda os limites do sistema.
2) Do manifesto ao Pod: reconciliadores, Deployment e a cadeia de objetos
Uma das partes mais importantes para “dominar” Kubernetes é saber como os objetos se encadeiam. O resultado final do seu manifest geralmente não é um único recurso; é uma malha de controladores produzindo outros recursos.
Pod (unidade de execução)
Onde está o contêiner. Pod define ambiente, volumes, rede e políticas aplicadas ao processo. Na prática, é o objeto que efetivamente roda — mas normalmente ele é gerado por controladores.
Deployment → ReplicaSet
Deployment controla estratégia (rolling update, replicas desejadas) e gera ReplicaSets. ReplicaSets garantem que um conjunto de Pods com determinada template exista.
Jobs/CronJobs
Focam em execução (tarefa) e finalização. Um Job não busca “ficar rodando”; ele busca concluir. CronJobs agendam a criação de Jobs.
Services/Ingress
Abstraem acesso. Services fornecem endereçamento estável para um conjunto de Pods. Ingress lida com roteamento HTTP/L7 (com um controlador específico).
Ao reconciliar, Kubernetes compara spec vs status. Quando existe divergência, ações são tomadas: criar recursos, atualizar campos, deletar objetos antigos e promover mudanças conforme a estratégia.
Isso evita o erro comum de tratar “sintomas” no Pod sem verificar por que o control loop não está convergindo. Kubernetes não “decide aleatoriamente”; ele tenta consistentemente atingir o estado declarado.
3) Rede no Kubernetes: Service, kube-proxy e conectividade
A rede é frequentemente o ponto onde a teoria vira dor. A base: Kubernetes cria um modelo em que Pods são efêmeros, mas o acesso precisa ser estável. É aí que o Service entra.
Service (endereço estável)
Um Service representa um conjunto de Pods via selectors. Ele entrega um IP/DNS fixos dentro do cluster e define portas e regras (ClusterIP/NodePort/LoadBalancer).
kube-proxy (ou dataplane equivalente)
Implementa o roteamento do tráfego do Service para Pods endpoints. Dependendo da plataforma, isso pode ser feito via iptables/ipvs ou mecanismos do provedor.
DNS interno
Geralmente baseado em CoreDNS. Permite resolver Service por nome (ex.: meu-svc.sobrenome-namespace.svc.cluster.local).
Pod-to-Pod
A conectividade leste-oeste depende do CNI (Container Network Interface). A arquitetura do cluster pressupõe que Pods consigam se comunicar conforme as regras do CNI.
Para “dominar” o assunto, foque nos três níveis:
- Identificação: Service abstrai seleção de Pods (labels).
- Roteamento: kube-proxy/CNI define como o tráfego chega nos endpoints.
- Resolução: DNS traduz nomes para endereços do Service.
Outro ponto crítico: readiness/liveness probes influenciam endpoints. Normalmente, somente Pods ready entram no conjunto efetivo de endpoints para o Service. Resultado: parece “conectividade” quando na verdade é estado do Pod.
4) Escalonamento e persistência: nós, recursos e storage
Escalonar é escolher o destino. Persistir é garantir que o “não efêmero” continue existindo apesar do ciclo de vida dos Pods. Para ambos, você precisa entender como Kubernetes decide e como os recursos são representados.
Scheduler: capacidades e restrições
Considera requests/limits, afinidade (node/pod), taints/tolerations, políticas de topologia e disponibilidade. Sem isso, você terá um cluster “ocupado” com Pods que não cabem ou que não deveriam estar ali.
Requests e Limits
Requests influenciam alocação e bin packing. Limits são o teto (ex.: CPU throttling/memória OOM). Um manifest consistente reduz falhas e melhora previsibilidade.
Volumes e PVC
Para persistência, você usa PersistentVolume e PersistentVolumeClaim. O PVC é a intenção; o PV é o recurso provisionado/administrado.
StorageClass
Define políticas para provisionamento dinâmico (tipo de disco, replicação, modo de acesso). Em ambientes reais, o “comportamento de performance e failover” vem daqui.
Uma arquitetura madura depende de decisões explícitas: como você quer que o escalonamento respeite zonas/regiões, como quer que recursos sejam distribuídos e qual estratégia de storage atende a consistência e recuperação exigidas.
E, ao diagnosticar, lembre: falhas de agendamento raramente são “misteriosas”. Procure por eventos (constraints, falta de recursos, taints) e pelo status dos controladores que tentam reconciliar.
Exemplo prático: Service + Deployment com readiness e requests/limits
Abaixo um manifest curto que mostra três decisões arquiteturais: Service estável para tráfego, readiness para endpoints corretos e requests/limits para escalonamento previsível.
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: minha-registry/minha-api:1.0.0
ports:
- containerPort: 8080
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
ports:
- name: http
port: 80
targetPort: 8080
type: ClusterIP
Como isso se conecta à arquitetura: o Service depende de labels; o conjunto de endpoints depende de readiness; o Scheduler depende de requests/limits para decidir onde os Pods irão ficar.
Pronto para aprofundar?
Agora que você tem a visão da arquitetura, vale seguir para posts que destrincham deploys, diagnóstico e boas práticas por componente.