transmissão ao vivo · o gp do kubernetes básico, etapa por etapa
Kubernetes narrado
direto do paddock.
Boa tarde, Brasil! Boa tarde, paddock! Oito etapas, da largada (por que esse esporte existe) à reta final do autoscaling, onde o cluster passa a pilotar sozinho. Em jogo: sair daqui sabendo montar, operar, curar e escalar um cluster de verdade. O farol vai apagar — e quem assume o volante da narrativa é o piloto. Com vocês.
Cada conceito de Kubernetes lido como um piloto lê a telemetria: o problema que cada peça resolve, a analogia de F1 tecnicamente honesta, o YAML comentado linha a linha, os comandos com a saída esperada e um mão na massa por etapa. No final, os sites gratuitos pra praticar em clusters reais no navegador.
O quadro de-para — cole isto no volante
A mesma analogia vale do início ao fim do guia. Não tente decorar esta tabela agora — ela é o mapa do circuito, não a prova: siga direto para a Etapa 01 e volte aqui sempre que uma analogia aparecer no texto.
| Kubernetes | Fórmula 1 |
|---|---|
| Container | O carro + kit da equipe: isolado na sua garagem, compartilhando a infraestrutura do circuito |
| Imagem de container | A especificação de montagem do carro — replicável em qualquer circuito do calendário |
| Máquina virtual (VM) | Levar a fábrica inteira da equipe para cada GP |
| Kubernetes (orquestrador) | A operação completa de mureta + garagem |
| Estado desejado | O target passado no rádio: você declara o alvo, o sistema mantém |
| Cluster | A equipe montada no fim de semana de GP |
| Control plane (master node) | A mureta (pit wall) |
| Worker node | A garagem/box onde os carros são montados e operados |
| API Server | O engenheiro de corrida — todo rádio passa por ele, sem exceção |
| kubectl | O botão de rádio do piloto |
| kubeconfig | O paddock pass + a frequência de rádio da equipe |
| etcd | O sistema central de dados da equipe (setup sheets + estado de tudo) |
| kubelet | O chefe de mecânicos de cada garagem |
| kube-proxy | O sinaleiro do pit lane, direcionando cada carro ao box certo |
| Minikube | O simulador da fábrica |
| Pod | O carro (chassi montado e rodando) |
| IP do Pod | A posição do carro na pista — muda o tempo todo |
| Labels | As etiquetas de rastreamento FIA nas peças e no carro (servem para selecionar) |
| Annotations | As anotações do engenheiro no caderno de debrief (servem para humanos) |
| Manifesto YAML | A folha de especificação do carro, versionada |
| Imperativo vs. declarativo | Ordem direta no rádio ("box, box") vs. plano de corrida escrito antes do GP |
| Service | O pit box: posição fixa no pit lane, atende qualquer carro com a etiqueta da equipe |
| ClusterIP | Canal interno de rádio — só a equipe ouve |
| NodePort | Portão de serviço numerado do autódromo |
| LoadBalancer | A entrada oficial do autódromo, com bilheteria |
| ConfigMap | A folha de set-up — separada do chassi |
| Secret | Os mapas de motor confidenciais |
| ReplicaSet | A regra do chefe de equipe: "N carros prontos, sempre" (e a virada de madrugada dos mecânicos) |
| Deployment | O programa de desenvolvimento: pacotes de upgrade, spec por spec |
| Rolling update | Introduzir o upgrade em um carro de cada vez |
| Rollback | Voltar para a spec anterior (o assoalho antigo que funcionava) |
| emptyDir | O quadro branco da garagem — apagado quando o fim de semana acaba |
| hostPath | Guardar dados no caixote de frete daquele circuito |
| PVC | A requisição de armazenamento do engenheiro de dados |
| PV | O storage físico da fábrica que atende a requisição |
| StorageClass | O catálogo de tipos de storage (trackside rápido vs. datacenter da fábrica) |
| Probes | As checagens de telemetria + radio check |
| Liveness probe | Telemetria mudou → reset completo do carro |
| Readiness probe | O semáforo do box: segura o carro fora da pista, sem desmontar nada |
| Startup probe | O procedimento de fire-up da PU: nada é cobrado antes do motor aquecer |
| HPA | A mureta de estratégia alinhando mais carros conforme a carga (uma F1 sem o limite de 2 carros) |
| metrics-server | Os sensores de telemetria — sem eles a mureta não enxerga nada |
| resources.requests | A alocação declarada de energia/combustível — a base de qualquer percentual |
Onde as analogias quebram (piloto que esconde limitação do carro quebra no muro):
- ReplicaSet (Etapa 05): na F1, reposição de carro só entre sessões, e o regulamento limita a 2 carros por equipe. O ReplicaSet repõe em segundos, a qualquer momento, em qualquer quantidade. A "virada de madrugada dos mecânicos" vale para o mecanismo (remontar da especificação), não para o tempo nem para o limite.
- HPA (Etapa 08): escalar réplicas não tem paralelo direto no grid de 2 carros — a analogia declarada é uma "endurance sem limite de inscrições". O comportamento da mureta (reagir à telemetria, respeitar piso e teto) se mantém fiel.
- Service (Etapa 04): o pit box real atende um carro por vez; o Service balanceia tráfego contínuo entre N réplicas simultâneas. A parte fiel é o endereço fixo + a seleção por etiqueta.
- Pod multi-container (Etapa 03): o carro com PU + MGU-K ilustra "unidades distintas compartilhando sistemas", mas containers de um Pod são processos independentes que podem ser trocados individualmente na especificação.
Etapa 01 motivação + setup
Por que o Kubernetes existe
APAGARAM-SE AS LUZES! É largada no GP do Kubernetes! Primeira curva, primeira freada, e a pergunta que abre todo campeonato: por que esse esporte existe? A resposta desta etapa sustenta as outras sete. Segura comigo.
Pense na demanda de um fim de semana de GP: o site da equipe, o timing, o streaming — tudo dorme durante a semana e explode no domingo da corrida. E tem o carro que voa no simulador e não anda na pista: o clássico "na minha máquina funciona". Todo projeto esbarra nesses dois problemas — e o Kubernetes automatiza a solução dos dois.
Como funciona
A peça comum das duas soluções é o container. Uma máquina virtual é como levar a fábrica inteira para cada GP — prensa de fibra de carbono, túnel de vento, escritório, tudo embarcado no avião. Um container é o carro com o kit da equipe: cada equipe tem sua garagem isolada, seus segredos, suas peças — mas a estrutura do circuito (o prédio dos boxes, a energia, o pit lane, ou seja, o kernel do sistema operacional) é compartilhada entre as dez equipes. A Cadillac, estreando neste ano, não construiu um autódromo para correr — chegou com seus caixotes e plugou na infraestrutura existente.
Em termos técnicos: a VM carrega um sistema operacional completo (gigabytes, minutos para subir); o container compartilha o kernel do SO hospedeiro e leva só os arquivos, binários e bibliotecas que o app precisa (megabytes, segundos). Uma imagem de container é um ambiente inteiro, replicável em qualquer lugar — a especificação de montagem que garante que o carro embarcado para Suzuka é idêntico ao que rodou em Melbourne. Adeus "na minha máquina funciona".
Só que containers resolvem o problema do ambiente e criam outro: com dezenas ou centenas deles, alguém precisa criá-los, destruí-los, vigiar a saúde e recriar o que falhar. Fazer isso na mão não escala — é como pedir para uma pessoa só operar os dois carros, a telemetria e o pit stop. O Kubernetes (K8s) é o orquestrador que assume essas tarefas: a operação completa de mureta + garagem.
A filosofia dele é a do engenheiro de corrida ditando target: ele não manda instrução a cada curva — declara "target +0.3 por volta, modo de energia 6" e todo o sistema trabalha sozinho para manter. No K8s você declara o estado desejado ("quero 3 cópias disso rodando") e ele mantém a realidade de acordo — inclusive de madrugada, quando um container morre. A mureta nunca dorme.
Os conceitos-chave desta etapa
Container ≠ VM
VM = hardware virtual + SO completo (a fábrica embarcada). Container = só o necessário do app, compartilhando o kernel do hospedeiro (o carro na garagem do circuito). Muito mais leve.
Escala horizontal
Mais cópias da aplicação dividindo a carga (é o que o K8s automatiza). Vertical = mais CPU/RAM na mesma máquina — alinhar mais carros vs. motor maior num carro só.
Cluster e Pod
O K8s organiza máquinas (nós) em clusters. Os containers rodam agrupados em Pods — a menor unidade gerenciada. Cluster = a equipe no fim de semana; Pod = o carro.
kubectl
A ferramenta de linha de comando que conversa com a API REST do cluster. É o seu botão de rádio (detalhes na Etapa 02).
Minikube
Um cluster K8s de 1 nó rodando na sua máquina. O simulador da fábrica: feito para estudo, sem risco de bater o carro de verdade — é o laboratório deste guia.
Estado desejado
A filosofia do K8s: você declara o que quer, ele faz acontecer e mantém. Caiu? Ele recria sozinho. O target no rádio.
Montando o laboratório (passo a passo)
# 1. Instale o Docker Desktop (docker.com) — no Linux, use o Docker# Engine (docs.docker.com/engine/install) — e confirme:$ docker -vDocker version 27.x# 2. Instale o kubectl (kubernetes.io/docs/tasks/tools) e confirme:$ kubectl version --output=yaml# 3. Instale o Minikube (minikube.sigs.k8s.io/docs/start) e suba o cluster:$ minikube start😄 minikube v1.33 on Windows 11✨ Using the docker driver🏄 Done! kubectl is now configured to use "minikube"# 4. Confirme que o cluster está de pé:$ kubectl get nodesNAME STATUS ROLES AGE VERSIONminikube Ready control-plane 1m v1.30.x# 5. Cluster vazio = sucesso:$ kubectl get podsNo resources found in default namespace.
💡 A primeira execução do minikube start baixa a imagem do cluster e demora alguns minutos. É normal — é o fire-up do simulador, e simulador frio nunca liga instantâneo.
Comandos essenciais desta etapa
Mão na massa
O menor exercício possível: prove que seu laboratório está vivo — o equivalente ao installation lap.
- Rode minikube start e aguarde o "Done!".
- Rode kubectl get nodes — observe: o nó minikube com STATUS Ready. Se aparecer NotReady, aguarde 1 minuto e repita.
- Rode kubectl get pods — observe: "No resources found". Cluster vazio e pronto é exatamente o ponto de partida da próxima etapa — garagem limpa antes do carro chegar.
- Bônus: rode minikube stop e depois kubectl get nodes — veja a mensagem de erro de conexão. Suba de novo com minikube start. Agora você sabe o que "cluster fora do ar" parece no terminal — é o rádio mudo, e rádio mudo em corrida é a pior sensação que existe.
Dica: Se o minikube start falhar, a causa mais comum é o Docker Desktop não estar aberto (no Linux, o serviço parado: sudo systemctl start docker). Suba o Docker primeiro e tente de novo. (Todo simulador tem um disjuntor que alguém esqueceu de ligar.)
Anota aí: Container é um ambiente leve e replicável — o carro que anda igual em qualquer circuito; Kubernetes é o engenheiro de corrida do estado desejado — você declara o target, ele garante.
Setor 1 no verde! Laboratório de pé, simulador ligado, cluster respondendo — largada limpíssima. Agora vem a parte que todo estreante subestima: aprender a falar no rádio. Etapa 02 na sequência — não sai daí.
Etapa 02 o botão de rádio
kubectl e a API: como você comanda o cluster
Segunda etapa e o traçado aperta: de que adianta ter o carro na garagem se você não sabe apertar o botão do rádio? A F1 vive desse canal — foi nele que Kimi Räikkönen imortalizou o "deixa comigo, eu sei o que estou fazendo" em Abu Dhabi 2012, e venceu. Hoje é você quem aprende a dar as ordens.
Seu cluster está de pé, mas é uma caixa fechada. Como mandar ordens? Como investigar quando algo der errado, sem acesso "físico" ao container? Na pista o piloto tem o mesmo problema: a 300 km/h, não dá pra descer e abrir o capô — tudo que ele sabe do carro chega pelo rádio e pela telemetria.
Como funciona
Tudo no Kubernetes passa pela API REST do nó master. O kubectl é o cliente dessa API: cada comando que você digita vira uma requisição HTTP (GET, POST, PUT, DELETE) contra o cluster. Na F1, o piloto não fala com o mecânico do pneu dianteiro esquerdo nem com a fábrica — fala com uma pessoa: o engenheiro de corrida. Toda mensagem passa por esse canal único, que valida, registra e repassa para quem executa. O kubectl é o seu botão de rádio; o API Server é o engenheiro de corrida: nada acontece no cluster sem passar por ele.
O caminho de um comando: você digita kubectl get pods → o kubectl lê o arquivo kubeconfig (endereço do API Server, credenciais e contexto do cluster atual — o Minikube configura isso sozinho; pense nele como o paddock pass com a frequência de rádio da equipe já sintonizada) → e dispara um GET /api/v1/pods contra o API Server. A resposta volta formatada no seu terminal.
A API é dividida em grupos: o "core" tem os recursos fundamentais (pods, services, replicasets); outros grupos cuidam de segurança, armazenamento, autoscaling — como os departamentos da equipe: chassi, aero, PU, estratégia. Como é REST puro, dá para chamar de qualquer linguagem — Python, Go, Java, C# — o que abre portas para automação.
Existem dois jeitos de trabalhar: o imperativo (kubectl run nginx --image=nginx — a ordem direta, o "box, box, box" no rádio: rápido, decisivo, bom para testes) e o declarativo (escrever um YAML e rodar kubectl apply -f arquivo.yaml — o plano de corrida escrito no sábado à noite: documentado, revisado, versionado). Em projetos reais o declarativo domina, porque o arquivo é versionável no Git — nenhuma equipe séria improvisa a estratégia inteira no rádio.
Os verbos que resolvem 90% do dia
get
Consultar: lista recursos e o status de cada um. kubectl get pods, get svc, get nodes... É a olhada no painel de timing.
create / run / apply
Criar: run cria um pod imperativo; apply -f aplica um YAML (declarativo).
delete
Remover: kubectl delete pod nginx. Cuidado — pode afetar quem depende do recurso.
describe
Detalhar: configuração + a seção Events. Primeira parada quando algo trava — o histórico de telemetria da sessão, evento por evento.
logs
Ver o que o container está imprimindo. Seu melhor amigo no debug: é ouvir o rádio do carro direto.
exec
Abrir um shell dentro do container: kubectl exec -it <pod> -- /bin/sh. O mecânico plugando o laptop no carro.
Exemplo estruturado: ciclo de vida de um Pod
# Cria um pod chamado "nginx" a partir da imagem nginx:1.14.2 do Docker Hub$ kubectl run nginx --image=nginx:1.14.2 --port=80pod/nginx created# Acompanhe até o status ficar Running (o primeiro estado é ContainerCreating)$ kubectl get podsNAME READY STATUS RESTARTS AGEnginx 1/1 Running 0 30s# Detalhes + eventos (veja a linha "Pulling image" na seção Events)$ kubectl describe pod nginx# O que o container está imprimindo$ kubectl logs nginx# Limpeza$ kubectl delete pod nginxpod "nginx" deleted
💡 Se o status ficar em ImagePullBackOff, o cluster não conseguiu baixar a imagem — confira o nome/tag e sua internet. É o caixote de peças que não chegou no circuito: sem a spec certa, o carro não monta.
Comandos essenciais desta etapa
Mão na massa
Execute o ciclo completo e force o primeiro erro da sua vida no K8s — todo piloto precisa da primeira rodada para calibrar o limite:
- Rode a sequência do exemplo acima (run → get → describe → logs → delete). Observe no describe a seção Events: as linhas Pulling image, Created container, Started container contam a história do pod em ordem — igual ao replay da telemetria, quadro a quadro.
- Agora crie um pod quebrado de propósito: kubectl run quebrado --image=nginx:versao-que-nao-existe.
- Rode kubectl get pods — observe o status ImagePullBackOff (ou ErrImagePull).
- Rode kubectl describe pod quebrado — observe nos Events a mensagem explicando que a imagem não foi encontrada. Você acabou de praticar o fluxo de debug de verdade.
- Limpe: kubectl delete pod quebrado.
Dica: Grave este fluxo: get pods (qual o status?) → describe pod (o que dizem os Events?) → logs (o que o app diz?). Essa sequência resolve a maioria dos problemas. É o protocolo pós-problema do piloto: painel de timing → histórico de telemetria → rádio do carro.
Anota aí: Tudo no K8s é uma chamada à API REST; o kubectl é o seu botão de rádio e o API Server é o engenheiro de corrida — e quando algo trava, o caminho é sempre get → describe → logs.
Rádio calibrado e — repararam? — o primeiro erro forçado e diagnosticado sem pânico. Esse setor separa quem aperta botão de quem conversa com a equipe. E atenção, porque agora vem o miolo técnico do circuito: a anatomia do cluster e a folha de especificação. Não pisca.
Etapa 03 arquitetura + labels
A anatomia do cluster — e a menor unidade dele: o Pod
Entramos no complexo de curvas mais técnico do traçado — aqui não adianta coragem, é precisão. E a história do esporte não perdoa spec fora do lugar: em 1999 a Ferrari quase perdeu uma vitória na Malásia por milímetros nas barge boards. Especificação não é burocracia, é resultado. Hoje você escreve a sua primeira folha de especificação.
Na Etapa 02 você criou um pod com um comando imperativo. Funciona, mas tem dois furos: você não sabe o que exatamente foi criado nem onde — e se amanhã precisar recriar aquele pod idêntico, vai depender da memória. Nenhuma equipe monta um carro de memória: existe folha de especificação para tudo, do ângulo da asa ao torque de cada parafuso.
Como funciona
Um cluster é um grupo de máquinas (nodes) trabalhando juntas, com papéis bem definidos — é a equipe montada no fim de semana de GP. O Pod é a menor unidade que o Kubernetes gerencia — no nosso mapa, o Pod é o carro: um "envelope" com um ou mais containers que dividem rede e armazenamento.
Quatro fatos sobre Pods: (1) um Pod representa um processo em execução e pode ter mais de um container dividindo o mesmo IP e volumes — como PU e MGU-K no mesmo carro; (2) Pods são efêmeros — nascem e morrem o tempo todo; o carro que correu em Silverstone hoje será desmontado até o último parafuso antes de Spa, o que permanece é a especificação (guarde esta frase: ela é a raiz das Etapas 04, 05 e 06); (3) cada Pod ganha um IP interno do cluster — a posição do carro na pista: existe, é real, mas muda o tempo todo; (4) Pods são descritos em YAML — a folha de especificação do carro.
Para organizar dezenas de Pods existem os rótulos e as anotações. Na F1, cada componente do carro — PU, turbo, MGU-K, câmbio — carrega uma etiqueta de rastreamento lacrada pela FIA: é por ela que o sistema sabe qual motor está em qual carro; a etiqueta serve para IDENTIFICAR E SELECIONAR. Já o caderno de debrief do engenheiro ("piloto reportou vibração na curva 7") é informação para humanos — ninguém filtra componentes por anotação de caderno. Labels são a etiqueta FIA (é por label que um Service acha seus Pods — você verá na Etapa 04); annotations são o caderno de debrief (autor, documentação, auditoria — NÃO participam de seleção). Essa diferença é o que cai em prova.
Quem faz o quê dentro do cluster
Master node
A mureta (pit wall): gerencia o cluster e decide onde executar os Pods.
Worker node
As garagens: executam os Pods e demais recursos. É onde o carro é montado e roda.
etcd
O sistema central de dados da equipe: banco distribuído com a configuração e o estado do cluster — as setup sheets de tudo.
kubelet
O chefe de mecânicos de cada garagem: agente em cada node que gerencia os Pods locais.
kube-proxy
O sinaleiro do pit lane: encaminha o tráfego de rede para os Pods certos.
API Server
O engenheiro de corrida — tudo que o kubectl faz passa por aqui (Etapa 02).
O primeiro YAML — decore este esqueleto
apiVersion: v1 # versão da API do K8s p/ este objetokind: Pod # o TIPO de objeto criadometadata: # dados SOBRE o objetoname: meu-podlabels: # rótulos: chave-valor p/ SELECIONARapp: myappambiente: estudoannotations: # anotações: metadados livres (docs)autor: "Davi Gomes"spec: # a ESPECIFICAÇÃO: o que roda dentrocontainers:- name: meu-containerimage: nginx:1.14.2ports:- containerPort: 80
💡 Todo objeto K8s segue esse esqueleto: apiVersion + kind + metadata + spec. Muda o kind e o conteúdo do spec — o resto é sempre igual. É como o regulamento técnico: quem entende a estrutura de um artigo lê todos os outros.
Comandos essenciais desta etapa
Mão na massa
- Salve o YAML acima como meu-pod.yaml e aplique com kubectl apply -f meu-pod.yaml.
- Rode kubectl get pods --show-labels — observe os dois labels na última coluna.
- Rode kubectl get pods -l app=myapp e depois kubectl get pods -l app=outra-coisa — observe: o primeiro encontra o pod, o segundo retorna vazio. Etiqueta certa, carro encontrado; etiqueta errada, garagem vazia.
- Adicione um label em tempo real: kubectl label pod meu-pod time=devops e confirme com --show-labels.
- NÃO delete o pod — ele será o alvo do Service na próxima etapa. (Se deletou, é só aplicar o YAML de novo — essa é a graça do declarativo: a folha de especificação remonta o carro idêntico.)
Dica: Labels = seleção operacional (o K8s usa). Annotations = documentação (humanos usam). Autor de um Pod? Annotation. Agrupar Pods de uma app? Label. Etiqueta FIA vs. caderno de debrief.
Anota aí: Todo objeto K8s é apiVersion + kind + metadata + spec — a folha de especificação do carro; e labels são a etiqueta FIA pela qual tudo no cluster encontra tudo.
Que setor limpo, senhoras e senhores! Esqueleto de YAML no bolso, etiquetas dominadas — e repara que o guia armou a jogada: esse label app: myapp que ficou vivo na pista é a ultrapassagem preparada da próxima etapa. Vamos para o pit box!
Etapa 04 rede + configuração
Services: endereço fixo pra Pods que mudam
Volta 4 e o problema clássico do pit lane aparece: como achar um carro que muda de posição o tempo todo? Quem acompanha F1 sabe que endereço e procedimento no box não são detalhe — Christijan Albers que o diga, saindo do box em 2007 com a mangueira de combustível ainda pendurada. Endereço fixo e configuração fora do chassi: é disso que esta etapa vive.
Lembra do fato nº 2 da Etapa 03? Pods são efêmeros: cada Pod novo nasce com um IP diferente. Tentar falar com eles pelo IP é como achar um carro pela posição na pista — na volta 12 ele está em P4, na volta 30 em P7. E tem o segundo problema: configuração dentro da imagem obriga a rebuildar a cada mudança — um chassi novo toda vez que a mureta pede meio grau a mais de asa.
Como funciona
Problema 1 → Service. O Service é o pit box da equipe: a posição do box no pit lane é fixa a temporada inteira — todo mundo sabe onde fica o box da Ferrari. Qual carro entra nele a cada volta muda (o de Leclerc, o de Hamilton, um chassi montado ontem) — e quem precisa do box não se importa: o endereço é o mesmo, e o box atende qualquer carro que carregue a etiqueta da equipe.
O fluxo: uma requisição chega no Service (IP e nome fixos) → o Service seleciona os Pods pelo label selector (o mecanismo da Etapa 03 — a etiqueta FIA de novo) → e distribui o tráfego de forma balanceada entre as réplicas saudáveis. O nome do Service vira um hostname interno do cluster: se o Service chama "auth-service", qualquer Pod acessa http://auth-service — mesmo que os Pods por trás troquem de IP mil vezes.
Problema 2 → ConfigMap. O ConfigMap é a folha de set-up separada do chassi: asa, pressões, mapas — nada disso é soldado no carro; está numa folha que os mecânicos aplicam antes do carro sair da garagem. Você guarda os valores num objeto central e injeta de 3 formas: variáveis de ambiente (a mais comum, via envFrom), arquivos montados (ótimo para configs longas) ou argumentos de linha de comando. Mudou a config? Atualiza o ConfigMap — a imagem continua a mesma. Meio grau de asa não exige chassi novo.
Os 3 tipos de Service
ClusterIP (padrão)
IP interno, só dentro do cluster. O canal interno de rádio: só a equipe ouve. Use para comunicação entre serviços (ex.: API ↔ banco).
NodePort
Porta fixa (30000–32767) aberta no nó. O portão de serviço numerado do autódromo — o jeito de expor algo no Minikube.
LoadBalancer
Balanceador externo com IP público. A entrada oficial do autódromo, com bilheteria — o tipo de produção na nuvem (AWS, GCP, Azure).
Os YAMLs — repare no selector
# app.yaml — salve o Service neste arquivoapiVersion: v1kind: Servicemetadata:name: meu-service # vira o hostname internospec:type: NodePort # troque p/ ClusterIP (interno) ou LoadBalancer (nuvem)selector: # ← O ELO: procura Pods com este labelapp: myappports:- protocol: TCPport: 80 # porta em que o Service escutatargetPort: 80 # porta do container que recebenodePort: 30080 # porta exposta no nó (só NodePort)
💡 O selector do Service casa com o label do Pod (app: myapp) — exatamente o meu-pod que você criou na Etapa 03. É assim que ele sabe pra quem mandar o tráfego: o box lê a etiqueta do carro que está chegando.
Comandos essenciais desta etapa
Mão na massa
- Com o meu-pod da Etapa 03 rodando (label app: myapp), salve o YAML do Service como app.yaml e aplique.
- Rode minikube service meu-service --url e abra a URL no navegador — observe a página de boas-vindas do nginx. Você acessou um Pod efêmero por um endereço estável — encontrou o carro pelo box, não pela posição na pista.
- Teste o elo: delete o pod (kubectl delete pod meu-pod) e recarregue o navegador — observe o erro (box vazio, nenhum carro com a etiqueta da equipe). Recrie com kubectl apply -f meu-pod.yaml e recarregue — voltou, sem tocar no Service. O box nem se mexeu.
- Aplique o ConfigMap + pod (kubectl apply -f configmap-pod.yaml) e rode kubectl exec pod-config -- env — observe MENSAGEM e MODO na lista de variáveis. A folha de set-up foi aplicada no carro.
Dica: Regra de ouro: exponha o mínimo. Banco de dados = ClusterIP (canal interno — estratégia de corrida não vaza no rádio aberto). Só a porta de entrada do sistema vira NodePort/LoadBalancer. Pra senhas e chaves, o irmão seguro do ConfigMap é o Secret — os mapas de motor que nem todo mecânico da própria equipe conhece.
Anota aí: Service é o pit box: endereço fixo para carros (Pods) que mudam, achando-os pela etiqueta (label); ConfigMap é a folha de set-up — configuração fora do chassi (imagem).
Setor no roxo! Pod acessado por endereço estável, configuração fora do chassi — e você ainda provou o elo deletando o carro e vendo o box impassível no mesmo lugar. Mas atenção, porque agora vem a curva que decide corrida: o que acontece quando o carro PARA na pista?
Etapa 05 auto-cura + escala
Auto-cura e escala: ReplicaSets e Deployments
É AQUI que separa os pontuadores do resto do grid! Hoje mesmo, volta 46, o carro da Red Bull calou e o Verstappen assistiu ao fim da prova do muro — zero ponto. Em produção, o seu Pod único morrendo às 3h da manhã é exatamente essa cena. Auto-cura e caminho de volta — a etapa mais importante do guia começa AGORA.
Até aqui você criou Pods na mão — ótimo pra aprender, mas pense em Silverstone hoje: o Verstappen parou na volta 46 e acabou — não há substituto no meio da corrida. Em produção, seu único Pod morrendo de madrugada é isso: site fora do ar até alguém acordar. E quando lançar a 2.0, como trocar a versão sem derrubar o serviço? E se ela vier com um bug catastrófico, como voltar rápido?
Como funciona
ReplicaSet — o chefe de equipe do número. Você declara "replicas: 3" e ele monitora os Pods pelo label selector (a etiqueta FIA, de novo!). Caiu um? Ele detecta que a contagem baixou e cria outro em segundos, sem você pedir. É a regra inegociável do chefe de equipe — "N carros prontos, sempre": o piloto destrói o chassi no sábado, os mecânicos viram a madrugada e no domingo tem um carro inteiro no grid, remontado da especificação. É a auto-cura do Kubernetes — o "estado desejado" da Etapa 01 mantido de verdade.
Aqui a analogia quebra — e vale registrar: na F1, a reposição só acontece entre sessões, e o regulamento limita cada equipe a 2 carros. O ReplicaSet não tem parc fermé nem regulamento: repõe o Pod em segundos, a qualquer hora, em qualquer quantidade. Pense no K8s como uma endurance sem limite de inscrições — e a "madrugada dos mecânicos" dura trinta segundos.
Deployment — o gestor de specs. Ele embrulha o ReplicaSet e adiciona o programa de desenvolvimento: Rolling Update (ao trocar a imagem, sobe réplicas novas e desliga as antigas gradualmente — o serviço nunca fica fora do ar, como o upgrade que entra em um carro enquanto o outro segue com a spec antiga), Rollback (kubectl rollout undo volta pra anterior em segundos — o assoalho novo não anda, o carro volta com a spec anterior; a Ferrari chegou em Barcelona este ano com pacote novo e o Hamilton venceu, mas se o pacote piorasse o carro, voltavam pra spec de Mônaco sem drama) e escala manual (kubectl scale --replicas=5: cinco carros no grid).
Os YAMLs de ReplicaSet e Deployment são quase idênticos, mas no dia a dia usamos quase sempre o Deployment, pelo controle de versão — ninguém gerencia só o número de carros; gerencia-se o número E a spec de cada um. O Deployment cria e gerencia o ReplicaSet por baixo dos panos.
O que cada um garante
ReplicaSet
N réplicas rodando SEMPRE. Caiu uma, nasce outra em segundos — a madrugada dos mecânicos comprimida. Seleção por label selector.
Rolling Update
Troca de versão gradual: sobe as novas, desliga as antigas. Zero downtime — upgrade introduzido em um carro por vez.
Rollback
A versão nova quebrou? kubectl rollout undo volta pra anterior em segundos — de volta pra spec que funcionava.
O Deployment completo + ciclo de vida
apiVersion: apps/v1kind: Deploymentmetadata:name: nginx-fiapspec:replicas: 3 # quero 3 cópias, sempreselector:matchLabels:app: nginx-app # gerencio os Pods com este label...template: # ...e este é o "molde" de cada Podmetadata:labels:app: nginx-app # tem que casar com o selector ↑spec:containers:- name: nginximage: nginx:1.14.2 # trocar esta versão dispara o rolling updateports:- containerPort: 80
💡 Repare: o template é literalmente o esqueleto de Pod da Etapa 03, embutido no Deployment. Nada aqui é novo — é composição: a folha de especificação do carro, anexada à ordem do chefe de equipe ("três carros desta spec, sempre").
Comandos essenciais desta etapa
Mão na massa
O momento que as arquibancadas esperavam: o pit stop do guia. Mas aqui, diferente da troca de pneus, pressa é inimiga — o valor do exercício está em OBSERVAR cada estado mudando no terminal. Calma e olhos abertos.
- Aplique o deployment.yaml e confirme os 3 pods Running — três carros na pista, mesma spec.
- Delete um pod na mão (copie um nome real do kubectl get pods) e rode kubectl get pods de novo, rápido — observe o substituto em ContainerCreating. Você tentou violar o estado desejado e o cluster corrigiu.
- Rode o rolling update para nginx:1.16.1 e acompanhe com kubectl rollout status — observe a mensagem de sucesso. Upgrade introduzido carro a carro, ninguém saiu da pista.
- Quebre de propósito com a imagem nginx:nao-existe — observe no kubectl get pods os pods antigos Running segurando o serviço e os novos em ImagePullBackOff.
- Execute kubectl rollout undo deployment/nginx-fiap e confirme com kubectl rollout history — observe as revisões listadas. Você fez um rollback de produção em um comando — voltou pra spec da classificação sem perder a corrida.
Dica: Faça o teste da auto-cura pelo menos uma vez: matar um pod e ver o substituto nascer — a madrugada dos mecânicos comprimida em segundos. É o momento em que o Kubernetes "clica" na cabeça.
Anota aí: Ninguém cria Pod avulso em produção — carro sem equipe não termina corrida: o Deployment garante N réplicas (auto-cura), troca specs sem tirar ninguém da pista (rolling update) e volta pra spec anterior em um comando (rollback).
E o público de pé nas arquibancadas! Você MATOU um Pod e o cluster o remontou antes do replay terminar. Setor decisivo completado no verde. Agora, a pergunta que assombra qualquer equipe de ponta: e os DADOS?
Etapa 06 persistência de dados
Volumes: dados que sobrevivem ao Pod
Entramos no setor de alta velocidade — e no assunto que não aparece nos highlights, mas ganha campeonatos: dados. A Williams dominou os anos 90 porque transformava telemetria em desenvolvimento antes de todo mundo. Carro se desmonta; histórico, jamais. Etapa 06 valendo.
Pods são efêmeros — e a Etapa 05 deixou isso radical, com pods morrendo e nascendo em rolling updates. Ótimo pro app, catastrófico pra dados: o carro que correu hoje será desmontado até o monocoque, mas os gigabytes de telemetria já estão na fábrica antes do piloto tirar o capacete. Se o Pod do PostgreSQL for recriado num update, todos os pedidos da Black Friday somem junto — dados de verdade não podem viver no filesystem de um container.
Como funciona
O Kubernetes resolve isso com uma cadeia de 4 conceitos: Volume, PersistentVolume (PV), PersistentVolumeClaim (PVC) e StorageClass (SC). Memorize pela operação de dados da equipe: o PVC é a REQUISIÇÃO do engenheiro de dados ("preciso de 1Gi, leitura e escrita por um nó"); o PV é o STORAGE físico da fábrica que atende a requisição (NFS, EBS da AWS, hostPath...); a StorageClass é o CATÁLOGO de tipos de storage (o servidor trackside rápido? o datacenter da fábrica?).
O Pod só referencia o PVC — o carro não sabe (nem precisa saber) em qual rack da fábrica a telemetria dele está guardada. Essa separação é o que permite o mesmo YAML rodar no Minikube e na AWS — o mesmo procedimento de dados funciona em Interlagos e em Suzuka. No Minikube, a StorageClass "standard" já provisiona PVs automaticamente: você faz a requisição (PVC) e o storage (PV) aparece.
Modos de acesso do PVC (quem pode montar o volume): ReadWriteOnce (leitura e escrita por UM nó — o caso típico de banco de dados; só a garagem da equipe escreve nos próprios dados), ReadOnlyMany (só leitura, vários nós — assets estáticos; como o feed de timing da FIA: todas as equipes leem, ninguém altera) e ReadWriteMany (leitura e escrita por vários nós — precisa de NFS ou similar).
A cadeia de armazenamento
emptyDir
Vive e morre com o Pod. O quadro branco da garagem: anotações da sessão, apagadas quando o fim de semana acaba. Pra dado temporário e compartilhamento entre containers do Pod.
hostPath
Monta diretório do NÓ no container. O caixote de frete daquele circuito: dev ok; produção, cuidado (amarra o Pod ao nó).
PVC → PV
A requisição (Claim) casa com o storage (Volume). Dados sobrevivem à morte do Pod — a telemetria na fábrica.
StorageClass
O catálogo: provisiona PVs automaticamente por perfil. No Minikube, a classe "standard" já faz isso.
Prove a persistência: escreva, destrua, leia de volta
apiVersion: v1kind: PersistentVolumeClaimmetadata:name: meu-pvcspec:accessModes:- ReadWriteOnce # um nó lê e escreve (típico de banco)resources:requests:storage: 1Gi # quanto disco eu quero# no Minikube, a StorageClass "standard" provisiona o PV sozinha
Comandos essenciais desta etapa
Mão na massa
- Aplique o PVC e rode kubectl get pvc — observe o STATUS Bound: sua requisição foi atendida por um PV criado automaticamente (confirme com kubectl get pv).
- Execute a sequência completa do exemplo: escrever o arquivo → deletar o pod → recriar o pod → ler o arquivo. Observe o "sobrevivi!" voltar. Esse é o contrato do PVC — o carro morre, a telemetria fica.
- Experimento extra (o contraste que ensina): repita o teste trocando o volume por emptyDir — ao recriar o Pod, o arquivo terá sumido. Essa é a diferença entre o quadro branco da garagem e o servidor da fábrica, sentida na prática.
Dica: Dado importante SEMPRE em PVC. Se os dados sumiram após um restart, aposto que estavam em emptyDir ou no filesystem do container — alguém anotou a estratégia da corrida no quadro branco e a faxina passou.
Anota aí: PVC é a requisição, PV é o storage, StorageClass é o catálogo — e dado que importa mora sempre atrás de um PVC: o carro é desmontado, a telemetria nunca.
"SOBREVIVI!" — e o arquivo voltou! O carro foi desmontado até o monocoque e a telemetria estava lá, intacta, na fábrica. Setor no verde. Mas segura na cadeira, porque agora vem a pegadinha mais traiçoeira do circuito: o carro que anda... mas não anda.
Etapa 07 saúde do app
Probes: como o cluster sabe que seu app está vivo
Atenção que esta curva é CEGA! Hoje, em Silverstone, o mundo inteiro viu: Antonelli largou na pole, cravou 1:31.777 — a volta mais rápida da prova — e cruzou a linha em DÉCIMO SEXTO. Cinquenta e duas voltas na pista, e nada saudável. E os mais antigos lembram de Senna em Interlagos, 1991: o carro andava, mas só restava a sexta marcha. É exatamente esse buraco que as probes fecham.
O Antonelli esteve na pista, rodando, as 52 voltas — e mesmo assim algo claramente não estava saudável. No cluster é idêntico: seu app entra em deadlock às 3h da manhã, o processo continua de pé (pro Kubernetes está tudo Running), mas nenhuma requisição é respondida. A auto-cura da Etapa 05 só recria pods que MORREM; ela não enxerga pods vivos porém travados — o carro que anda, mas não anda.
Como funciona
As probes são verificações de saúde declaradas no manifesto do Pod. É a telemetria + o radio check: a equipe não confia no fato de o carro estar se movendo — ela verifica canais específicos em intervalos regulares: pressão de óleo, temperatura da PU, resposta do piloto no rádio. Não basta o carro estar na pista; ele precisa responder aos estímulos.
Como a probe verifica (3 mecanismos): httpGet (o kubelet faz um GET num endpoint tipo /health e espera 200 OK — o mais comum; é o radio check: "me dá um ok, piloto"), tcpSocket (testa se a porta aceita conexão — pra serviços que não falam HTTP; a portadora do rádio abre, mesmo sem conversa) e exec (executa um comando dentro do container; código de saída 0 = saudável — o mecânico plugando o laptop e rodando o diagnóstico).
Boas práticas da aula: use as três probes juntas em produção; use endpoints diferentes pra cada probe (canais de telemetria separados — pressão de óleo não se mede no sensor de freio); comece pelas configurações padrão e ajuste intervalos só quando o app pedir; monitore as falhas de probe (ex.: com Prometheus) — elas são o primeiro sinal de problema, como aquele tremor na telemetria duas voltas antes de a peça quebrar.
As 3 probes e o que acontece na falha
Liveness
"Está vivo?" Falhou → o Pod é REINICIADO. O "faça o ciclo completo — desliga e liga o carro". Pra apps que travam e só voltam com restart.
Readiness
"Pronto pra tráfego?" Falhou → SAI do balanceador, sem restart. O semáforo vermelho do box: segurado na garagem, ninguém o desmonta. Pra apps que carregam dados antes.
Startup
"Terminou de subir?" Enquanto roda, SEGURA as outras. O fire-up da PU: ninguém cobra tempo de volta com motor frio. Pra apps lentos no boot.
Pod com as 3 probes + sabotagem didática
apiVersion: v1kind: Podmetadata:name: exemplo-probesspec:containers:- name: appimage: exemplo:latestports:- containerPort: 80livenessProbe: # falhou → REINICIA o podhttpGet:path: /healthport: 80periodSeconds: 10 # verifica a cada 10stimeoutSeconds: 5failureThreshold: 3 # 3 falhas seguidas → reinicia (3 é o padrão)readinessProbe: # falhou → SAI do balanceadorhttpGet:path: /ready # boa prática: endpoint separadoport: 80periodSeconds: 5startupProbe: # segura as outras até o app subirhttpGet:path: /startupport: 80initialDelaySeconds: 120 # app lento: espera 2minperiodSeconds: 30
💡 Este YAML é ilustrativo — a imagem exemplo:latest é fictícia. O experimento executável está na aba seguinte.
Comandos essenciais desta etapa
Mão na massa
- Aplique o liveness-exec.yaml e rode kubectl get pods -w — observe a coluna RESTARTS subir sozinha a cada ~35-45s. Cada incremento é o kubelet mandando o "desliga e liga o carro" pra um Pod que parou de responder na telemetria.
- Em outro terminal, rode kubectl describe pod liveness-exec — observe nos Events o par Warning Unhealthy + Normal Killing. Aprenda a reconhecer essa dupla: em produção, ela é o diagnóstico de probe falhando.
- Limpe: kubectl delete pod liveness-exec.
Dica: Running NÃO significa saudável. O Antonelli rodou as 52 voltas de Silverstone com pole e volta mais rápida no bolso — e terminou em P16. Carro na pista não é carro competitivo; processo de pé não é app funcionando. É exatamente por isso que as probes existem.
Anota aí: Liveness falhou = desliga e liga o carro (reinicia); Readiness falhou = semáforo vermelho do box (sai do balanceador sem reiniciar); Startup = fire-up da PU (segura as duas até o app terminar de aquecer).
RESTARTS subindo sozinho na tela — você sabotou o sensor e viu a mureta mandar o reset, três leituras confirmadas, sem pânico. Poucos setores ensinam tanto com tão pouco YAML. E agora, a reta final do circuito: o cluster vai aprender a pilotar sozinho.
Etapa 08 escala automática
HPA: escala automática baseada em métricas
ÚLTIMA ETAPA, bandeirada à vista! E que fecho de prova: a mureta assumindo a estratégia em tempo real. Foi assim que Ross Brawn venceu a Hungria em 1998 — Schumacher voando e uma estratégia de três paradas recalculada com a corrida em andamento. Hoje, quem lê e reage é o HPA — e o ciclo do estado desejado, aberto lá na Etapa 01, se fecha diante dos seus olhos.
Volte ao problema da Etapa 01: a demanda explode no domingo da corrida. Você já sabe escalar na mão (kubectl scale, Etapa 05) — mas vai ficar de plantão no terminal ajustando réplicas a cada pico? Às 2h da manhã também? Nenhuma mureta funciona assim: a estratégia reage à corrida em tempo real, com base em telemetria. O ciclo precisa se fechar: o cluster deve medir a carga e escalar sozinho.
Como funciona
O Horizontal Pod Autoscaler (HPA) monitora métricas dos Pods (CPU, memória...) e ajusta o número de réplicas entre um mínimo e um máximo que você define. É a mureta de estratégia com poder de alinhar mais carros conforme a carga da corrida — lembrando o combinado da Etapa 05: aqui a F1 trava em 2 carros, então pense numa endurance sem limite de inscrições. O ritmo apertou além do alvo → alinha mais carros (até o teto); a corrida acalmou → recolhe gradualmente.
O funcionamento: o HPA compara a utilização dos Pods com o alvo configurado (ex.: manter a média de CPU em 70%). Passou → cria réplicas (até o máximo). Caiu → remove (até o mínimo), economizando recurso. O scale down é propositalmente lento (~5min de estabilidade) pra não ficar "pistonando" com variações rápidas — mesma razão pela qual a mureta não muda a estratégia a cada nuvem no radar: espera o padrão se confirmar, sem desmontar a operação no primeiro safety car.
Métricas suportadas: CPU (a mais comum), memória, métricas personalizadas do app (requisições/s, fila), métricas externas (ex.: Prometheus) e E/S de disco. A métrica certa depende do perfil do app — como escolher a estratégia pelo que o carro degrada: pneu em Barcelona, freio em Montreal.
Dois pré-requisitos que pegam todo mundo: (1) o cluster precisa do metrics-server pra ler CPU/memória — no Minikube: minikube addons enable metrics-server. Sem sensores no carro, a mureta não enxerga nada. (2) O container PRECISA declarar resources.requests.cpu, porque "70% de CPU" significa 70% DO QUE O POD PEDIU — como a alocação de energia do ERS por volta: "usei 70%" só faz sentido contra uma alocação declarada. Sem requests, o HPA mostra <unknown> e não escala.
O que o HPA entende
CPU / Memória
As métricas clássicas. % calculada sobre o resources.requests do container — o percentual da alocação declarada, nunca um número absoluto solto.
Métricas custom
Do seu app (req/s, fila) ou externas (Prometheus). Pra escalar pelo que importa — cada pista degrada uma coisa diferente.
min / max
Você sempre define o piso e o teto de réplicas. O HPA trabalha dentro da faixa, como a estratégia dentro do regulamento.
Deployment + HPA + Service + teste de carga
apiVersion: apps/v1kind: Deploymentmetadata:name: nginx-hpaspec:replicas: 1 # começa com 1; o HPA assume daquiselector:matchLabels:app: nginx-hpatemplate:metadata:labels:app: nginx-hpaspec:containers:- name: nginximage: nginx:1.14.2resources: # SEM requests o HPA não calcula %requests:cpu: "100m" # 100 milicores = 0,1 CPUlimits:cpu: "200m"
Comandos essenciais desta etapa
Mão na massa
Volta rápida final do fim de semana — todos os setores juntos numa tacada só:
- Ative o metrics-server e aplique os três YAMLs (Deployment, HPA, Service). Rode kubectl get hpa — observe os targets: se aparecer <unknown>, aguarde ~1min (sensor recém-instalado não dá dado antes da primeira volta).
- Suba o gerador de carga num terminal e kubectl get hpa -w em outro — observe o percentual de CPU disparar acima de 70% e a coluna REPLICAS subir. Se estacionar abaixo do alvo, use o plano B da aba de carga. Confirme com kubectl get pods: pods novos nasceram sem nenhum comando seu — a mureta alinhou carros sozinha, lendo a telemetria.
- Pare a carga (Ctrl+C) e continue assistindo — observe que as réplicas demoram ~5min pra encolher. Essa lentidão é proposital (ninguém desmonta a garagem no primeiro momento de calmaria).
- Use kubectl top pods durante o teste pra ver a métrica crua que alimenta o HPA — a telemetria antes da decisão de estratégia.
Dica: kubectl get hpa mostrando <unknown> nos targets? Ou o metrics-server não está ativo, ou o container não declarou resources.requests. São as duas causas, sempre — ou o sensor está desligado, ou ninguém declarou a alocação de referência.
Anota aí: HPA = estado desejado aplicado à escala: você define alvo, piso e teto — a mureta faz o resto. Mas sem metrics-server (sensores) e sem resources.requests (alocação declarada) ele não enxerga nada.
E o cluster ESCALOU SOZINHO, senhoras e senhores! Réplicas subindo na tela sem um comando sequer — o ciclo se fechou: você declara o alvo, a mureta faz a corrida. Última curva completada. Agora é volta de desaceleração, aceno pra arquibancada — e o pódio logo ali.
Etapa 09 labs online
Pratique de graça em clusters reais
Volta de desaceleração: o motor esfria, mas o campeonato continua — e todo piloto sabe que temporada se constrói no treino. Aqui está o calendário de testes.
Pense nisto como a escada de qualquer piloto: simulador público, kart, F4, e só então o carro de verdade. Estas plataformas dão terminal com Kubernetes real direto no navegador — comece pelas 100% gratuitas.
Killercoda
100% grátisCenários interativos de Kubernetes direto no navegador: você recebe um terminal com cluster real e um roteiro guiado. Sucessor do Katacoda.
Bom para: Praticar cada etapa deste guia sem instalar nada. Comece por aqui.
killercoda.com/kubernetesPlay with Kubernetes
100% grátisCluster Kubernetes real e temporário (sessões de 4 horas) no navegador, mantido pela Docker. Você monta o cluster na mão com kubeadm.
Bom para: Testar comandos kubectl livremente e entender a montagem de um cluster.
labs.play-with-k8s.comKube by Example
100% grátisTutoriais e exemplos curtos mantidos pela Red Hat: um conceito por página (Pods, Services, Deployments...), com exemplos direto ao ponto.
Bom para: Revisar um conceito específico rapidamente, como uma segunda explicação.
kubebyexample.comIntroduction to Kubernetes (LFS158)
100% grátisCurso oficial gratuito da Linux Foundation (quem mantém o K8s), disponível também no edX. Base teórica sólida com certificado de participação.
Bom para: Consolidar a teoria com o material oficial depois de fechar este guia.
training.linuxfoundation.orgKubernetes the Hard Way
100% grátisO lendário roteiro do Kelsey Hightower: montar um cluster peça por peça, na unha, sem instaladores. É o "monte o carro parafuso por parafuso" — quem faz, nunca mais olha a garagem do mesmo jeito.
Bom para: Nível avançado — quando quiser entender o que o Minikube esconde de você.
github.com/kelseyhightowerKodeKloud
Free tier + pagoLabs guiados estilo desafio: "esse Pod não sobe, descubra por quê". Alguns labs são gratuitos; o catálogo completo (e os simulados CKA/CKAD) é pago.
Bom para: Troubleshooting realista, o mais próximo de uma entrevista técnica.
kodekloud.comiximiuz Labs
Free tier + pagoPlaygrounds de containers e Kubernetes no navegador com desafios práticos. Vários playgrounds e desafios liberados no plano gratuito.
Bom para: Experimentos mais profundos: rede, imagens, internals de containers.
labs.iximiuz.comRoteiro sugerido: a cada etapa deste guia, abra o Killercoda e repita os comandos no cenário equivalente (Pods, Deployments, Volumes...). Fechou as 8 etapas? Vá pro KodeKloud encarar desafios de troubleshooting.