🧠FFVAcademy
☸️

Kubernetes Completo: do Pod ao cluster de produção

28 min de leitura·+120 XP
Pré-requisitos (0/1)0%

Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.

Kubernetes é um orquestrador de containers. Tradução: ele pega centenas de containers, distribui em dezenas de servidores, garante que o número certo esteja rodando, reinicia os que quebram, escala por carga, faz deploy sem downtime, roteia tráfego e cuida de estado persistente. É gigante porque os problemas que ele resolve são gigantes. Este guia cobre arquitetura do control plane, todos os objetos que você realmente usa (Pod, Deployment, Service, Ingress, ConfigMap, Secret, PVC, Namespace), RBAC, autoscaling, Helm, observabilidade e os comandos de kubectl que resolvem 95% dos casos. Pré-requisito: entender Docker (se não entende, volte um módulo).

Por que K8s existe: o problema que ele resolve

Com Docker você sobe um container numa máquina. Mas produção real tem perguntas chatas:

Como ter N réplicas?Se um container cai às 3h da manhã, quem sobe outro?
Como distribuir em vários hosts?Meu app não cabe num único server — onde cada container roda?
Como fazer deploy sem downtime?Rolling update, canary, blue/green — precisa de alguém coordenando.
Como escalar com a carga?Sexta 18h bate 10x o tráfego — alguém precisa subir réplicas sozinho.
Como rotear tráfego?Um endpoint público pra 50 services internos, com TLS e load balancing.
Como cuidar de estado?Banco, cache, fila — precisa de volume persistente que sobrevive reschedule de Pod.
Como falar entre services?DNS, descoberta, retries — infra de service mesh.
Como gerenciar config e segredo?Rotação, separação por ambiente, sem vazar em repo.

K8s responde todas essas. O custo é complexidade e uma curva de aprendizado real. Para apps pequenos um único container num servidor basta; K8s começa a valer a pena quando você tem múltiplos serviços, SLA de uptime, ou precisa de escalabilidade elástica.

A arquitetura: Control Plane + Data Plane

🗺️ Anatomia de um cluster
Control Plane (cérebro)
🛡️
kube-apiserver
única porta de entrada — REST/gRPC
💾
etcd
estado do cluster (Raft)
🎯
scheduler
decide qual node roda qual Pod
🔁
controller-manager
loops de reconciliação
watch / exec
Data Plane (nodes)
🤖
kubelet
agente em cada node
🔀
kube-proxy
regras iptables/ipvs para Services
📦
container runtime
containerd → runc
🧩
Pods
as cargas de trabalho
kube-apiserverA única porta de entrada. Tudo (kubectl, controllers, kubelet) fala com ele. REST + gRPC.
etcdKey-value distribuído (Raft) onde vive o estado desejado do cluster. Se perde etcd, perde o cluster.
schedulerObserva Pods sem node atribuído e decide em qual node rodar (afinidade, recursos, taints).
controller-managerLoop de reconciliação: "estado atual ≠ estado desejado? ajustar". Dezenas de controllers (Deployment, Node, Endpoint...).
cloud-controllerIntegra com a cloud (load balancer, volume, node). Separado para clouds customizarem.
kubeletAgente em cada node. Recebe do apiserver quais Pods rodar e fala com o runtime (containerd).
kube-proxyPrograma regras iptables/ipvs que implementam Services. É o "roteamento" interno do cluster.
container runtimecontainerd (default moderno) ou CRI-O. Quem realmente cria os containers via runc.
💡
Mental model: K8s é um loop de reconciliação. Você declara o desejado (YAML com “quero 3 réplicas da v2”), salva no etcd via apiserver, e controllers trabalham em loop infinito pra fazer a realidade bater com o desejo. Não é um scheduler de jobs — é um sistema de “convergência contínua”.

Pod — a unidade atômica

Pod é o menor objeto que o K8s agenda. Um Pod é um ou mais containersque compartilham rede (mesmo IP, localhost entre eles), volumes e ciclo de vida. Na prática, 95% dos Pods têm 1 container. Multi-container Pod é o padrão “sidecar” (ex.: app + proxy Envoy, app + log shipper).

yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:1.27-alpine
      ports:
        - containerPort: 80
      resources:
        requests: { cpu: 100m, memory: 64Mi }
        limits:   { cpu: 500m, memory: 256Mi }
CoisaEntre containers DO mesmo PodEntre Pods
Redelocalhost, mesma IPIP próprio, via Service
VolumePodem montar o mesmoNão compartilham (use PVC)
Ciclo de vidaPod cai, todos caem juntosIndependente
⚠️
Não crie Pod direto em prod.Se o node morre, o Pod é perdido e ninguém o recria — Pod não tem “controller”. Use Deployment (stateless), StatefulSet (stateful), DaemonSet (um por node), Job/CronJob (batch). Pod nu é só pra debug: kubectl run --rm -it debug --image=alpine -- sh.

Deployment + ReplicaSet — como apps stateless rodam

📝Deploymentvocê escreve
YAML declarativo com a imagem, réplicas, estratégia de update. A única coisa que a equipe edita.
gera e controla
🧬ReplicaSetshistórico + atual
v1 (antiga) permanece como histórico pra rollback; v2 (atual) é a versão alvo sendo aplicada.
rolling update
📦Podsrodam de fato
v1 são derrubados gradualmente enquanto v2 sobem. Tráfego segue via Service sem interrupção.
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  selector:
    matchLabels: { app: api }
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1            # 1 a mais pode existir durante o rollout
      maxUnavailable: 0      # nenhum pode estar indisponível
  template:
    metadata:
      labels: { app: api }
    spec:
      containers:
        - name: api
          image: ghcr.io/me/api:1.2.0
          ports: [{ containerPort: 3000 }]
          env:
            - name: DATABASE_URL
              valueFrom: { secretKeyRef: { name: api-secrets, key: db-url } }
          readinessProbe:
            httpGet: { path: /health, port: 3000 }
            initialDelaySeconds: 3
            periodSeconds: 5
          livenessProbe:
            httpGet: { path: /health, port: 3000 }
            initialDelaySeconds: 15
            periodSeconds: 20
          resources:
            requests: { cpu: 100m, memory: 128Mi }
            limits:   { cpu: 500m, memory: 512Mi }
replicasQuantos Pods o ReplicaSet mantém.
selector + labelsComo o Deployment sabe quais Pods são dele. Nunca mude labels de um Deployment vivo.
strategyRollingUpdate (default) ou Recreate (derruba tudo, sobe v2). Recreate = downtime.
readinessProbeQuando o Pod está pronto para receber tráfego. Falhou = removido do Service (mas não morto).
livenessProbeQuando o Pod está vivo. Falhou = kubelet reinicia o container.
resources.requestsScheduler usa pra decidir em qual node cabe.
resources.limitsKernel mata o Pod (OOMKill) se passar de memória; throttle em CPU.
Comandos de rollout essenciais: kubectl rollout status deploy/api, kubectl rollout history deploy/api, kubectl rollout undo deploy/api.

StatefulSet, DaemonSet, Job — quando usar cada um

ControllerPropósitoExemplos
DeploymentApps stateless com N réplicas intercambiáveisAPI HTTP, worker de fila, frontend
StatefulSetPods com identidade estável (pod-0, pod-1) e PVC por PodPostgres, Kafka, Elasticsearch, Redis cluster
DaemonSetUm Pod por node (ou subset via nodeSelector)Log collector (fluentd), node exporter, CNI
JobRoda até completar N vezes com sucessoMigração de schema, export de dados
CronJobJob em schedule cronBackup noturno, cleanup de lixo, relatório diário
💡
StatefulSet vs Deployment: StatefulSet garante nomes estáveis (db-0, db-1) e volume persistente por Pod (volumeClaimTemplates). Se db-0 morre e volta, reengancha no mesmo PVC. Essencial pra bancos e sistemas distribuídos que precisam saber quem é o líder/follower.

Services — 4 tipos, 4 propósitos

Service é o objeto que dá endpoint estável pra um conjunto de Pods. Pods morrem e nascem com IPs diferentes; Service tem um IP virtual (ClusterIP) e um nome DNS (api.default.svc.cluster.local) que persistem.

TipoEscopoQuando usar
ClusterIPSó dentro do clusterDefault. Comunicação entre services.
NodePortExpõe em uma porta 30000-32767 de cada nodeDev, on-prem sem LoadBalancer, debug
LoadBalancerPede LB externo à cloud (ELB, GLB, Azure LB)Produção cloud — expõe um service ao mundo
ExternalNameDNS CNAME pra fora do clusterApontar pra RDS externo, API parceira
Headless (clusterIP: None)Sem IP virtual, só DNS de PodsStatefulSet — cada Pod precisa ser endereçado
yaml
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  type: ClusterIP
  selector: { app: api }
  ports:
    - port: 80           # a porta do Service
      targetPort: 3000   # a porta do container nos Pods
⚠️
LoadBalancer por service fica caro. Cada Service type=LoadBalancer na AWS cria um ELB = US$ ~16/mês + tráfego. Em vez disso, o padrão é: 1 LoadBalancer → Ingress Controller → muitos Services ClusterIP. Um LB só, roteamento L7.

Ingress — o roteamento HTTP do cluster

Service opera em L4 (TCP/UDP). Pra roteamento HTTP/S por host ou path com TLS, você quer Ingress. Mas Ingress por si só é só uma regra — precisa de um Ingress Controller(pod que efetivamente faz o roteamento). Os mais comuns: nginx-ingress, Traefik, HAProxy, AWS ALB Controller.

🌐Internetcliente
Browser ou API externa resolve api.meusite.com via DNS.
DNS → IP do LB
⚖️LoadBalancer1 por cluster
NLB/ALB/ELB provisionado pelo cloud provider quando você cria Service type=LoadBalancer.
TCP/HTTPS
🚪Ingress Controllerpod nginx/traefik
host=api.meusite.com /v1/* → api-v1 · /v2/* → api-v2 · host=app.meusite.com /* → frontend
roteia por host/path
🧭Service ClusterIPselector
IP virtual estável que faz balanceamento interno entre os Pods que bate o label selector.
encaminha
📦Podsalvo final
Containers da aplicação recebem o tráfego. Escalam horizontalmente via HPA.
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts: [api.meusite.com]
      secretName: api-tls
  rules:
    - host: api.meusite.com
      http:
        paths:
          - path: /v1
            pathType: Prefix
            backend:
              service: { name: api-v1, port: { number: 80 } }
          - path: /v2
            pathType: Prefix
            backend:
              service: { name: api-v2, port: { number: 80 } }

ConfigMap e Secret — separar código de config

ObjetoConteúdoComo injetar
ConfigMapConfig não-sensível (feature flags, URLs, tunings)env var, volume de arquivo, argv
SecretSegredo (senha de db, API key, TLS cert)env var ou volume (preferível volume)
yaml
apiVersion: v1
kind: ConfigMap
metadata: { name: app-config }
data:
  LOG_LEVEL: info
  FEATURE_NEW_DASHBOARD: "true"
---
apiVersion: v1
kind: Secret
metadata: { name: app-secrets }
type: Opaque
stringData:
  db-url: postgres://user:pass@db:5432/app
  jwt-key: "super-secret-change-me"
---
# no Pod spec
spec:
  containers:
    - name: app
      image: me/app:1.0
      envFrom:
        - configMapRef: { name: app-config }
      env:
        - name: DB_URL
          valueFrom: { secretKeyRef: { name: app-secrets, key: db-url } }
🚨
Secret NÃO é criptografado por default no etcd — só codificado em base64. Habilite encryption-at-rest no kube-apiserver (KMS provider) em produção. Para segredos críticos, use External Secrets Operator + Vault / AWS Secrets Manager / Azure Key Vault — o Secret no cluster fica sincronizado do cofre real, nunca em plaintext no git.
⚠️
Mudança de ConfigMap não reinicia Pod automaticamente. Se você usa envFrom, o valor é congelado no start. Soluções: (1) mount como volume (atualiza sozinho) e o app faz re-load; (2) adicionar annotation com hash do ConfigMap no PodTemplate (Reloader é um operator que faz isso automaticamente).

Storage — PV, PVC, StorageClass

Volumes em K8s são uma abstração em 3 camadas:

⚙️StorageClassadmin cria 1x
Define como provisionar: driver (EBS gp3, NFS, Ceph…), parâmetros, reclaim policy.
referenciado por
📮PersistentVolumeClaimapp pede
"Quero 20Gi ReadWriteOnce do storageClass=gp3." É a demanda escrita pela aplicação.
bound em
💾PersistentVolumerecurso real
Volume provisionado dinamicamente (ex: EBS vol-abc123) que atende o PVC.
mount em
📦Podconsome
Monta o PV em /var/lib/postgresql/data — filesystem persistente entre restarts.
yaml
# PVC dinâmico: o StorageClass provisiona o PV sozinho
apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: pg-data }
spec:
  accessModes: [ReadWriteOnce]
  storageClassName: gp3
  resources:
    requests: { storage: 20Gi }
---
apiVersion: v1
kind: Pod
metadata: { name: postgres }
spec:
  containers:
    - name: pg
      image: postgres:16-alpine
      volumeMounts:
        - { name: data, mountPath: /var/lib/postgresql/data }
  volumes:
    - name: data
      persistentVolumeClaim: { claimName: pg-data }
accessModeSignificadoBackends típicos
ReadWriteOnce (RWO)Montado R/W em um node por vezEBS, disk volumes
ReadOnlyMany (ROX)Vários Pods, só leituraConfig/assets em NFS
ReadWriteMany (RWX)Vários Pods, todos R/WEFS, CephFS, GlusterFS
ReadWriteOncePod (RWOP)Um único Pod R/W (mais forte que RWO)PV para Pods únicos

Namespaces — multi-tenancy dentro do cluster

Namespace é um agrupamento lógico. Recursos com o mesmo nome podem coexistir em namespaces diferentes. Default quando você não define: default. Do sistema: kube-system (control plane), kube-public.

bash
kubectl create namespace staging
kubectl apply -f deployment.yaml -n staging
kubectl get pods -n staging
kubectl config set-context --current --namespace=staging   # fica no ns
💡
Namespace não é barreira de segurança forte. Serve pra organizar, aplicar quota (ResourceQuota), e anexar políticas (RBAC, NetworkPolicy). Pra isolamento forte (tenants hostis), use clusters separados.

RBAC — controle de acesso

4 objetos:

RoleColeção de permissões (verbos: get, list, watch, create, update, delete) sobre recursos em UM namespace.
ClusterRoleIgual, mas cluster-wide. Nodes, PVs, CRDs vivem aqui.
RoleBindingLiga uma Role a um Subject (User, Group, ServiceAccount) num namespace.
ClusterRoleBindingLiga ClusterRole a Subject cluster-wide.
yaml
# Permite que o SA "deployer" faça qualquer coisa com Deployments em prod
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployer
  namespace: prod
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deployer-bind
  namespace: prod
subjects:
  - kind: ServiceAccount
    name: ci-bot
    namespace: ci
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: deployer

Autoscaling — HPA, VPA, Cluster Autoscaler

AutoscalerO que escalaBaseado em
HorizontalPodAutoscaler (HPA)Número de réplicas do DeploymentCPU, memória, custom metrics (Prometheus)
VerticalPodAutoscaler (VPA)Requests/limits do PodHistórico de uso — recomenda ou ajusta
Cluster AutoscalerNúmero de nodesPods pendentes que não cabem nos nodes atuais
KEDARéplicas, baseado em eventos (fila SQS, Kafka lag)Event-driven (0 → N)
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: api-hpa }
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  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 }
⚠️
HPA precisa de metrics-server instalado no cluster — não vem por default em clusters DIY. Em EKS/GKE/AKS geralmente já vem. Sem metrics-server, HPA reporta <unknown> nos targets e não escala nada.

Helm — package manager do K8s

Aplicar 15 YAMLs à mão, com valores diferentes por ambiente, vira pesadelo. Helm empacota isso em um Chart: templates Go com valores parametrizáveis + um values.yaml por ambiente.

bash
# instalar um chart público (Postgres oficial do Bitnami)
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-pg bitnami/postgresql \
  --namespace data \
  --set auth.postgresPassword=secret \
  --set primary.persistence.size=20Gi

# seu próprio chart
helm create minhaapp          # scaffolds templates/
helm install meuapp ./minhaapp -f values.prod.yaml
helm upgrade meuapp ./minhaapp -f values.prod.yaml
helm rollback meuapp 3        # volta pra revisão 3
helm uninstall meuapp
💡
Alternativas ao Helm: Kustomize (embutido no kubectl — overlays em YAML puro, sem templating); Argo CD (GitOps pull-based). Em produção profissional, o padrão hoje é Helm + Argo CD: Helm empacota, Argo CD reconcilia do git pro cluster.

Observabilidade — o que você precisa pra dormir à noite

Logskubectl logs pra debug. Em prod: Loki / Elasticsearch / CloudWatch via DaemonSet (fluent-bit, vector).
MétricasPrometheus (pull) + Grafana. kube-state-metrics expõe estado do cluster; node-exporter expõe nodes.
TracesOpenTelemetry + Jaeger/Tempo. Essencial em microservices.
Eventoskubectl get events --sort-by=.lastTimestamp. Onde você descobre por que o Pod não subiu.
Probesliveness + readiness + startup (para apps de boot lento). Tunados errado = causa #1 de flakiness.

kubectl — o CLI que resolve 95% do dia-a-dia

bash
# Contexto e namespace
kubectl config get-contexts
kubectl config use-context prod
kubectl config set-context --current --namespace=default

# Inspeção
kubectl get pods                      # lista pods no ns atual
kubectl get pods -A                   # todos os namespaces
kubectl get pods -o wide              # + node, IP
kubectl get pods -w                   # watch (live)
kubectl describe pod api-xyz          # tudo sobre o pod (eventos!)
kubectl get events --sort-by=.lastTimestamp

# Logs e exec
kubectl logs -f deploy/api            # segue logs do Deployment
kubectl logs -p pod/api-xyz           # logs do container que morreu (--previous)
kubectl exec -it pod/api-xyz -- sh    # shell no container

# Debug de rede
kubectl run -it --rm curl --image=curlimages/curl -- sh
kubectl port-forward svc/api 8080:80  # acessa service local em http://localhost:8080

# Mudanças rápidas
kubectl scale deploy/api --replicas=5
kubectl set image deploy/api api=me/api:1.3.0
kubectl rollout status deploy/api
kubectl rollout undo deploy/api

# Apply, diff, explain
kubectl apply -f manifests/
kubectl diff -f manifests/            # o que vai mudar
kubectl explain deployment.spec.strategy  # docs do schema direto do cluster

# Copy e debug effêmero
kubectl cp api-xyz:/app/log.txt ./log.txt
kubectl debug pod/api-xyz --image=nicolaka/netshoot  # sidecar de debug

Troubleshooting — o checklist quando algo quebra

Pod Pendingkubectl describe — falta CPU/mem nos nodes, ou PVC não bindou, ou taint/toleration.
Pod CrashLoopBackOffkubectl logs -p — logs do crash anterior. Quase sempre app morre no start (config errada, DB inacessível).
Pod ImagePullBackOffTag errada, registry privado sem imagePullSecret, ou rate limit do Docker Hub.
OOMKilledkubectl describe mostra Last State: OOMKilled. Aumente memory.limits ou corrija memory leak.
Service não roteiaLabels do Service não batem com labels dos Pods. kubectl get endpoints svc/xyz — se está vazio, é isso.
Ingress 502/503Service ok mas Pod não responde na porta esperada. kubectl port-forward direto no Pod pra confirmar.
Rollout travadoreadinessProbe falhando nos Pods novos. kubectl describe nos Pods da nova versão.
🚨
Regra número 1 do K8s: sempre rode kubectl describe antes de kubectl logs. A seção Events no final do describe mostra o que aconteceu, em ordem, com timestamp. 90% dos problemas aparecem ali.

Cenários de decisão

📋 Equipe de 6 devs, 3 microservices, SLA baixo. Precisa de K8s?

Não — comece com docker-compose + 1 VM (ou ECS Fargate)

K8s introduz complexidade enorme (RBAC, ingress, helm, observabilidade). Pra 3 apps stateless com tráfego moderado, compose + systemd resolve. Mude pra K8s quando tiver 10+ services e time de ops.

Alt: K3s (K8s leve)se a equipe já sabe K8s e quer uniformidade.

Alt: ECS/Fargateorquestração gerenciada AWS sem a curva do K8s.

📋 20 microservices, 3 ambientes, vários times. Expor cada um?

Ingress Controller + cert-manager + 1 LoadBalancer cloud

Um LB só cloud (caro) → Ingress → 20 services ClusterIP. cert-manager renova TLS Let's Encrypt automaticamente. Roteamento L7 por host/path. Custo previsível, governança centralizada.

Alt: LoadBalancer por service20 × US$16/mês + complexidade de DNS. Evite.

📋 Preciso rodar Postgres HA dentro do K8s — é boa ideia?

Depende — use um Operator (CloudNativePG, Zalando) ou RDS

StatefulSet cru não faz HA de Postgres — backup, failover, PITR são não-triviais. Operators encapsulam esse know-how. RDS/Aurora terceirizam o problema inteiro. Só 'Postgres artesanal' se o time entende muito bem.

Alt: RDS/Cloud SQLmenos controle, muito menos dor operacional.

Perguntas típicas

Posso começar a aprender K8s sem ter um cluster pago?

Sim. kind (Kubernetes-in-Docker) ou minikube sobem um cluster inteiro na sua máquina em 30 segundos. Depois, clusters gratuitos na cloud com free tier (EKS tem custo da control plane; GKE Autopilot e AKS têm camadas gratuitas). Pra treino puro, kind é o melhor.

Qual a diferença entre EKS, GKE e AKS?

Todos entregam Kubernetes gerenciado — a control plane fica sob responsabilidade do cloud provider. Diferenças práticas: GKE é considerado o mais maduro (Google inventou K8s); EKS tem integração profunda com IAM/ELB/VPC da AWS; AKS integra com Azure AD/ARM. Para SAA-C03 e trabalho AWS, foque em EKS.

Preciso escrever YAML todo dia?

Você lê YAML todo dia. Escreve cada vez menos — helm chart, kustomize overlays, ou ferramentas como cdk8s (YAML via TypeScript/Python) geram. YAML continua sendo o formato de cabo final, mas quase nunca você digita do zero depois dos primeiros meses.

K8s faz CI/CD?

Não por si só. K8s é o destino. Ferramentas rodam em cima: Argo CD (GitOps pull-based — manifestos no git, Argo sincroniza), Flux, ou pipelines tradicionais (GitHub Actions, GitLab, Jenkins) que rodam kubectl apply ou helm upgrade.

O que é um Operator?

Um controller custom que entende de um domínio específico (Postgres, Kafka, Elasticsearch). Você cria um CRD (Custom Resource Definition) — ex.: kind: PostgresCluster— e o operator watcheia esses CRDs e faz a mágica (provisionar réplicas, failover, backup). É como “transformar know-how humano em controller”.
Take-aways. (1) K8s é loop de reconciliação: você declara desejado, controllers convergem. (2) Control plane (apiserver + etcd + scheduler + controller-manager) é o cérebro; data plane (kubelet + kube-proxy + runtime) roda as cargas. (3) Pod é átomo, mas você nunca cria Pod direto — use Deployment/StatefulSet/DaemonSet/Job. (4) Service é IP estável; Ingress é roteamento HTTP com TLS. (5) ConfigMap/Secret separam config de código — cuidado com mudança que não propaga. (6) PVC dá volume persistente; StatefulSet garante que cada Pod mantenha o dele. (7) RBAC é obrigatório em prod. (8) HPA escala Pods, Cluster Autoscaler escala nodes, Helm+Argo CD gerencia releases. (9) Sempre kubectl describe antes de kubectl logs. (10) K8s resolve problemas grandes e cobra complexidade — só adote quando o retorno compensar.
🧩

Quiz rápido

4 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito

Continue lendo