[{"data":1,"prerenderedAt":2430},["ShallowReactive",2],{"article-\u002Finfraestrutura\u002Fkubernetes-para-iniciantes":3},{"id":4,"title":5,"author":6,"body":7,"category":2415,"date":2416,"description":2417,"extension":2418,"keywords":2419,"meta":2424,"navigation":1584,"path":2425,"seo":2426,"slug":2427,"stem":2428,"updated":2416,"__hash__":2429},"content\u002Finfraestrutura\u002Fkubernetes-para-iniciantes.md","Kubernetes para iniciantes: guia 2026","Inicialize Tec",{"type":8,"value":9,"toc":2371},"minimark",[10,15,80,84,88,91,97,113,116,123,128,131,168,172,175,181,187,190,194,294,305,323,382,386,389,406,409,415,447,451,523,527,534,542,546,549,575,579,582,602,608,612,618,625,631,636,640,660,808,817,821,827,833,838,1210,1214,1217,1239,1245,1249,1252,1262,1267,1271,1339,1450,1454,1460,1480,1484,1487,1491,1536,1540,1551,1626,1630,1679,1683,1690,1722,1726,1729,1787,1790,1811,1815,1822,1827,2005,2008,2020,2024,2079,2082,2086,2094,2102,2116,2120,2125,2138,2142,2147,2160,2164,2169,2178,2254,2258,2263,2272,2353,2356,2367],[11,12,14],"h2",{"id":13},"índice","Índice",[16,17,18,26,32,38,44,50,56,62,68,74],"ol",{},[19,20,21],"li",{},[22,23,25],"a",{"href":24},"#o-que-e","O que é Kubernetes, afinal?",[19,27,28],{},[22,29,31],{"href":30},"#containers","Containers: a base de tudo",[19,33,34],{},[22,35,37],{"href":36},"#por-que-orquestracao","Por que você precisa de orquestração",[19,39,40],{},[22,41,43],{"href":42},"#anatomia","Anatomia de um cluster",[19,45,46],{},[22,47,49],{"href":48},"#pods","Pods: a menor unidade",[19,51,52],{},[22,53,55],{"href":54},"#deployments","Deployments: garantir o estado desejado",[19,57,58],{},[22,59,61],{"href":60},"#services","Services: como encontrar seus pods",[19,63,64],{},[22,65,67],{"href":66},"#primeira-app","Subindo sua primeira aplicação",[19,69,70],{},[22,71,73],{"href":72},"#auto-scaling","Auto-scaling: crescer sob demanda",[19,75,76],{},[22,77,79],{"href":78},"#erros-comuns","Erros comuns",[11,81,83],{"id":82},"o-que-é-kubernetes-afinal-o-que-e","O que é Kubernetes, afinal? {#o-que-e}",[85,86,87],"p",{},"Imagine um porto de navios. Chegam milhares de contêineres por dia — cada um\ncom um conteúdo diferente, um destino diferente, um peso diferente. Sem alguém\ncoordenando, vira caos: contêineres empilhados no lugar errado, guindastes\nociosos enquanto outros estão sobrecarregados, cargas perecíveis estragando\nenquanto esperam.",[85,89,90],{},"O gerente do porto é quem organiza tudo: decide qual contêiner vai para qual\nnavio, redireciona quando um guindaste quebra, escala mais caminhões no horário\nde pico. Ele não carrega os contêineres — ele orquestra quem carrega.",[85,92,93],{},[94,95,96],"strong",{},"Kubernetes é esse gerente de porto, mas para software.",[85,98,99,100,104,105,108,109,112],{},"Kubernetes (pronuncia-se ",[101,102,103],"em",{},"koo-ber-NET-ees",") é uma plataforma de código aberto\nque automatiza a implantação, o escalonamento e a operação de aplicações em\n",[94,106,107],{},"containers",". Ele foi criado pelo Google em 2014, baseado em um sistema\ninterno chamado Borg que rodava os serviços do Google há mais de uma década.\nHoje é mantido pela ",[94,110,111],{},"CNCF"," (Cloud Native Computing Foundation — uma fundação\nque cuida de projetos de software \"cloud native\", ou seja, pensados para rodar\nna nuvem desde o início).",[85,114,115],{},"A palavra Kubernetes vem do grego e significa \"timoneiro\" — quem governa o\nleme do navio. Por isso o logo é uma roda de navio.",[85,117,118,119,122],{},"A abreviação ",[94,120,121],{},"k8s"," é comum: o \"8\" representa as oito letras entre o \"k\"\ninicial e o \"s\" final (k-ubernete-s).",[124,125,127],"h3",{"id":126},"o-que-kubernetes-não-é","O que Kubernetes NÃO é",[85,129,130],{},"É importante alinhar expectativas desde já:",[132,133,134,152,162],"ul",{},[19,135,136,139,140,143,144,147,148,151],{},[94,137,138],{},"Não é um sistema de containers",": ele ",[101,141,142],{},"gerencia"," containers, mas quem os\ncria e executa é um \"container runtime\" (motor de execução) como\n",[94,145,146],{},"containerd"," ou ",[94,149,150],{},"Docker",". Kubernetes é a camada acima.",[19,153,154,157,158,161],{},[94,155,156],{},"Não é uma nuvem",": Kubernetes roda ",[101,159,160],{},"sobre"," uma nuvem (AWS, Google Cloud,\nAzure) ou até em seus próprios servidores. Ele não substitui a infraestrutura\n— ele a orquestra.",[19,163,164,167],{},[94,165,166],{},"Não é mágica",": ele automatiza muito, mas exige configuração, conhecimento\ne manutenção. Não é \"instalar e esquecer\".",[11,169,171],{"id":170},"containers-a-base-de-tudo-containers","Containers: a base de tudo {#containers}",[85,173,174],{},"Antes de entender Kubernetes, você precisa entender containers.",[85,176,177,180],{},[94,178,179],{},"Container"," é uma forma de empacotar uma aplicação junto com tudo o que ela\nprecisa para rodar — código, bibliotecas, configurações, variáveis de ambiente\n— em uma unidade portátil e isolada.",[85,182,183,186],{},[94,184,185],{},"Analogia",": pense em um container de navio. Não importa o que tem dentro\n(eletrodomésticos, roupas, comida), o container tem um formato padrão. O navio\nnão precisa saber o que tem dentro — ele só precisa saber as dimensões. Qualquer\nnavio carrega qualquer container.",[85,188,189],{},"Da mesma forma, um container de software roda em qualquer servidor que tenha\num container runtime. O servidor não precisa ter as bibliotecas da sua\naplicação instaladas — tudo vem dentro do container.",[124,191,193],{"id":192},"container-vs-máquina-virtual","Container vs máquina virtual",[195,196,197,212],"table",{},[198,199,200],"thead",{},[201,202,203,207,210],"tr",{},[204,205,206],"th",{},"Aspecto",[204,208,209],{},"Máquina Virtual (VM)",[204,211,179],{},[213,214,215,229,242,255,268,281],"tbody",{},[201,216,217,223,226],{},[218,219,220],"td",{},[94,221,222],{},"O que inclui",[218,224,225],{},"Sistema operacional completo + app",[218,227,228],{},"Só a app e dependências",[201,230,231,236,239],{},[218,232,233],{},[94,234,235],{},"Tamanho",[218,237,238],{},"Gigabytes",[218,240,241],{},"Megabytes",[201,243,244,249,252],{},[218,245,246],{},[94,247,248],{},"Tempo de inicialização",[218,250,251],{},"Minutos",[218,253,254],{},"Segundos",[201,256,257,262,265],{},[218,258,259],{},[94,260,261],{},"Isolamento",[218,263,264],{},"Total (cada VM tem seu SO)",[218,266,267],{},"Compartilha o kernel do host",[201,269,270,275,278],{},[218,271,272],{},[94,273,274],{},"Densidade",[218,276,277],{},"Poucas VMs por servidor",[218,279,280],{},"Centenas de containers por servidor",[201,282,283,288,291],{},[218,284,285],{},[94,286,287],{},"Quando usar",[218,289,290],{},"Isolamento máximo, SO diferente",[218,292,293],{},"Aplicações na mesma linguagem\u002FSO",[85,295,296,297,300,301,304],{},"A diferença fundamental: uma VM virtualiza o ",[94,298,299],{},"hardware"," (cada VM roda um\nsistema operacional completo), enquanto um container virtualiza o ",[94,302,303],{},"sistema\noperacional"," (vários containers compartilham o mesmo kernel, o núcleo do SO).",[85,306,307,309,310,314,315,318,319,322],{},[94,308,150],{}," é o container runtime mais conhecido. Você escreve um\n",[311,312,313],"code",{},"Dockerfile"," (receita de como montar o container), executa ",[311,316,317],{},"docker build"," e\nobtém uma ",[94,320,321],{},"imagem"," — um pacote imutável. Ao executar essa imagem, você tem\num container rodando.",[324,325,330],"pre",{"className":326,"code":327,"language":328,"meta":329,"style":329},"language-dockerfile shiki shiki-themes github-light github-dark","# Dockerfile: receita para criar a imagem da aplicação\nFROM node:20-alpine          # Começa com uma imagem base (Node.js leve)\nWORKDIR \u002Fapp                 # Define o diretório de trabalho dentro do container\nCOPY package.json .          # Copia o arquivo de dependências\nRUN npm install              # Instala as dependências (roda só no build)\nCOPY . .                     # Copia o resto do código\nEXPOSE 3000                  # Documenta que a app usa a porta 3000\nCMD [\"node\", \"server.js\"]    # Comando executado quando o container inicia\n","dockerfile","",[311,331,332,340,346,352,358,364,370,376],{"__ignoreMap":329},[333,334,337],"span",{"class":335,"line":336},"line",1,[333,338,339],{},"# Dockerfile: receita para criar a imagem da aplicação\n",[333,341,343],{"class":335,"line":342},2,[333,344,345],{},"FROM node:20-alpine          # Começa com uma imagem base (Node.js leve)\n",[333,347,349],{"class":335,"line":348},3,[333,350,351],{},"WORKDIR \u002Fapp                 # Define o diretório de trabalho dentro do container\n",[333,353,355],{"class":335,"line":354},4,[333,356,357],{},"COPY package.json .          # Copia o arquivo de dependências\n",[333,359,361],{"class":335,"line":360},5,[333,362,363],{},"RUN npm install              # Instala as dependências (roda só no build)\n",[333,365,367],{"class":335,"line":366},6,[333,368,369],{},"COPY . .                     # Copia o resto do código\n",[333,371,373],{"class":335,"line":372},7,[333,374,375],{},"EXPOSE 3000                  # Documenta que a app usa a porta 3000\n",[333,377,379],{"class":335,"line":378},8,[333,380,381],{},"CMD [\"node\", \"server.js\"]    # Comando executado quando o container inicia\n",[11,383,385],{"id":384},"por-que-você-precisa-de-orquestração-por-que-orquestracao","Por que você precisa de orquestração {#por-que-orquestracao}",[85,387,388],{},"Imagine que sua aplicação faz sucesso. Você tinha 1 container rodando, agora\nprecisa de 10. Sem orquestração, você faz tudo manualmente:",[16,390,391,394,397,400,403],{},[19,392,393],{},"Em quais servidores colocar cada container?",[19,395,396],{},"Se um servidor cair, como mover os containers para outro?",[19,398,399],{},"Se o tráfego crescer às 14h, como adicionar containers automaticamente?",[19,401,402],{},"Se um container travar, quem reinicia?",[19,404,405],{},"Como atualizar a versão sem derrubar o serviço?",[85,407,408],{},"Fazer isso manualmente com 10 containers já é trabalhoso. Com 100, é\nimpossível. Com 1.000, é uma pesadelo.",[85,410,411,414],{},[94,412,413],{},"É aqui que entra o orquestrador."," Kubernetes resolve todos esses problemas\nautomaticamente:",[132,416,417,423,429,435,441],{},[19,418,419,422],{},[94,420,421],{},"Escalonamento",": adicionar ou remover containers conforme a demanda",[19,424,425,428],{},[94,426,427],{},"Self-healing"," (auto-cura): reiniciar containers que travaram",[19,430,431,434],{},[94,432,433],{},"Balanceamento de carga",": distribuir tráfego entre os containers",[19,436,437,440],{},[94,438,439],{},"Rolling updates",": atualizar a versão sem downtime (tempo fora do ar)",[19,442,443,446],{},[94,444,445],{},"Service discovery",": containers se encontram automaticamente, sem IPs fixos",[124,448,450],{"id":449},"sem-kubernetes-vs-com-kubernetes","Sem Kubernetes vs com Kubernetes",[195,452,453,466],{},[198,454,455],{},[201,456,457,460,463],{},[204,458,459],{},"Situação",[204,461,462],{},"Sem orquestração",[204,464,465],{},"Com Kubernetes",[213,467,468,479,490,501,512],{},[201,469,470,473,476],{},[218,471,472],{},"Container trava",[218,474,475],{},"Você reinicia manualmente",[218,477,478],{},"Reinicia sozinho em segundos",[201,480,481,484,487],{},[218,482,483],{},"Tráfego aumenta",[218,485,486],{},"Você adiciona servidores manualmente",[218,488,489],{},"Auto-scaling adiciona pods",[201,491,492,495,498],{},[218,493,494],{},"Servidor cai",[218,496,497],{},"Containers perdidos, app fora do ar",[218,499,500],{},"Pods realocados para outro servidor",[201,502,503,506,509],{},[218,504,505],{},"Deploy de nova versão",[218,507,508],{},"Derruba a app, sobe a nova",[218,510,511],{},"Atualiza gradualmente, sem downtime",[201,513,514,517,520],{},[218,515,516],{},"Descoberta de serviços",[218,518,519],{},"Configura IPs manualmente",[218,521,522],{},"DNS interno resolve automaticamente",[11,524,526],{"id":525},"anatomia-de-um-cluster-anatomia","Anatomia de um cluster {#anatomia}",[85,528,529,530,533],{},"Um ",[94,531,532],{},"cluster"," Kubernetes é um conjunto de máquinas que rodam containers\ngerenciados pelo Kubernetes. Ele tem duas partes principais:",[324,535,540],{"className":536,"code":538,"language":539},[537],"language-text","┌─────────────────────────────────────────────────────┐\n│                   CLUSTER K8S                        │\n│                                                      │\n│  ┌─────────────────┐   ┌──────────────────────┐     │\n│  │  CONTROL PLANE  │   │    WORKER NODES      │     │\n│  │  (o cérebro)    │   │    (os músculos)     │     │\n│  │                 │   │                      │     │\n│  │  • API Server   │   │  Node 1  Node 2      │     │\n│  │  • Scheduler    │   │  [pods]  [pods]      │     │\n│  │  • etcd         │   │  Node 3              │     │\n│  │  • Controller   │   │  [pods]              │     │\n│  └────────┬────────┘   └──────────▲───────────┘     │\n│           │                       │                  │\n│           └─────── controla ──────┘                  │\n└─────────────────────────────────────────────────────┘\n","text",[311,541,538],{"__ignoreMap":329},[124,543,545],{"id":544},"control-plane-plano-de-controle-o-cérebro","Control Plane (plano de controle) — o cérebro",[85,547,548],{},"É quem toma as decisões. Não roda suas aplicações — apenas gerencia o cluster.",[132,550,551,557,563,569],{},[19,552,553,556],{},[94,554,555],{},"API Server",": a porta de entrada. Tudo o que você faz (criar pods, escalar,\natualizar) passa pelo API Server. É como a recepção de um prédio.",[19,558,559,562],{},[94,560,561],{},"Scheduler"," (agendador): decide em qual worker node cada pod vai rodar,\nbaseado em recursos disponíveis (CPU, memória).",[19,564,565,568],{},[94,566,567],{},"etcd",": um banco de dados chave-valor que guarda todo o estado do cluster.\nÉ a \"memória\" do Kubernetes — sem ele, o cluster esquece tudo.",[19,570,571,574],{},[94,572,573],{},"Controller Manager",": garante que o estado real corresponde ao estado\ndesejado. Se você pediu 3 pods e só tem 2, ele cria o terceiro.",[124,576,578],{"id":577},"worker-nodes-nós-de-trabalho-os-músculos","Worker Nodes (nós de trabalho) — os músculos",[85,580,581],{},"São as máquinas que realmente rodam suas aplicações. Cada worker node tem:",[132,583,584,590,596],{},[19,585,586,589],{},[94,587,588],{},"kubelet",": o agente que recebe ordens do control plane e garante que os\npods estão rodando conforme o esperado.",[19,591,592,595],{},[94,593,594],{},"kube-proxy",": responsável pelo roredamento de rede entre os pods.",[19,597,598,601],{},[94,599,600],{},"Container runtime",": o motor que executa os containers (containerd, Docker,\nCRI-O).",[85,603,604,607],{},[94,605,606],{},"Analogia final",": o control plane é o gerente do porto (decide, planeja,\nmonitora). Os worker nodes são os guindastes e caminhões (executam o trabalho\npesado).",[11,609,611],{"id":610},"pods-a-menor-unidade-pods","Pods: a menor unidade {#pods}",[85,613,614,617],{},[94,615,616],{},"Pod"," é a menor unidade gerenciável no Kubernetes. E é o conceito mais\nimportante para entender.",[85,619,620,621,624],{},"Um pod pode conter um ou mais containers, mas o caso mais comum é ",[94,622,623],{},"um pod =\num container",". Os containers dentro do mesmo pod compartilham rede e\narmazenamento — são \"amigos íntimos\" que precisam estar sempre juntos.",[85,626,627,630],{},[94,628,629],{},"Por que pods e não containers direto?"," Porque Kubernetes precisa gerenciar\nalgo maior que um container. Um pod pode ter, além do container principal,\num \"sidecar\" — um container auxiliar. Por exemplo: um container com sua\naplicação + um container que coleta logs e envia para um servidor central.",[85,632,633,635],{},[94,634,185],{},": se o container é um peixe, o pod é o aquário. Você pode ter\nvários peixes no mesmo aquário (containers no mesmo pod), compartilhando a\nmesma água (rede) e o mesmo fundo (armazenamento). Kubernetes gerencia\naquários, não peixes diretamente.",[124,637,639],{"id":638},"características-dos-pods","Características dos pods",[132,641,642,648,654],{},[19,643,644,647],{},[94,645,646],{},"Efêmeros",": pods nascem e morrem. Se um pod morre, o Kubernetes cria outro\n— mas com um IP novo. Por isso você nunca deve depender do IP de um pod.",[19,649,650,653],{},[94,651,652],{},"Não se atualizam",": para atualizar a versão da sua app, o Kubernetes mata o\npod antigo e cria um novo com a nova imagem.",[19,655,656,659],{},[94,657,658],{},"Escalam em número",": para suportar mais tráfego, você cria mais réplicas\ndo mesmo pod.",[324,661,665],{"className":662,"code":663,"language":664,"meta":329,"style":329},"language-yaml shiki shiki-themes github-light github-dark","# pod-simples.yaml — exemplo de um pod básico\napiVersion: v1\nkind: Pod\nmetadata:\n  name: minha-app        # Nome do pod\n  labels:\n    app: minha-app       # Label (etiqueta) para identificar o pod depois\nspec:\n  containers:\n    - name: minha-app    # Nome do container dentro do pod\n      image: nginx:latest  # Imagem que vai rodar (nginx neste exemplo)\n      ports:\n        - containerPort: 80  # Porta que o container expõe\n","yaml",[311,666,667,673,687,697,705,718,725,737,744,752,768,782,790],{"__ignoreMap":329},[333,668,669],{"class":335,"line":336},[333,670,672],{"class":671},"sJ8bj","# pod-simples.yaml — exemplo de um pod básico\n",[333,674,675,679,683],{"class":335,"line":342},[333,676,678],{"class":677},"s9eBZ","apiVersion",[333,680,682],{"class":681},"sVt8B",": ",[333,684,686],{"class":685},"sZZnC","v1\n",[333,688,689,692,694],{"class":335,"line":348},[333,690,691],{"class":677},"kind",[333,693,682],{"class":681},[333,695,696],{"class":685},"Pod\n",[333,698,699,702],{"class":335,"line":354},[333,700,701],{"class":677},"metadata",[333,703,704],{"class":681},":\n",[333,706,707,710,712,715],{"class":335,"line":360},[333,708,709],{"class":677},"  name",[333,711,682],{"class":681},[333,713,714],{"class":685},"minha-app",[333,716,717],{"class":671},"        # Nome do pod\n",[333,719,720,723],{"class":335,"line":366},[333,721,722],{"class":677},"  labels",[333,724,704],{"class":681},[333,726,727,730,732,734],{"class":335,"line":372},[333,728,729],{"class":677},"    app",[333,731,682],{"class":681},[333,733,714],{"class":685},[333,735,736],{"class":671},"       # Label (etiqueta) para identificar o pod depois\n",[333,738,739,742],{"class":335,"line":378},[333,740,741],{"class":677},"spec",[333,743,704],{"class":681},[333,745,747,750],{"class":335,"line":746},9,[333,748,749],{"class":677},"  containers",[333,751,704],{"class":681},[333,753,755,758,761,763,765],{"class":335,"line":754},10,[333,756,757],{"class":681},"    - ",[333,759,760],{"class":677},"name",[333,762,682],{"class":681},[333,764,714],{"class":685},[333,766,767],{"class":671},"    # Nome do container dentro do pod\n",[333,769,771,774,776,779],{"class":335,"line":770},11,[333,772,773],{"class":677},"      image",[333,775,682],{"class":681},[333,777,778],{"class":685},"nginx:latest",[333,780,781],{"class":671},"  # Imagem que vai rodar (nginx neste exemplo)\n",[333,783,785,788],{"class":335,"line":784},12,[333,786,787],{"class":677},"      ports",[333,789,704],{"class":681},[333,791,793,796,799,801,805],{"class":335,"line":792},13,[333,794,795],{"class":681},"        - ",[333,797,798],{"class":677},"containerPort",[333,800,682],{"class":681},[333,802,804],{"class":803},"sj4cs","80",[333,806,807],{"class":671},"  # Porta que o container expõe\n",[809,810,811],"blockquote",{},[85,812,813,816],{},[94,814,815],{},"Atenção",": na prática, você quase nunca cria pods diretamente. Você cria\nDeployments (próxima seção), que gerenciam os pods para você. Criar pods\n\"soltos\" é como construir uma casa sem alicerce — funciona, mas não sobrevive\na uma tempestade.",[11,818,820],{"id":819},"deployments-garantir-o-estado-desejado-deployments","Deployments: garantir o estado desejado {#deployments}",[85,822,823,826],{},[94,824,825],{},"Deployment"," é o objeto do Kubernetes que garante que um número de réplicas\nde um pod esteja sempre rodando. É a forma correta de rodar aplicações no\nKubernetes.",[85,828,829,832],{},[94,830,831],{},"Como funciona",": você diz ao Kubernetes \"quero 3 pods da minha aplicação\nrodando\". O Deployment cria esses 3 pods. Se um morrer, ele cria outro. Se\nvocê quiser atualizar a versão, ele substitui gradualmente os pods antigos por\npods novos. Se você quiser escalar para 10, ele cria mais 7.",[85,834,835,837],{},[94,836,185],{},": imagine um gerente de uma fábrica que recebe a ordem \"mantenha\nsempre 3 máquinas de embalagem funcionando\". Se uma quebra, ele liga uma\nreserva. Se você pede para aumentar para 10, ele liga mais máquinas. Ele não\nembala nada — ele garante que as máquinas estejam operando.",[324,839,841],{"className":662,"code":840,"language":664,"meta":329,"style":329},"# deployment.yaml — a forma correta de rodar sua aplicação\napiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: minha-app\nspec:\n  replicas: 3              # Quantos pods queremos rodando simultaneamente\n  selector:\n    matchLabels:\n      app: minha-app       # Quais pods este Deployment gerencia (por label)\n  template:                # O \"molde\" para criar cada pod\n    metadata:\n      labels:\n        app: minha-app     # Label que casa com o selector acima\n    spec:\n      containers:\n        - name: minha-app\n          image: minha-app:v1.0.0  # Versão da imagem (use tags, não :latest)\n          ports:\n            - containerPort: 3000\n          resources:        # Importante: defina limites de recursos!\n            requests:       # O mínimo que o pod precisa para ser agendado\n              memory: \"128Mi\"\n              cpu: \"250m\"   # 250m = 250 milicores = 0.25 de um núcleo\n            limits:         # O máximo que o pod pode consumir\n              memory: \"256Mi\"\n              cpu: \"500m\"\n          livenessProbe:    # Verifica se a app está viva (senão, reinicia)\n            httpGet:\n              path: \u002Fhealth\n              port: 3000\n            initialDelaySeconds: 10  # Espera 10s antes de começar a checar\n          readinessProbe:   # Verifica se a app está pronta para receber tráfego\n            httpGet:\n              path: \u002Fready\n              port: 3000\n            initialDelaySeconds: 5\n",[311,842,843,848,857,866,872,881,887,900,907,914,926,937,944,951,964,972,980,991,1005,1013,1026,1038,1050,1061,1075,1087,1097,1107,1119,1127,1138,1148,1162,1174,1181,1191,1200],{"__ignoreMap":329},[333,844,845],{"class":335,"line":336},[333,846,847],{"class":671},"# deployment.yaml — a forma correta de rodar sua aplicação\n",[333,849,850,852,854],{"class":335,"line":342},[333,851,678],{"class":677},[333,853,682],{"class":681},[333,855,856],{"class":685},"apps\u002Fv1\n",[333,858,859,861,863],{"class":335,"line":348},[333,860,691],{"class":677},[333,862,682],{"class":681},[333,864,865],{"class":685},"Deployment\n",[333,867,868,870],{"class":335,"line":354},[333,869,701],{"class":677},[333,871,704],{"class":681},[333,873,874,876,878],{"class":335,"line":360},[333,875,709],{"class":677},[333,877,682],{"class":681},[333,879,880],{"class":685},"minha-app\n",[333,882,883,885],{"class":335,"line":366},[333,884,741],{"class":677},[333,886,704],{"class":681},[333,888,889,892,894,897],{"class":335,"line":372},[333,890,891],{"class":677},"  replicas",[333,893,682],{"class":681},[333,895,896],{"class":803},"3",[333,898,899],{"class":671},"              # Quantos pods queremos rodando simultaneamente\n",[333,901,902,905],{"class":335,"line":378},[333,903,904],{"class":677},"  selector",[333,906,704],{"class":681},[333,908,909,912],{"class":335,"line":746},[333,910,911],{"class":677},"    matchLabels",[333,913,704],{"class":681},[333,915,916,919,921,923],{"class":335,"line":754},[333,917,918],{"class":677},"      app",[333,920,682],{"class":681},[333,922,714],{"class":685},[333,924,925],{"class":671},"       # Quais pods este Deployment gerencia (por label)\n",[333,927,928,931,934],{"class":335,"line":770},[333,929,930],{"class":677},"  template",[333,932,933],{"class":681},":                ",[333,935,936],{"class":671},"# O \"molde\" para criar cada pod\n",[333,938,939,942],{"class":335,"line":784},[333,940,941],{"class":677},"    metadata",[333,943,704],{"class":681},[333,945,946,949],{"class":335,"line":792},[333,947,948],{"class":677},"      labels",[333,950,704],{"class":681},[333,952,954,957,959,961],{"class":335,"line":953},14,[333,955,956],{"class":677},"        app",[333,958,682],{"class":681},[333,960,714],{"class":685},[333,962,963],{"class":671},"     # Label que casa com o selector acima\n",[333,965,967,970],{"class":335,"line":966},15,[333,968,969],{"class":677},"    spec",[333,971,704],{"class":681},[333,973,975,978],{"class":335,"line":974},16,[333,976,977],{"class":677},"      containers",[333,979,704],{"class":681},[333,981,983,985,987,989],{"class":335,"line":982},17,[333,984,795],{"class":681},[333,986,760],{"class":677},[333,988,682],{"class":681},[333,990,880],{"class":685},[333,992,994,997,999,1002],{"class":335,"line":993},18,[333,995,996],{"class":677},"          image",[333,998,682],{"class":681},[333,1000,1001],{"class":685},"minha-app:v1.0.0",[333,1003,1004],{"class":671},"  # Versão da imagem (use tags, não :latest)\n",[333,1006,1008,1011],{"class":335,"line":1007},19,[333,1009,1010],{"class":677},"          ports",[333,1012,704],{"class":681},[333,1014,1016,1019,1021,1023],{"class":335,"line":1015},20,[333,1017,1018],{"class":681},"            - ",[333,1020,798],{"class":677},[333,1022,682],{"class":681},[333,1024,1025],{"class":803},"3000\n",[333,1027,1029,1032,1035],{"class":335,"line":1028},21,[333,1030,1031],{"class":677},"          resources",[333,1033,1034],{"class":681},":        ",[333,1036,1037],{"class":671},"# Importante: defina limites de recursos!\n",[333,1039,1041,1044,1047],{"class":335,"line":1040},22,[333,1042,1043],{"class":677},"            requests",[333,1045,1046],{"class":681},":       ",[333,1048,1049],{"class":671},"# O mínimo que o pod precisa para ser agendado\n",[333,1051,1053,1056,1058],{"class":335,"line":1052},23,[333,1054,1055],{"class":677},"              memory",[333,1057,682],{"class":681},[333,1059,1060],{"class":685},"\"128Mi\"\n",[333,1062,1064,1067,1069,1072],{"class":335,"line":1063},24,[333,1065,1066],{"class":677},"              cpu",[333,1068,682],{"class":681},[333,1070,1071],{"class":685},"\"250m\"",[333,1073,1074],{"class":671},"   # 250m = 250 milicores = 0.25 de um núcleo\n",[333,1076,1078,1081,1084],{"class":335,"line":1077},25,[333,1079,1080],{"class":677},"            limits",[333,1082,1083],{"class":681},":         ",[333,1085,1086],{"class":671},"# O máximo que o pod pode consumir\n",[333,1088,1090,1092,1094],{"class":335,"line":1089},26,[333,1091,1055],{"class":677},[333,1093,682],{"class":681},[333,1095,1096],{"class":685},"\"256Mi\"\n",[333,1098,1100,1102,1104],{"class":335,"line":1099},27,[333,1101,1066],{"class":677},[333,1103,682],{"class":681},[333,1105,1106],{"class":685},"\"500m\"\n",[333,1108,1110,1113,1116],{"class":335,"line":1109},28,[333,1111,1112],{"class":677},"          livenessProbe",[333,1114,1115],{"class":681},":    ",[333,1117,1118],{"class":671},"# Verifica se a app está viva (senão, reinicia)\n",[333,1120,1122,1125],{"class":335,"line":1121},29,[333,1123,1124],{"class":677},"            httpGet",[333,1126,704],{"class":681},[333,1128,1130,1133,1135],{"class":335,"line":1129},30,[333,1131,1132],{"class":677},"              path",[333,1134,682],{"class":681},[333,1136,1137],{"class":685},"\u002Fhealth\n",[333,1139,1141,1144,1146],{"class":335,"line":1140},31,[333,1142,1143],{"class":677},"              port",[333,1145,682],{"class":681},[333,1147,1025],{"class":803},[333,1149,1151,1154,1156,1159],{"class":335,"line":1150},32,[333,1152,1153],{"class":677},"            initialDelaySeconds",[333,1155,682],{"class":681},[333,1157,1158],{"class":803},"10",[333,1160,1161],{"class":671},"  # Espera 10s antes de começar a checar\n",[333,1163,1165,1168,1171],{"class":335,"line":1164},33,[333,1166,1167],{"class":677},"          readinessProbe",[333,1169,1170],{"class":681},":   ",[333,1172,1173],{"class":671},"# Verifica se a app está pronta para receber tráfego\n",[333,1175,1177,1179],{"class":335,"line":1176},34,[333,1178,1124],{"class":677},[333,1180,704],{"class":681},[333,1182,1184,1186,1188],{"class":335,"line":1183},35,[333,1185,1132],{"class":677},[333,1187,682],{"class":681},[333,1189,1190],{"class":685},"\u002Fready\n",[333,1192,1194,1196,1198],{"class":335,"line":1193},36,[333,1195,1143],{"class":677},[333,1197,682],{"class":681},[333,1199,1025],{"class":803},[333,1201,1203,1205,1207],{"class":335,"line":1202},37,[333,1204,1153],{"class":677},[333,1206,682],{"class":681},[333,1208,1209],{"class":803},"5\n",[124,1211,1213],{"id":1212},"liveness-vs-readiness-a-diferença-importa","Liveness vs Readiness: a diferença importa",[85,1215,1216],{},"Esses dois termos confundem iniciantes, mas a diferença é crucial:",[132,1218,1219,1229],{},[19,1220,1221,1224,1225,1228],{},[94,1222,1223],{},"Liveness probe"," (sonda de vitalidade): \"A aplicação está viva?\" Se falhar,\no Kubernetes ",[94,1226,1227],{},"reinicia"," o pod. Como um médico checando os sinais vitais —\nse o paciente parou de respirar, chama o reanimador.",[19,1230,1231,1234,1235,1238],{},[94,1232,1233],{},"Readiness probe"," (sonda de prontidão): \"A aplicação está pronta para\nreceber tráfego?\" Se falhar, o Kubernetes ",[94,1236,1237],{},"remove o pod do balanceamento de\ncarga"," — não reinicia, só para de enviar requisições. Como um garçom que\nnão anota pedidos de uma mesa onde o chef ainda não chegou.",[85,1240,1241,1244],{},[94,1242,1243],{},"Cenário",": sua app demora 30 segundos para iniciar (precisa carregar dados\nem memória). Sem readiness probe, o Kubernetes já envia tráfego aos 5 segundos\n— a app quebra, o liveness falha, o pod reinicia, e entra em um loop infinito.\nCom readiness probe configurada corretamente, o Kubernetes espera a app ficar\npronta antes de enviar tráfego.",[11,1246,1248],{"id":1247},"services-como-encontrar-seus-pods-services","Services: como encontrar seus pods {#services}",[85,1250,1251],{},"Lembra que pods são efêmeros e mudam de IP? Então como outras aplicações\nencontram o seu pod se o IP muda toda hora?",[85,1253,1254,1257,1258,1261],{},[94,1255,1256],{},"Service"," é a resposta. Um Service é um endereço fixo (IP + DNS) que funciona\ncomo uma porta de entrada para um conjunto de pods. Ele faz ",[94,1259,1260],{},"load balancing","\n(distribuição de carga) entre os pods que casam com seu seletor.",[85,1263,1264,1266],{},[94,1265,185],{},": pense no Service como o número do telefone da recepção de um\nhospital. Os médicos (pods) entram e saem, trocam de plantão, mas o número da\nrecepção (Service) é sempre o mesmo. Você liga para a recepção e ela direciona\npara um médico disponível.",[124,1268,1270],{"id":1269},"tipos-de-service","Tipos de Service",[195,1272,1273,1285],{},[198,1274,1275],{},[201,1276,1277,1280,1283],{},[204,1278,1279],{},"Tipo",[204,1281,1282],{},"Acessível por",[204,1284,287],{},[213,1286,1287,1300,1313,1326],{},[201,1288,1289,1294,1297],{},[218,1290,1291],{},[94,1292,1293],{},"ClusterIP",[218,1295,1296],{},"Só dentro do cluster",[218,1298,1299],{},"Comunicação interna entre serviços",[201,1301,1302,1307,1310],{},[218,1303,1304],{},[94,1305,1306],{},"NodePort",[218,1308,1309],{},"De fora do cluster (porta alta)",[218,1311,1312],{},"Testes, acesso externo simples",[201,1314,1315,1320,1323],{},[218,1316,1317],{},[94,1318,1319],{},"LoadBalancer",[218,1321,1322],{},"Internet (cria um LB da nuvem)",[218,1324,1325],{},"Expor para a internet em produção",[201,1327,1328,1333,1336],{},[218,1329,1330],{},[94,1331,1332],{},"Ingress",[218,1334,1335],{},"Internet (HTTP\u002FHTTPS com domínio)",[218,1337,1338],{},"Múltiplas apps no mesmo domínio",[324,1340,1342],{"className":662,"code":1341,"language":664,"meta":329,"style":329},"# service.yaml — expõe a aplicação dentro do cluster\napiVersion: v1\nkind: Service\nmetadata:\n  name: minha-app-service\nspec:\n  type: ClusterIP         # Endereço acessível só dentro do cluster\n  selector:\n    app: minha-app        # Roteia tráfego para pods com este label\n  ports:\n    - port: 80            # Porta que o Service escuta\n      targetPort: 3000    # Porta do pod para onde o tráfego vai\n",[311,1343,1344,1349,1357,1366,1372,1381,1387,1399,1405,1416,1423,1437],{"__ignoreMap":329},[333,1345,1346],{"class":335,"line":336},[333,1347,1348],{"class":671},"# service.yaml — expõe a aplicação dentro do cluster\n",[333,1350,1351,1353,1355],{"class":335,"line":342},[333,1352,678],{"class":677},[333,1354,682],{"class":681},[333,1356,686],{"class":685},[333,1358,1359,1361,1363],{"class":335,"line":348},[333,1360,691],{"class":677},[333,1362,682],{"class":681},[333,1364,1365],{"class":685},"Service\n",[333,1367,1368,1370],{"class":335,"line":354},[333,1369,701],{"class":677},[333,1371,704],{"class":681},[333,1373,1374,1376,1378],{"class":335,"line":360},[333,1375,709],{"class":677},[333,1377,682],{"class":681},[333,1379,1380],{"class":685},"minha-app-service\n",[333,1382,1383,1385],{"class":335,"line":366},[333,1384,741],{"class":677},[333,1386,704],{"class":681},[333,1388,1389,1392,1394,1396],{"class":335,"line":372},[333,1390,1391],{"class":677},"  type",[333,1393,682],{"class":681},[333,1395,1293],{"class":685},[333,1397,1398],{"class":671},"         # Endereço acessível só dentro do cluster\n",[333,1400,1401,1403],{"class":335,"line":378},[333,1402,904],{"class":677},[333,1404,704],{"class":681},[333,1406,1407,1409,1411,1413],{"class":335,"line":746},[333,1408,729],{"class":677},[333,1410,682],{"class":681},[333,1412,714],{"class":685},[333,1414,1415],{"class":671},"        # Roteia tráfego para pods com este label\n",[333,1417,1418,1421],{"class":335,"line":754},[333,1419,1420],{"class":677},"  ports",[333,1422,704],{"class":681},[333,1424,1425,1427,1430,1432,1434],{"class":335,"line":770},[333,1426,757],{"class":681},[333,1428,1429],{"class":677},"port",[333,1431,682],{"class":681},[333,1433,804],{"class":803},[333,1435,1436],{"class":671},"            # Porta que o Service escuta\n",[333,1438,1439,1442,1444,1447],{"class":335,"line":784},[333,1440,1441],{"class":677},"      targetPort",[333,1443,682],{"class":681},[333,1445,1446],{"class":803},"3000",[333,1448,1449],{"class":671},"    # Porta do pod para onde o tráfego vai\n",[124,1451,1453],{"id":1452},"ingress-o-porteiro-do-prédio","Ingress: o porteiro do prédio",[85,1455,1456,1457,1459],{},"Quando você tem múltiplas aplicações (API, frontend, admin) e quer expor todas\nna internet com um único IP e domínios diferentes, usa ",[94,1458,1332],{},". É como um\nporteiro que recebe todos os visitantes e direciona cada um para o andar certo\nbaseado no nome que procuram:",[132,1461,1462,1468,1474],{},[19,1463,1464,1467],{},[311,1465,1466],{},"api.minhaempresa.com"," → Service da API",[19,1469,1470,1473],{},[311,1471,1472],{},"app.minhaempresa.com"," → Service do frontend",[19,1475,1476,1479],{},[311,1477,1478],{},"admin.minhaempresa.com"," → Service do painel admin",[11,1481,1483],{"id":1482},"subindo-sua-primeira-aplicação-primeira-app","Subindo sua primeira aplicação {#primeira-app}",[85,1485,1486],{},"Vamos juntar tudo. Aqui está o passo a passo para subir uma aplicação Node.js\nno Kubernetes, do zero.",[124,1488,1490],{"id":1489},"passo-1-criar-a-imagem-docker","Passo 1: criar a imagem Docker",[324,1492,1496],{"className":1493,"code":1494,"language":1495,"meta":329,"style":329},"language-bash shiki shiki-themes github-light github-dark","# Constrói a imagem e envia para um registro (registry)\n# Registry = um \"Docker Hub\" privado onde imagens ficam armazenadas\ndocker build -t meu-registro\u002Fminha-app:v1.0.0 .\ndocker push meu-registro\u002Fminha-app:v1.0.0\n","bash",[311,1497,1498,1503,1508,1526],{"__ignoreMap":329},[333,1499,1500],{"class":335,"line":336},[333,1501,1502],{"class":671},"# Constrói a imagem e envia para um registro (registry)\n",[333,1504,1505],{"class":335,"line":342},[333,1506,1507],{"class":671},"# Registry = um \"Docker Hub\" privado onde imagens ficam armazenadas\n",[333,1509,1510,1514,1517,1520,1523],{"class":335,"line":348},[333,1511,1513],{"class":1512},"sScJk","docker",[333,1515,1516],{"class":685}," build",[333,1518,1519],{"class":803}," -t",[333,1521,1522],{"class":685}," meu-registro\u002Fminha-app:v1.0.0",[333,1524,1525],{"class":685}," .\n",[333,1527,1528,1530,1533],{"class":335,"line":354},[333,1529,1513],{"class":1512},[333,1531,1532],{"class":685}," push",[333,1534,1535],{"class":685}," meu-registro\u002Fminha-app:v1.0.0\n",[124,1537,1539],{"id":1538},"passo-2-criar-o-deployment","Passo 2: criar o Deployment",[85,1541,1542,1543,1546,1547,1550],{},"Salve o arquivo ",[311,1544,1545],{},"deployment.yaml"," (use o exemplo da seção Deployments acima,\ntrocando a imagem por ",[311,1548,1549],{},"meu-registro\u002Fminha-app:v1.0.0",") e aplique:",[324,1552,1554],{"className":1493,"code":1553,"language":1495,"meta":329,"style":329},"# kubectl = a ferramenta de linha de comando que fala com o Kubernetes\n# apply = aplica a configuração do arquivo no cluster\nkubectl apply -f deployment.yaml\n\n# Veja os pods sendo criados\nkubectl get pods\n# Saída esperada:\n# NAME                         READY   STATUS    RESTARTS   AGE\n# minha-app-7d4f5b6c8-x2k9j   1\u002F1     Running   0          30s\n# minha-app-7d4f5b6c8-m8p3q   1\u002F1     Running   0          30s\n# minha-app-7d4f5b6c8-r1n5t   1\u002F1     Running   0          30s\n",[311,1555,1556,1561,1566,1580,1586,1591,1601,1606,1611,1616,1621],{"__ignoreMap":329},[333,1557,1558],{"class":335,"line":336},[333,1559,1560],{"class":671},"# kubectl = a ferramenta de linha de comando que fala com o Kubernetes\n",[333,1562,1563],{"class":335,"line":342},[333,1564,1565],{"class":671},"# apply = aplica a configuração do arquivo no cluster\n",[333,1567,1568,1571,1574,1577],{"class":335,"line":348},[333,1569,1570],{"class":1512},"kubectl",[333,1572,1573],{"class":685}," apply",[333,1575,1576],{"class":803}," -f",[333,1578,1579],{"class":685}," deployment.yaml\n",[333,1581,1582],{"class":335,"line":354},[333,1583,1585],{"emptyLinePlaceholder":1584},true,"\n",[333,1587,1588],{"class":335,"line":360},[333,1589,1590],{"class":671},"# Veja os pods sendo criados\n",[333,1592,1593,1595,1598],{"class":335,"line":366},[333,1594,1570],{"class":1512},[333,1596,1597],{"class":685}," get",[333,1599,1600],{"class":685}," pods\n",[333,1602,1603],{"class":335,"line":372},[333,1604,1605],{"class":671},"# Saída esperada:\n",[333,1607,1608],{"class":335,"line":378},[333,1609,1610],{"class":671},"# NAME                         READY   STATUS    RESTARTS   AGE\n",[333,1612,1613],{"class":335,"line":746},[333,1614,1615],{"class":671},"# minha-app-7d4f5b6c8-x2k9j   1\u002F1     Running   0          30s\n",[333,1617,1618],{"class":335,"line":754},[333,1619,1620],{"class":671},"# minha-app-7d4f5b6c8-m8p3q   1\u002F1     Running   0          30s\n",[333,1622,1623],{"class":335,"line":770},[333,1624,1625],{"class":671},"# minha-app-7d4f5b6c8-r1n5t   1\u002F1     Running   0          30s\n",[124,1627,1629],{"id":1628},"passo-3-criar-o-service","Passo 3: criar o Service",[324,1631,1633],{"className":1493,"code":1632,"language":1495,"meta":329,"style":329},"kubectl apply -f service.yaml\n\n# Veja o Service criado com seu IP interno\nkubectl get services\n# Saída:\n# NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)\n# minha-app-service    ClusterIP   10.96.34.72     \u003Cnone>        80\u002FTCP\n",[311,1634,1635,1646,1650,1655,1664,1669,1674],{"__ignoreMap":329},[333,1636,1637,1639,1641,1643],{"class":335,"line":336},[333,1638,1570],{"class":1512},[333,1640,1573],{"class":685},[333,1642,1576],{"class":803},[333,1644,1645],{"class":685}," service.yaml\n",[333,1647,1648],{"class":335,"line":342},[333,1649,1585],{"emptyLinePlaceholder":1584},[333,1651,1652],{"class":335,"line":348},[333,1653,1654],{"class":671},"# Veja o Service criado com seu IP interno\n",[333,1656,1657,1659,1661],{"class":335,"line":354},[333,1658,1570],{"class":1512},[333,1660,1597],{"class":685},[333,1662,1663],{"class":685}," services\n",[333,1665,1666],{"class":335,"line":360},[333,1667,1668],{"class":671},"# Saída:\n",[333,1670,1671],{"class":335,"line":366},[333,1672,1673],{"class":671},"# NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)\n",[333,1675,1676],{"class":335,"line":372},[333,1677,1678],{"class":671},"# minha-app-service    ClusterIP   10.96.34.72     \u003Cnone>        80\u002FTCP\n",[124,1680,1682],{"id":1681},"passo-4-expor-para-a-internet-opcional","Passo 4: expor para a internet (opcional)",[85,1684,1685,1686,1689],{},"Para testar localmente, você pode fazer ",[94,1687,1688],{},"port-forward"," (encaminhamento de\nporta) — cria um túnel da sua máquina para o Service dentro do cluster:",[324,1691,1693],{"className":1493,"code":1692,"language":1495,"meta":329,"style":329},"# Encaminha a porta 8080 da sua máquina para a porta 80 do Service\nkubectl port-forward service\u002Fminha-app-service 8080:80\n\n# Agora acesse http:\u002F\u002Flocalhost:8080 no navegador\n",[311,1694,1695,1700,1713,1717],{"__ignoreMap":329},[333,1696,1697],{"class":335,"line":336},[333,1698,1699],{"class":671},"# Encaminha a porta 8080 da sua máquina para a porta 80 do Service\n",[333,1701,1702,1704,1707,1710],{"class":335,"line":342},[333,1703,1570],{"class":1512},[333,1705,1706],{"class":685}," port-forward",[333,1708,1709],{"class":685}," service\u002Fminha-app-service",[333,1711,1712],{"class":685}," 8080:80\n",[333,1714,1715],{"class":335,"line":348},[333,1716,1585],{"emptyLinePlaceholder":1584},[333,1718,1719],{"class":335,"line":354},[333,1720,1721],{"class":671},"# Agora acesse http:\u002F\u002Flocalhost:8080 no navegador\n",[124,1723,1725],{"id":1724},"passo-5-atualizar-a-versão","Passo 5: atualizar a versão",[85,1727,1728],{},"Quando você lançar a v1.1.0, basta mudar a imagem no Deployment:",[324,1730,1732],{"className":1493,"code":1731,"language":1495,"meta":329,"style":329},"# Muda a imagem do deployment para a nova versão\nkubectl set image deployment\u002Fminha-app minha-app=meu-registro\u002Fminha-app:v1.1.0\n\n# O Kubernetes faz um rolling update: cria pods novos, remove os antigos,\n# um de cada vez, sem derrubar a aplicação\nkubectl rollout status deployment\u002Fminha-app\n# Saída: \"deployment minah-app successfully rolled out\"\n",[311,1733,1734,1739,1755,1759,1764,1769,1782],{"__ignoreMap":329},[333,1735,1736],{"class":335,"line":336},[333,1737,1738],{"class":671},"# Muda a imagem do deployment para a nova versão\n",[333,1740,1741,1743,1746,1749,1752],{"class":335,"line":342},[333,1742,1570],{"class":1512},[333,1744,1745],{"class":685}," set",[333,1747,1748],{"class":685}," image",[333,1750,1751],{"class":685}," deployment\u002Fminha-app",[333,1753,1754],{"class":685}," minha-app=meu-registro\u002Fminha-app:v1.1.0\n",[333,1756,1757],{"class":335,"line":348},[333,1758,1585],{"emptyLinePlaceholder":1584},[333,1760,1761],{"class":335,"line":354},[333,1762,1763],{"class":671},"# O Kubernetes faz um rolling update: cria pods novos, remove os antigos,\n",[333,1765,1766],{"class":335,"line":360},[333,1767,1768],{"class":671},"# um de cada vez, sem derrubar a aplicação\n",[333,1770,1771,1773,1776,1779],{"class":335,"line":366},[333,1772,1570],{"class":1512},[333,1774,1775],{"class":685}," rollout",[333,1777,1778],{"class":685}," status",[333,1780,1781],{"class":685}," deployment\u002Fminha-app\n",[333,1783,1784],{"class":335,"line":372},[333,1785,1786],{"class":671},"# Saída: \"deployment minah-app successfully rolled out\"\n",[85,1788,1789],{},"Se algo der errado, você pode reverter (rollback) em segundos:",[324,1791,1793],{"className":1493,"code":1792,"language":1495,"meta":329,"style":329},"# Volta para a versão anterior\nkubectl rollout undo deployment\u002Fminha-app\n",[311,1794,1795,1800],{"__ignoreMap":329},[333,1796,1797],{"class":335,"line":336},[333,1798,1799],{"class":671},"# Volta para a versão anterior\n",[333,1801,1802,1804,1806,1809],{"class":335,"line":342},[333,1803,1570],{"class":1512},[333,1805,1775],{"class":685},[333,1807,1808],{"class":685}," undo",[333,1810,1781],{"class":685},[11,1812,1814],{"id":1813},"auto-scaling-crescer-sob-demanda-auto-scaling","Auto-scaling: crescer sob demanda {#auto-scaling}",[85,1816,1817,1818,1821],{},"O ",[94,1819,1820],{},"Horizontal Pod Autoscaler (HPA)"," aumenta ou diminui o número de pods\nautomaticamente baseado em métricas (uso de CPU, memória, ou métricas\ncustomizadas).",[85,1823,1824,1826],{},[94,1825,185],{},": é como um restaurante que abre mais caixas quando a fila fica\ngrande. Quando o movimento cai, fecha os caixas extras para economizar.",[324,1828,1830],{"className":662,"code":1829,"language":664,"meta":329,"style":329},"# hpa.yaml — auto-scaling horizontal de pods\napiVersion: autoscaling\u002Fv2\nkind: HorizontalPodAutoscaler\nmetadata:\n  name: minha-app-hpa\nspec:\n  scaleTargetRef:\n    apiVersion: apps\u002Fv1\n    kind: Deployment\n    name: minha-app       # Qual Deployment escalar\n  minReplicas: 2          # Mínimo de pods (mesmo sem tráfego)\n  maxReplicas: 20         # Máximo de pods (limite de custo)\n  metrics:\n    - type: Resource\n      resource:\n        name: cpu\n        target:\n          type: Utilization\n          averageUtilization: 70  # Se CPU passar de 70%, adiciona pods\n",[311,1831,1832,1837,1846,1855,1861,1870,1876,1883,1892,1901,1913,1926,1939,1946,1958,1965,1975,1982,1992],{"__ignoreMap":329},[333,1833,1834],{"class":335,"line":336},[333,1835,1836],{"class":671},"# hpa.yaml — auto-scaling horizontal de pods\n",[333,1838,1839,1841,1843],{"class":335,"line":342},[333,1840,678],{"class":677},[333,1842,682],{"class":681},[333,1844,1845],{"class":685},"autoscaling\u002Fv2\n",[333,1847,1848,1850,1852],{"class":335,"line":348},[333,1849,691],{"class":677},[333,1851,682],{"class":681},[333,1853,1854],{"class":685},"HorizontalPodAutoscaler\n",[333,1856,1857,1859],{"class":335,"line":354},[333,1858,701],{"class":677},[333,1860,704],{"class":681},[333,1862,1863,1865,1867],{"class":335,"line":360},[333,1864,709],{"class":677},[333,1866,682],{"class":681},[333,1868,1869],{"class":685},"minha-app-hpa\n",[333,1871,1872,1874],{"class":335,"line":366},[333,1873,741],{"class":677},[333,1875,704],{"class":681},[333,1877,1878,1881],{"class":335,"line":372},[333,1879,1880],{"class":677},"  scaleTargetRef",[333,1882,704],{"class":681},[333,1884,1885,1888,1890],{"class":335,"line":378},[333,1886,1887],{"class":677},"    apiVersion",[333,1889,682],{"class":681},[333,1891,856],{"class":685},[333,1893,1894,1897,1899],{"class":335,"line":746},[333,1895,1896],{"class":677},"    kind",[333,1898,682],{"class":681},[333,1900,865],{"class":685},[333,1902,1903,1906,1908,1910],{"class":335,"line":754},[333,1904,1905],{"class":677},"    name",[333,1907,682],{"class":681},[333,1909,714],{"class":685},[333,1911,1912],{"class":671},"       # Qual Deployment escalar\n",[333,1914,1915,1918,1920,1923],{"class":335,"line":770},[333,1916,1917],{"class":677},"  minReplicas",[333,1919,682],{"class":681},[333,1921,1922],{"class":803},"2",[333,1924,1925],{"class":671},"          # Mínimo de pods (mesmo sem tráfego)\n",[333,1927,1928,1931,1933,1936],{"class":335,"line":784},[333,1929,1930],{"class":677},"  maxReplicas",[333,1932,682],{"class":681},[333,1934,1935],{"class":803},"20",[333,1937,1938],{"class":671},"         # Máximo de pods (limite de custo)\n",[333,1940,1941,1944],{"class":335,"line":792},[333,1942,1943],{"class":677},"  metrics",[333,1945,704],{"class":681},[333,1947,1948,1950,1953,1955],{"class":335,"line":953},[333,1949,757],{"class":681},[333,1951,1952],{"class":677},"type",[333,1954,682],{"class":681},[333,1956,1957],{"class":685},"Resource\n",[333,1959,1960,1963],{"class":335,"line":966},[333,1961,1962],{"class":677},"      resource",[333,1964,704],{"class":681},[333,1966,1967,1970,1972],{"class":335,"line":974},[333,1968,1969],{"class":677},"        name",[333,1971,682],{"class":681},[333,1973,1974],{"class":685},"cpu\n",[333,1976,1977,1980],{"class":335,"line":982},[333,1978,1979],{"class":677},"        target",[333,1981,704],{"class":681},[333,1983,1984,1987,1989],{"class":335,"line":993},[333,1985,1986],{"class":677},"          type",[333,1988,682],{"class":681},[333,1990,1991],{"class":685},"Utilization\n",[333,1993,1994,1997,1999,2002],{"class":335,"line":1007},[333,1995,1996],{"class":677},"          averageUtilization",[333,1998,682],{"class":681},[333,2000,2001],{"class":803},"70",[333,2003,2004],{"class":671},"  # Se CPU passar de 70%, adiciona pods\n",[85,2006,2007],{},"Com essa configuração, se a CPU média dos pods passar de 70%, o Kubernetes\nadiciona mais pods. Se cair, remove. Tudo automático.",[809,2009,2010],{},[85,2011,2012,2015,2016,2019],{},[94,2013,2014],{},"Importante",": para o HPA funcionar com CPU\u002Fmemória, você precisa do\n",[94,2017,2018],{},"Metrics Server"," instalado no cluster. Ele coleta as métricas de\nconsumo de cada pod.",[124,2021,2023],{"id":2022},"tipos-de-auto-scaling-no-kubernetes","Tipos de auto-scaling no Kubernetes",[195,2025,2026,2038],{},[198,2027,2028],{},[201,2029,2030,2032,2035],{},[204,2031,1279],{},[204,2033,2034],{},"O que escala",[204,2036,2037],{},"Quando",[213,2039,2040,2053,2066],{},[201,2041,2042,2047,2050],{},[218,2043,2044],{},[94,2045,2046],{},"Horizontal Pod Autoscaler",[218,2048,2049],{},"Número de pods",[218,2051,2052],{},"Demanda variável de tráfego",[201,2054,2055,2060,2063],{},[218,2056,2057],{},[94,2058,2059],{},"Vertical Pod Autoscaler",[218,2061,2062],{},"CPU\u002Fmemória de cada pod",[218,2064,2065],{},"App precisa de mais recursos",[201,2067,2068,2073,2076],{},[218,2069,2070],{},[94,2071,2072],{},"Cluster Autoscaler",[218,2074,2075],{},"Número de worker nodes",[218,2077,2078],{},"Pods não cabem nos nodes atuais",[85,2080,2081],{},"O ideal é combinar HPA (mais pods) com Cluster Autoscaler (mais servidores\nquando os pods não cabem nos servidores existentes).",[11,2083,2085],{"id":2084},"erros-comuns-erros-comuns","Erros comuns {#erros-comuns}",[124,2087,2089,2090,2093],{"id":2088},"_1-usar-latest-como-tag-de-imagem","1. Usar ",[311,2091,2092],{},":latest"," como tag de imagem",[85,2095,2096,682,2099,2101],{},[94,2097,2098],{},"Problema",[311,2100,2092],{}," é mutável — hoje é a v1.0, amanhã é a v2.0. O\nKubernetes pode não perceber que a imagem mudou e continuar usando uma versão\nantiga em cache.",[85,2103,2104,2107,2108,2111,2112,2115],{},[94,2105,2106],{},"Solução",": sempre use tags versionadas (",[311,2109,2110],{},"v1.0.0",", ",[311,2113,2114],{},"v1.2.3",") ou o hash\nSHA da imagem.",[124,2117,2119],{"id":2118},"_2-não-definir-resource-requests-e-limits","2. Não definir resource requests e limits",[85,2121,2122,2124],{},[94,2123,2098],{},": sem limites, um pod pode consumir toda a CPU\u002Fmemória do node e\nderrubar outros pods. Sem requests, o scheduler não sabe onde colocar o pod.",[85,2126,2127,2129,2130,2133,2134,2137],{},[94,2128,2106],{},": sempre defina ",[311,2131,2132],{},"resources.requests"," (mínimo) e ",[311,2135,2136],{},"resources.limits","\n(máximo) para cada container.",[124,2139,2141],{"id":2140},"_3-confundir-liveness-e-readiness","3. Confundir liveness e readiness",[85,2143,2144,2146],{},[94,2145,2098],{},": usar liveness probe para checar dependências externas (banco de\ndados, API de terceiros). Se o banco cai, o liveness falha, o pod reinicia —\nmas o banco continua caído, e o pod reinicia de novo em loop.",[85,2148,2149,2151,2152,2155,2156,2159],{},[94,2150,2106],{},": liveness checa se a ",[94,2153,2154],{},"própria aplicação"," está viva. Readiness\ncheca se ela está ",[94,2157,2158],{},"pronta para servir",", incluindo dependências.",[124,2161,2163],{"id":2162},"_4-não-configurar-poddisruptionbudget","4. Não configurar PodDisruptionBudget",[85,2165,2166,2168],{},[94,2167,2098],{},": durante manutenção do cluster, o Kubernetes pode derrubar todos\nos seus pods de uma vez, causando downtime.",[85,2170,2171,2173,2174,2177],{},[94,2172,2106],{},": configure um ",[94,2175,2176],{},"PodDisruptionBudget"," (orçamento de disrupção)\ngarantindo que sempre um número mínimo de pods continue rodando:",[324,2179,2181],{"className":662,"code":2180,"language":664,"meta":329,"style":329},"apiVersion: policy\u002Fv1\nkind: PodDisruptionBudget\nmetadata:\n  name: minha-app-pdb\nspec:\n  minAvailable: 2          # Sempre mantém pelo menos 2 pods rodando\n  selector:\n    matchLabels:\n      app: minha-app\n",[311,2182,2183,2192,2201,2207,2216,2222,2234,2240,2246],{"__ignoreMap":329},[333,2184,2185,2187,2189],{"class":335,"line":336},[333,2186,678],{"class":677},[333,2188,682],{"class":681},[333,2190,2191],{"class":685},"policy\u002Fv1\n",[333,2193,2194,2196,2198],{"class":335,"line":342},[333,2195,691],{"class":677},[333,2197,682],{"class":681},[333,2199,2200],{"class":685},"PodDisruptionBudget\n",[333,2202,2203,2205],{"class":335,"line":348},[333,2204,701],{"class":677},[333,2206,704],{"class":681},[333,2208,2209,2211,2213],{"class":335,"line":354},[333,2210,709],{"class":677},[333,2212,682],{"class":681},[333,2214,2215],{"class":685},"minha-app-pdb\n",[333,2217,2218,2220],{"class":335,"line":360},[333,2219,741],{"class":677},[333,2221,704],{"class":681},[333,2223,2224,2227,2229,2231],{"class":335,"line":366},[333,2225,2226],{"class":677},"  minAvailable",[333,2228,682],{"class":681},[333,2230,1922],{"class":803},[333,2232,2233],{"class":671},"          # Sempre mantém pelo menos 2 pods rodando\n",[333,2235,2236,2238],{"class":335,"line":372},[333,2237,904],{"class":677},[333,2239,704],{"class":681},[333,2241,2242,2244],{"class":335,"line":378},[333,2243,911],{"class":677},[333,2245,704],{"class":681},[333,2247,2248,2250,2252],{"class":335,"line":746},[333,2249,918],{"class":677},[333,2251,682],{"class":681},[333,2253,880],{"class":685},[124,2255,2257],{"id":2256},"_5-ignorar-a-segurança-de-containers","5. Ignorar a segurança de containers",[85,2259,2260,2262],{},[94,2261,2098],{},": rodar containers como root, sem limites de privilégio, abre\nbrechas de segurança.",[85,2264,2265,2267,2268,2271],{},[94,2266,2106],{},": adicione ",[311,2269,2270],{},"securityContext"," nos seus manifests:",[324,2273,2275],{"className":662,"code":2274,"language":664,"meta":329,"style":329},"spec:\n  containers:\n    - name: minha-app\n      image: minha-app:v1.0.0\n      securityContext:\n        runAsNonRoot: true       # Não roda como usuário root\n        runAsUser: 1000          # Roda como usuário específico\n        readOnlyRootFilesystem: true  # Sistema de arquivos só-leitura\n",[311,2276,2277,2283,2289,2299,2308,2315,2328,2341],{"__ignoreMap":329},[333,2278,2279,2281],{"class":335,"line":336},[333,2280,741],{"class":677},[333,2282,704],{"class":681},[333,2284,2285,2287],{"class":335,"line":342},[333,2286,749],{"class":677},[333,2288,704],{"class":681},[333,2290,2291,2293,2295,2297],{"class":335,"line":348},[333,2292,757],{"class":681},[333,2294,760],{"class":677},[333,2296,682],{"class":681},[333,2298,880],{"class":685},[333,2300,2301,2303,2305],{"class":335,"line":354},[333,2302,773],{"class":677},[333,2304,682],{"class":681},[333,2306,2307],{"class":685},"minha-app:v1.0.0\n",[333,2309,2310,2313],{"class":335,"line":360},[333,2311,2312],{"class":677},"      securityContext",[333,2314,704],{"class":681},[333,2316,2317,2320,2322,2325],{"class":335,"line":366},[333,2318,2319],{"class":677},"        runAsNonRoot",[333,2321,682],{"class":681},[333,2323,2324],{"class":803},"true",[333,2326,2327],{"class":671},"       # Não roda como usuário root\n",[333,2329,2330,2333,2335,2338],{"class":335,"line":372},[333,2331,2332],{"class":677},"        runAsUser",[333,2334,682],{"class":681},[333,2336,2337],{"class":803},"1000",[333,2339,2340],{"class":671},"          # Roda como usuário específico\n",[333,2342,2343,2346,2348,2350],{"class":335,"line":378},[333,2344,2345],{"class":677},"        readOnlyRootFilesystem",[333,2347,682],{"class":681},[333,2349,2324],{"class":803},[333,2351,2352],{"class":671},"  # Sistema de arquivos só-leitura\n",[2354,2355],"hr",{},[85,2357,2358,2361,2362,2366],{},[94,2359,2360],{},"Precisa de ajuda com Kubernetes?"," A Inicialize Tec implementa clusters\nKubernetes, migra aplicações para containers e configura auto-scaling e\nobservabilidade do zero. ",[22,2363,2365],{"href":2364},"\u002F#top","Conversamos sobre seu caso",".",[2368,2369,2370],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":329,"searchDepth":348,"depth":348,"links":2372},[2373,2374,2377,2380,2383,2387,2390,2393,2397,2404,2407],{"id":13,"depth":342,"text":14},{"id":82,"depth":342,"text":83,"children":2375},[2376],{"id":126,"depth":348,"text":127},{"id":170,"depth":342,"text":171,"children":2378},[2379],{"id":192,"depth":348,"text":193},{"id":384,"depth":342,"text":385,"children":2381},[2382],{"id":449,"depth":348,"text":450},{"id":525,"depth":342,"text":526,"children":2384},[2385,2386],{"id":544,"depth":348,"text":545},{"id":577,"depth":348,"text":578},{"id":610,"depth":342,"text":611,"children":2388},[2389],{"id":638,"depth":348,"text":639},{"id":819,"depth":342,"text":820,"children":2391},[2392],{"id":1212,"depth":348,"text":1213},{"id":1247,"depth":342,"text":1248,"children":2394},[2395,2396],{"id":1269,"depth":348,"text":1270},{"id":1452,"depth":348,"text":1453},{"id":1482,"depth":342,"text":1483,"children":2398},[2399,2400,2401,2402,2403],{"id":1489,"depth":348,"text":1490},{"id":1538,"depth":348,"text":1539},{"id":1628,"depth":348,"text":1629},{"id":1681,"depth":348,"text":1682},{"id":1724,"depth":348,"text":1725},{"id":1813,"depth":342,"text":1814,"children":2405},[2406],{"id":2022,"depth":348,"text":2023},{"id":2084,"depth":342,"text":2085,"children":2408},[2409,2411,2412,2413,2414],{"id":2088,"depth":348,"text":2410},"1. Usar :latest como tag de imagem",{"id":2118,"depth":348,"text":2119},{"id":2140,"depth":348,"text":2141},{"id":2162,"depth":348,"text":2163},{"id":2256,"depth":348,"text":2257},"infraestrutura","2026-08-26","Aprenda Kubernetes do zero: o que é, como funciona, pods, deployments, services e como subir sua primeira aplicação — explicado com analogias simples.","md",[2420,107,2421,2422,2423,121,1513],"kubernetes","orquestração","pods","deployments",{},"\u002Finfraestrutura\u002Fkubernetes-para-iniciantes",{"title":5,"description":2417},"kubernetes-para-iniciantes","infraestrutura\u002Fkubernetes-para-iniciantes","rn0F-7wu9RXWRXlx8q7KQRVUKcMzaPO25KLvrCzfqv8",1787796309109]