DevOps & Infra

Como Fazer Deploy de uma Aplicação no Kubernetes: Guia Prático para Desenvolvedores

Aprenda a fazer o deploy de uma aplicação no Kubernetes de forma prática. Entenda a estrutura de manifestos YAML, configure health checks, exponha sua API e domine comandos essenciais do kubectl.

Marcos Costa
Marcos Costa
19 de setembro de 2026 8 min de leitura
Tela de um desenvolvedor mostrando arquivos YAML de configuração do Kubernetes e comandos `kubectl` em um terminal, com um diagrama estilizado de um cluster Kubernetes no plano de fundo, representando o deploy de aplicações.

Se você já domina o ambiente de desenvolvimento local usando Docker, consegue rodar seus containers sem problemas e agora precisa dar o próximo passo rumo à produção, o Kubernetes é o caminho natural. No entanto, a transição do ambiente local para um cluster de orquestração costuma ser acompanhada de uma sopa de letrinhas e conceitos que parecem mais complexos do que realmente são.

Para o dia a dia de quem desenvolve software, você não precisa ser um especialista em infraestrutura ou dominar toda a arquitetura interna do control plane para colocar sua aplicação no ar de forma resiliente. Entender os conceitos de containers e orquestração e saber como estruturar seus arquivos de configuração é o suficiente para garantir que sua API rode com alta disponibilidade.

Neste guia prático, vamos desmistificar o processo de deploy no Kubernetes, analisando desde a diferença dos recursos básicos até a escrita de manifestos YAML e a execução de comandos essenciais de monitoramento e rollback.

Pod, Deployment e StatefulSet: Qual é a diferença na prática?

Antes de escrever qualquer linha de configuração, é fundamental entender os blocos de construção que o Kubernetes utiliza para gerenciar suas aplicações. Os três recursos mais comuns para lidar com workloads são:

  • Pod: É a menor unidade executável no Kubernetes. Um Pod encapsula um ou mais containers (geralmente apenas um), compartilhando armazenamento e recursos de rede. Na prática, você nunca deve criar um Pod isolado diretamente em produção. Eles são efêmeros: se o nó onde o Pod está rodando falhar, o Pod morre e não é recriado automaticamente.
  • Deployment: É o recurso ideal para aplicações stateless (que não guardam estado local, como APIs HTTP, microsserviços e frontends). O Kubernetes Deployment gerencia a criação, atualização e escalabilidade dos Pods de forma declarativa. Se um Pod cair, o Deployment garante que outro seja criado instantaneamente para substituí-lo.
  • StatefulSet: Utilizado para aplicações stateful (que precisam manter um estado persistente e identidade única, como bancos de dados PostgreSQL, Redis ou sistemas de mensageria). Diferente do Deployment, onde os Pods são idênticos e intercambiáveis, no StatefulSet cada Pod possui um identificador persistente e um volume de disco vinculado que não se perde quando o Pod é reiniciado.

Para a maioria das aplicações web e APIs que desenvolvemos, o Deployment é a escolha padrão.

Anatomia de um Manifesto YAML: Estruturando o seu Deployment

No Kubernetes, tudo é definido de forma declarativa através de arquivos YAML. Em vez de rodar comandos para criar recursos, você descreve o estado desejado da sua aplicação e o Kubernetes se encarrega de convergir o estado atual para o estado descrito.

Antes de enviar a configuração para o cluster, o primeiro passo é empacotar sua aplicação com Docker e enviar a imagem para um registro público ou privado (como Docker Hub ou AWS ECR).

Abaixo, analisamos a estrutura básica de um manifesto de Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
  labels:
    app: minha-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: minha-api
  template:
    metadata:
      labels:
        app: minha-api
    spec:
      containers:
      - name: api-container
        image: meu-usuario/minha-api:v1.0.0
        ports:
        - containerPort: 8080

Entendendo os campos essenciais:

  • apiVersion e kind: Definem qual recurso estamos criando e qual versão da API do Kubernetes estamos utilizando.
  • metadata: Identifica o recurso no cluster, definindo seu nome (api-deployment) e etiquetas (labels).
  • spec.replicas: O número de instâncias idênticas (Pods) que queremos rodando simultaneamente. Se definirmos 3, o Kubernetes garantirá que sempre existam três Pods ativos.
  • spec.selector: Diz ao Deployment quais Pods ele deve gerenciar. Ele busca por Pods que possuam a label correspondente (app: minha-api).
  • spec.template: É o molde do Pod. Tudo o que estiver abaixo de template.spec descreve como o container deve ser criado (nome, imagem do container, portas expostas, variáveis de ambiente, etc.).

Garantindo a Estabilidade: Configurando Liveness e Readiness Probes

Um dos erros mais comuns ao realizar um deploy no Kubernetes é assumir que o container está pronto para receber tráfego só porque o processo principal iniciou. Para evitar que requisições de usuários caiam em um container que ainda está inicializando ou que travou internamente, utilizamos os Health Checks através de probes.

Existem dois tipos principais de validações de saúde:

  1. Readiness Probe (Verificação de Prontidão): Determina se o container está pronto para receber tráfego de rede. Se a validação falhar, o Kubernetes temporariamente remove o Pod do balanceamento de carga, mas não reinicia o container.
  2. Liveness Probe (Verificação de Sobrevivência): Determina se o container está rodando corretamente. Se a validação falhar (por exemplo, a aplicação travou em um deadlock), o Kubernetes mata o container e inicia um novo para tentar recuperar o serviço.

Veja como configurar essas validações simulando uma rota de health check (/healthz) da sua aplicação:

        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
  • initialDelaySeconds: Tempo de espera antes de realizar a primeira verificação (útil para dar tempo da aplicação subir).
  • periodSeconds: Intervalo de tempo entre cada verificação subsequente.

Expondo a Aplicação: Services (ClusterIP, NodePort, LoadBalancer) e Ingress

Por padrão, os Pods recebem IPs internos que mudam constantemente a cada reinicialização. Para expor sua aplicação de forma estável, você precisa de um Kubernetes Service.

Existem três tipos principais de Services:

  • ClusterIP (Padrão): Expõe o serviço em um IP interno do cluster. Ideal para comunicação interna entre microsserviços (ex: sua API conversando com um banco de dados).
  • NodePort: Expõe o serviço em uma porta estática em cada nó do cluster. Permite acesso externo básico, mas não é recomendado para produção devido à limitação de portas (faixa 30000-32767).
  • LoadBalancer: Cria um balanceador de carga real no provedor de nuvem (AWS, GCP, Azure) que direciona o tráfego externo diretamente para o seu Service.

Para cenários complexos com múltiplos domínios e rotas HTTP, o ideal é utilizar um Ingress Controller (como o NGINX Ingress), que atua como um proxy reverso unificado na borda do cluster, distribuindo o tráfego externo para os Services internos do tipo ClusterIP.

Abaixo, apresentamos um exemplo de manifesto YAML unificado contendo o Deployment da API e um Service do tipo ClusterIP:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
  labels:
    app: minha-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: minha-api
  template:
    metadata:
      labels:
        app: minha-api
    spec:
      containers:
      - name: api-container
        image: meu-usuario/minha-api:v1.0.0
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
---
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: ClusterIP
  selector:
    app: minha-api
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

Gerenciando o Deploy com kubectl: Comandos Essenciais para o Dia a Dia

Com os manifestos YAML prontos, você utilizará a ferramenta de linha de comando kubectl para interagir com o cluster. Aqui está o guia de sobrevivência com os comandos mais utilizados:

1. Aplicar configurações

Para criar ou atualizar qualquer recurso a partir de um arquivo YAML:

kubectl apply -f deployment.yaml

2. Monitorar o status dos recursos

Para listar seus Pods e verificar se estão rodando corretamente:

kubectl get pods

Para listar os Services ativos:

kubectl get svc

3. Debugar problemas

Se um Pod estiver com o status CrashLoopBackOff ou não iniciar, use o describe para ver o histórico de eventos do Kubernetes:

kubectl describe pod <nome-do-pod>

Para visualizar a saída de console (logs) da sua aplicação:

kubectl logs <nome-do-pod> --tail=100 -f

4. Executar comandos dentro do container

Se precisar inspecionar o ambiente interno do container (como testar uma conexão de rede):

kubectl exec -it <nome-do-pod> -- sh

Atualizações Sem Downtime: RollingUpdate e Como Fazer Rollback Rápido

Por padrão, o Kubernetes utiliza a estratégia de atualização chamada RollingUpdate. Quando você altera a versão da imagem no seu arquivo YAML e executa um kubectl apply, o Kubernetes não derruba todos os Pods antigos de uma vez.

Em vez disso, ele cria um novo Pod com a nova versão, aguarda que ele passe no teste do readinessProbe e, somente após a confirmação de que o novo Pod está saudável, ele remove um Pod antigo. Esse processo se repete gradualmente até que todos os Pods estejam atualizados, garantindo zero downtime durante o deploy.

Se você deseja automatizar esse fluxo de ponta a ponta, o ideal é implementar pipelines de CI/CD com Docker para que cada commit na branch principal gere uma nova imagem e atualize o manifesto no cluster.

O que fazer se o deploy falhar?

Se você subiu uma versão com bug ou erro de inicialização, o Kubernetes interromperá o processo de RollingUpdate ao perceber que os novos Pods estão falhando nas validações de saúde. Para reverter o deploy imediatamente para a versão anterior estável, execute:

kubectl rollout undo deployment/api-deployment

Esse comando desfaz a última alteração e retorna o cluster ao estado de funcionamento anterior em segundos, minimizando o impacto para os usuários finais.

Referências

Perguntas Frequentes (FAQ)

Qual a diferença prática entre ClusterIP, NodePort e LoadBalancer?

O ClusterIP expõe o serviço apenas internamente no cluster. O NodePort expõe o serviço em uma porta estática em cada nó do cluster, permitindo acesso externo básico. O LoadBalancer cria um balanceador de carga real no provedor de nuvem para direcionar o tráfego externo ao serviço.

O que acontece se o livenessProbe falhar?

Se o livenessProbe falhar, o Kubernetes entende que o container está travado ou em estado irrecuperável e reinicia o container automaticamente para tentar restabelecer a saúde da aplicação.

Como posso testar meus manifestos do Kubernetes localmente?

Você pode utilizar ferramentas leves como Minikube, Kind (Kubernetes in Docker) ou habilitar o Kubernetes integrado no Docker Desktop para rodar um cluster local e aplicar seus arquivos YAML de teste.

Marcos Costa

Sobre Marcos Costa

Desenvolvedor backend com foco em arquitetura de software, automação e produtos digitais.

Ver mais artigos