Ir para o conteúdo principal

deployment.yml

Descrição: este arquivo cria um Deployment no Kubernetes.

Um Deployment é usado para executar uma aplicação baseada em Pods e ReplicaSets, permitindo:

  • definir quantas réplicas da aplicação devem existir;
  • atualizar a aplicação de forma declarativa;
  • fazer rollout gradual de novas versões;
  • fazer rollback para versões anteriores;
  • manter a aplicação disponível durante atualizações;
  • recriar Pods automaticamente quando eles falham.

No arquivo de referência do cluster, o recurso aparece como:

Recurso: deployments.apps
Grupo/API: apps
Tipo: Deployment
Versão: v1

TIPO:       Deployment
VERSÃO:    v1

DESCRIÇÃO:
    Deployment permite atualizações declarativas para Pods e ReplicaSets.

Quando usar Deployment

Use Deployment quando a aplicação:

  • é uma aplicação web;
  • é uma API;
  • é um frontend;
  • é um backend sem estado local obrigatório;
  • pode ter várias réplicas iguais;
  • pode ser reiniciada sem perder dados importantes;
  • guarda dados fora do Pod, por exemplo em banco externo, PVC, S3, NFS, Redis, PostgreSQL, MariaDB etc.;
  • precisa de atualização controlada, como RollingUpdate;
  • precisa escalar horizontalmente, aumentando ou diminuindo réplicas.

Exemplos comuns:

  • sistema administrativo web;
  • portal institucional;
  • API de autenticação;
  • backend de disciplina;
  • aplicação de laboratório;
  • sistema de pesquisa;
  • painel interno;
  • microsserviço;
  • frontend React/Vue/Angular servido por Nginx;
  • backend Python, Node.js, Java, Go, PHP etc.

Quando Deployment não é o recurso indicado

Deployment não é o melhor recurso quando o problema exige outro tipo de controle.

Necessidade Recurso mais indicado Motivo
Banco de dados com identidade fixa StatefulSet Cada réplica precisa de nome e volume persistente próprios.
Rodar um agente em todos os nós DaemonSet Garante um Pod por nó ou por conjunto de nós.
Tarefa única que termina Job Executa até concluir.
Tarefa agendada CronJob Executa em horários definidos.
Criar apenas rede estável para Pods Service Service expõe Pods internamente.
Publicar por domínio HTTP/HTTPS Ingress Ingress publica serviços web por hostname.
Guardar senha/token Secret Deployment apenas consome o Secret.
Guardar configuração ConfigMap Deployment apenas consome o ConfigMap.
Isolar rede entre aplicações NetworkPolicy Deployment não controla isolamento de tráfego.
Definir limite do namespace inteiro ResourceQuota Quota limita o namespace, não um Deployment isolado.
Definir padrão de CPU/memória LimitRange LimitRange aplica padrões no namespace.

Uso em cenário genérico de universidade federal brasileira

Em uma universidade federal,universidade, um Deployment pode ser usado para executar sistemas institucionais e acadêmicos sem colocar cada aplicação em uma VM própria.

Exemplos genéricos:Exemplos:

  • sistema web de um setor administrativo;
  • aplicação de apoio a um laboratório;
  • API de um projeto de pesquisa;
  • serviço de uma disciplina;
  • ambiente de homologação de uma equipe;
  • aplicação temporária para evento, curso ou extensão;
  • painel interno consumido apenas pela rede institucional;
  • backend de uma plataforma usada por alunos, técnicos ou docentes.

Uso recomendado em ambiente universitário:

  • um Namespace por projeto, sistema, disciplina, laboratório ou ambiente;
  • um Deployment por aplicação;
  • um Service para expor os Pods internamente;
  • um Ingress para publicar por domínio;
  • ResourceQuota e LimitRange para evitar consumo exagerado de CPU/memória;
  • NetworkPolicy para isolar projetos diferentes;
  • ServiceAccount, Role e RoleBinding para permissões mínimas;
  • GitLab, Argo CD ou outro GitOps/CI para aplicar os manifestos;
  • imagens versionadas, evitando latest em produção;
  • readinessProbe e livenessProbe para aumentar estabilidade.

Exemplo completo: deployment.yml

apiVersion: apps/v1
kind: Deployment

metadata:
  name: minha-aplicacao
  namespace: meu-projeto
  labels:
    app: minha-aplicacao
    ambiente: homologacao
    componente: backend
  annotations:
    descricao: "Deployment exemplo para aplicação web sem estado"

spec:
  replicas: 3

  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
  minReadySeconds: 10
  paused: false

  selector:
    matchLabels:
      app: minha-aplicacao

  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%

  template:
    metadata:
      labels:
        app: minha-aplicacao
        ambiente: homologacao
        componente: backend
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"

    spec:
      serviceAccountName: minha-aplicacao
      automountServiceAccountToken: false

      imagePullSecrets:
        - name: registry-credencial

      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000

      initContainers:
        - name: aguardar-dependencia
          image: busybox:1.36
          command:
            - sh
            - -c
          args:
            - "echo aguardando dependencia && sleep 5"

      containers:
        - name: app
          image: registry.exemplo.local/projeto/minha-aplicacao:1.0.0
          imagePullPolicy: IfNotPresent

          command:
            - "/app/bin/start"
          args:
            - "--porta=8080"

          workingDir: /app

          ports:
            - name: http
              containerPort: 8080
              protocol: TCP

          env:
            - name: AMBIENTE
              value: "homologacao"
            - name: LOG_LEVEL
              value: "info"
            - name: SENHA_BANCO
              valueFrom:
                secretKeyRef:
                  name: minha-aplicacao-secret
                  key: senha-banco

          envFrom:
            - configMapRef:
                name: minha-aplicacao-config
            - secretRef:
                name: minha-aplicacao-secret

          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"

          volumeMounts:
            - name: config-volume
              mountPath: /app/config
              readOnly: true
            - name: cache
              mountPath: /app/cache

          readinessProbe:
            httpGet:
              path: /ready
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
            timeoutSeconds: 2
            failureThreshold: 3
            successThreshold: 1

          livenessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 30
            periodSeconds: 20
            timeoutSeconds: 2
            failureThreshold: 3

          startupProbe:
            httpGet:
              path: /startup
              port: http
            periodSeconds: 5
            failureThreshold: 30

          lifecycle:
            preStop:
              exec:
                command:
                  - sh
                  - -c
                  - "sleep 10"

          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: false
            capabilities:
              drop:
                - ALL

      volumes:
        - name: config-volume
          configMap:
            name: minha-aplicacao-config
        - name: cache
          emptyDir: {}

      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst

      nodeSelector:
        kubernetes.io/os: linux

      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchLabels:
                    app: minha-aplicacao
                topologyKey: kubernetes.io/hostname

      tolerations: []

      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: ScheduleAnyway
          labelSelector:
            matchLabels:
              app: minha-aplicacao

      priorityClassName: ""
      runtimeClassName: ""

Explicação linha por linha

apiVersion: apps/v1

Define a versão da API usada pelo manifesto.

Para Deployment, normalmente é:

apiVersion: apps/v1

Significado:

  • apps: grupo da API Kubernetes onde fica o Deployment;
  • v1: versão estável da API.

Use exatamente apps/v1 para Deployment moderno.


kind: Deployment

Define o tipo de recurso que será criado.

kind: Deployment

Significado:

  • Deployment: controlador que gerencia ReplicaSets e Pods.

Não confundir com:

  • Pod: container direto;
  • StatefulSet: aplicação com estado;
  • DaemonSet: Pod por nó;
  • Job: tarefa pontual;
  • CronJob: tarefa agendada.

metadata

metadata identifica e organiza o Deployment.

metadata:
  name: minha-aplicacao
  namespace: meu-projeto
  labels:
    app: minha-aplicacao
  annotations:
    descricao: "Deployment exemplo"

metadata.name

Nome do Deployment.

name: minha-aplicacao

Uso:

  • identifica o recurso dentro do namespace;
  • aparece em kubectl get deployments;
  • deve ser único dentro do namespace.

Regras práticas:

  • use letras minúsculas;
  • use hífen;
  • evite acentos;
  • evite espaços;
  • escolha nome curto e claro.

Exemplos bons:

name: portal-academico
name: api-pesquisa
name: backend-laboratorio

metadata.namespace

Namespace onde o Deployment será criado.

namespace: meu-projeto

Uso:

  • separa aplicações;
  • evita mistura entre projetos;
  • ajuda em RBAC, quotas e isolamento.

Se omitir:

  • Kubernetes usa o namespace atual do contexto;
  • em produção isso pode causar aplicação no namespace errado.

Recomendação:

  • sempre declarar namespace.

metadata.labels

Labels são pares chave/valor usados para seleção, organização e filtros.

labels:
  app: minha-aplicacao
  ambiente: homologacao
  componente: backend

Uso:

  • Service usa labels para encontrar Pods;
  • Deployment.spec.selector usa labels para gerenciar Pods;
  • kubectl pode filtrar por labels;
  • ferramentas de observabilidade e GitOps usam labels.

Exemplo:

kubectl get pods -l app=minha-aplicacao

Boas labels:

app: minha-aplicacao
ambiente: producao
componente: backend
equipe: infraestrutura

Evite usar label com dado sensível.


metadata.annotations

Annotations são metadados livres.

annotations:
  descricao: "Aplicação de exemplo"

Uso:

  • observabilidade;
  • configuração de ferramentas;
  • documentação;
  • integração com Ingress Controller, Prometheus, service mesh etc.

Diferença entre labels e annotations:

Campo Uso
labels seleção e organização
annotations informação extra e configuração de ferramentas

Campos de metadata normalmente gerenciados pelo Kubernetes

O kubectl explain mostra vários campos de metadata, mas muitos são preenchidos pelo próprio cluster.

Normalmente você não escreve manualmente:

creationTimestamp:
deletionTimestamp:
resourceVersion:
uid:
generation:
managedFields:
selfLink:

Eles servem para controle interno do Kubernetes.


spec

spec descreve o estado desejado do Deployment.

spec:
  replicas: 3
  selector:
    matchLabels:
      app: minha-aplicacao
  template:
    metadata:
      labels:
        app: minha-aplicacao
    spec:
      containers:
        - name: app
          image: nginx:1.27

Campos principais:

spec:
  minReadySeconds
  paused
  progressDeadlineSeconds
  replicas
  revisionHistoryLimit
  selector
  strategy
  template

spec.replicas

Quantidade desejada de réplicas da aplicação.

replicas: 3

Significado:

  • 1: uma instância;
  • 2 ou mais: alta disponibilidade básica;
  • 0: desliga a aplicação sem apagar o Deployment.

Exemplo:

replicas: 1

Uso comum:

  • desenvolvimento: 1;
  • homologação: 1 ou 2;
  • produção: 2 ou mais.

Observação:

  • se usar HorizontalPodAutoscaler, o número de réplicas pode ser alterado automaticamente.

spec.revisionHistoryLimit

Quantidade de versões antigas mantidas para rollback.

revisionHistoryLimit: 10

Uso:

  • permite voltar para versões anteriores;
  • evita guardar histórico infinito.

Exemplos:

revisionHistoryLimit: 3
revisionHistoryLimit: 10

Recomendação:

  • 3 a 10 costuma ser suficiente.

spec.progressDeadlineSeconds

Tempo máximo para o Deployment progredir antes de ser marcado como com problema.

progressDeadlineSeconds: 600

Significado:

  • valor em segundos;
  • 600 = 10 minutos.

Uso:

  • detectar rollout travado;
  • identificar imagem quebrada;
  • identificar Pod que não fica pronto.

spec.minReadySeconds

Tempo mínimo que um Pod novo deve ficar pronto antes de ser considerado disponível.

minReadySeconds: 10

Significado:

  • valor em segundos;
  • ajuda a evitar considerar o Pod pronto cedo demais.

Use quando:

  • aplicação demora a estabilizar;
  • readiness probe fica pronta antes de a aplicação estar realmente saudável;
  • você quer rollout mais conservador.

spec.paused

Pausa o Deployment.

paused: false

Valores:

paused: true
paused: false

Uso:

  • false: comportamento normal;
  • true: pausa novos rollouts.

Normalmente deixe:

paused: false

spec.selector

Define quais Pods pertencem ao Deployment.

selector:
  matchLabels:
    app: minha-aplicacao

Este campo é obrigatório.

Regra importante:

  • spec.selector.matchLabels deve combinar com spec.template.metadata.labels.

Exemplo correto:

selector:
  matchLabels:
    app: minha-aplicacao

template:
  metadata:
    labels:
      app: minha-aplicacao

Se não bater:

  • o Deployment não consegue gerenciar os Pods corretamente;
  • o manifesto pode ser rejeitado;
  • o rollout pode falhar.

spec.selector.matchLabels

Seleção simples por labels.

matchLabels:
  app: minha-aplicacao

Equivale a:

selecione Pods com app=minha-aplicacao.

É o modo mais comum.


spec.selector.matchExpressions

Seleção avançada.

matchExpressions:
  - key: ambiente
    operator: In
    values:
      - homologacao
      - producao

Campos:

Campo Função
key chave da label
operator operador de comparação
values lista de valores

Operadores comuns:

Operador Uso
In label deve estar dentro da lista
NotIn label não pode estar na lista
Exists label precisa existir
DoesNotExist label não pode existir

Exemplo:

matchExpressions:
  - key: componente
    operator: In
    values:
      - backend

spec.strategy

Define como a atualização do Deployment será feita.

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 25%
    maxUnavailable: 25%

Campos:

strategy:
  type
  rollingUpdate:
    maxSurge
    maxUnavailable

spec.strategy.type

Tipo de estratégia.

type: RollingUpdate

Valores aceitos:

type: RollingUpdate
type: Recreate

RollingUpdate

Atualiza gradualmente.

Uso:

  • produção;
  • sistemas que precisam continuar disponíveis;
  • APIs;
  • frontends;
  • serviços web.

Comportamento:

  • cria Pods novos;
  • espera ficarem prontos;
  • remove Pods antigos gradualmente.

Recreate

Derruba os Pods antigos e depois cria os novos.

Uso:

  • aplicação não suporta duas versões ao mesmo tempo;
  • aplicação usa lock exclusivo;
  • sistema legado;
  • aplicação não tolera múltiplas instâncias simultâneas.

Cuidado:

  • causa indisponibilidade durante atualização.

spec.strategy.rollingUpdate.maxSurge

Quantidade extra de Pods permitida durante atualização.

maxSurge: 25%

Pode ser:

maxSurge: 1
maxSurge: 25%

Exemplo:

  • replicas: 4;
  • maxSurge: 25%;
  • Kubernetes pode criar até 1 Pod extra temporariamente.

Uso:

  • acelera rollout;
  • mantém disponibilidade;
  • consome recursos extras durante atualização.

spec.strategy.rollingUpdate.maxUnavailable

Quantidade de Pods que podem ficar indisponíveis durante atualização.

maxUnavailable: 25%

Pode ser:

maxUnavailable: 0
maxUnavailable: 1
maxUnavailable: 25%

Uso conservador:

maxUnavailable: 0

Uso comum:

maxUnavailable: 25%

Cuidado:

  • se for alto demais, a aplicação pode ficar parcialmente indisponível.

spec.template

Define o modelo dos Pods criados pelo Deployment.

template:
  metadata:
    labels:
      app: minha-aplicacao
  spec:
    containers:
      - name: app
        image: nginx:1.27

Este campo é obrigatório.

O Deployment não roda container diretamente. Ele cria ReplicaSet, e o ReplicaSet cria Pods com base em template.


spec.template.metadata

Metadados aplicados aos Pods.

template:
  metadata:
    labels:
      app: minha-aplicacao
    annotations:
      prometheus.io/scrape: "true"

template.metadata.labels

Labels dos Pods.

labels:
  app: minha-aplicacao

Obrigatório na prática, porque precisa casar com o selector.

Também é usado por:

  • Service;
  • NetworkPolicy;
  • monitoramento;
  • logs;
  • GitOps;
  • ferramentas de inventário.

template.metadata.annotations

Annotations dos Pods.

annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "8080"

Uso:

  • Prometheus;
  • sidecars;
  • service mesh;
  • reinício forçado;
  • configuração de agentes.

Exemplo para forçar rollout alterando annotation:

annotations:
  restartTimestamp: "2026-01-01T00:00:00"

spec.template.spec

Define como cada Pod será criado.

template:
  spec:
    containers:
      - name: app
        image: nginx:1.27

Campos comuns:

serviceAccountName
automountServiceAccountToken
imagePullSecrets
securityContext
initContainers
containers
volumes
restartPolicy
terminationGracePeriodSeconds
dnsPolicy
nodeSelector
affinity
tolerations
topologySpreadConstraints
priorityClassName
runtimeClassName

serviceAccountName

Define a identidade usada pelo Pod dentro do Kubernetes.

serviceAccountName: minha-aplicacao

Use quando:

  • a aplicação precisa acessar a API Kubernetes;
  • precisa ler Secrets/ConfigMaps;
  • precisa interagir com outros recursos do cluster;
  • precisa permissões via RBAC.

Para aplicação comum que não acessa a API Kubernetes, pode usar ServiceAccount com permissões mínimas.


automountServiceAccountToken

Controla se o token da ServiceAccount será montado automaticamente no Pod.

automountServiceAccountToken: false

Valores:

automountServiceAccountToken: true
automountServiceAccountToken: false

Recomendação de segurança:

automountServiceAccountToken: false

Use true apenas se a aplicação realmente precisa chamar a API Kubernetes.


imagePullSecrets

Secrets usados para baixar imagens de registry privado.

imagePullSecrets:
  - name: registry-credencial

Use quando:

  • a imagem está em registry privado;
  • GitLab Registry exige autenticação;
  • registry institucional exige token.

securityContext do Pod

Configura segurança padrão para todos os containers do Pod.

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  runAsGroup: 1000
  fsGroup: 1000

Campos comuns:

Campo Função
runAsNonRoot exige usuário não-root
runAsUser UID do processo
runAsGroup GID do processo
fsGroup grupo dono de volumes montados

Recomendação:

  • evitar rodar como root;
  • definir UID/GID explícitos quando possível.

initContainers

Containers que rodam antes do container principal.

initContainers:
  - name: aguardar-dependencia
    image: busybox:1.36
    command:
      - sh
      - -c
    args:
      - "sleep 5"

Use para:

  • aguardar banco;
  • preparar diretório;
  • baixar arquivo inicial;
  • rodar migração simples;
  • validar dependência.

Cuidado:

  • se initContainer falhar, o Pod não inicia;
  • não use para lógica complexa que deveria estar em Job.

containers

Lista de containers principais do Pod.

containers:
  - name: app
    image: nginx:1.27

Este campo é obrigatório.

Normalmente um Deployment tem um container principal, mas pode ter mais de um.

Use múltiplos containers no mesmo Pod quando eles precisam:

  • compartilhar rede local;
  • compartilhar volumes;
  • nascer e morrer juntos;
  • funcionar como sidecar.

Exemplos:

  • aplicação + proxy sidecar;
  • aplicação + agente de logs;
  • aplicação + exporter.

containers[].name

Nome do container.

name: app

Uso:

  • identificar logs;
  • referenciar container em probes;
  • facilitar debug.

Exemplo:

kubectl logs deployment/minha-aplicacao -c app

containers[].image

Imagem do container.

image: registry.exemplo.local/projeto/minha-aplicacao:1.0.0

Formato comum:

registry/projeto/imagem:tag

Exemplos:

image: nginx:1.27
image: registry.local/sistemas/api:2.4.1
image: registry.gitlab.exemplo/projeto/app:commit-a1b2c3

Recomendação:

  • em produção, evite latest;
  • use tags versionadas;
  • idealmente use digest para máxima reprodutibilidade.

containers[].imagePullPolicy

Define quando a imagem será baixada.

imagePullPolicy: IfNotPresent

Valores:

Valor Comportamento
Always sempre tenta baixar a imagem
IfNotPresent baixa se não existir no nó
Never nunca baixa, usa apenas imagem local

Uso comum:

imagePullPolicy: IfNotPresent

Em ambiente com tag mutável ou latest:

imagePullPolicy: Always

containers[].command

Sobrescreve o comando principal da imagem.

command:
  - "/app/bin/start"

Equivale ao ENTRYPOINT do Docker.

Use quando:

  • precisa trocar o comando padrão da imagem;
  • a mesma imagem executa modos diferentes.

containers[].args

Argumentos passados ao comando.

args:
  - "--porta=8080"

Equivale ao CMD do Docker.

Exemplo:

command:
  - "python"
args:
  - "app.py"

containers[].workingDir

Diretório de trabalho dentro do container.

workingDir: /app

Use quando:

  • a aplicação espera rodar a partir de um diretório específico;
  • scripts usam caminhos relativos.

containers[].ports

Declara portas expostas pelo container.

ports:
  - name: http
    containerPort: 8080
    protocol: TCP

Campos:

Campo Função
name nome lógico da porta
containerPort porta dentro do container
protocol protocolo, normalmente TCP

Protocolos comuns:

protocol: TCP
protocol: UDP

Recomendação:

  • nomeie a porta, por exemplo http;
  • use esse nome em probes e Services.

containers[].env

Variáveis de ambiente individuais.

env:
  - name: AMBIENTE
    value: "homologacao"

Campos:

Campo Função
name nome da variável
value valor literal
valueFrom valor vindo de Secret, ConfigMap ou campo do Pod

env.value

Valor direto.

env:
  - name: LOG_LEVEL
    value: "info"

Use para:

  • configurações simples;
  • valores não sensíveis.

Não use para:

  • senha;
  • token;
  • chave privada.

env.valueFrom.secretKeyRef

Valor vindo de Secret.

env:
  - name: SENHA_BANCO
    valueFrom:
      secretKeyRef:
        name: minha-aplicacao-secret
        key: senha-banco

Use para:

  • senhas;
  • tokens;
  • credenciais;
  • chaves.

env.valueFrom.configMapKeyRef

Valor vindo de ConfigMap.

env:
  - name: URL_API
    valueFrom:
      configMapKeyRef:
        name: minha-aplicacao-config
        key: url-api

Use para configuração não sensível.


env.valueFrom.fieldRef

Valor vindo de metadados do próprio Pod.

env:
  - name: POD_NAME
    valueFrom:
      fieldRef:
        fieldPath: metadata.name

Exemplos úteis:

fieldPath: metadata.name
fieldPath: metadata.namespace
fieldPath: spec.nodeName
fieldPath: status.podIP

env.valueFrom.resourceFieldRef

Valor vindo de recursos do container.

env:
  - name: LIMITE_MEMORIA
    valueFrom:
      resourceFieldRef:
        resource: limits.memory

Exemplos:

resource: limits.cpu
resource: limits.memory
resource: requests.cpu
resource: requests.memory

containers[].envFrom

Importa várias variáveis de uma vez.

envFrom:
  - configMapRef:
      name: minha-aplicacao-config
  - secretRef:
      name: minha-aplicacao-secret

Use quando:

  • há muitas variáveis;
  • quer centralizar configuração;
  • Secret/ConfigMap já está pronto.

Cuidado:

  • pode expor variáveis demais para a aplicação;
  • nomes de chaves viram nomes de variáveis.

containers[].resources

Define CPU e memória para o container.

resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "500m"
    memory: "512Mi"

resources.requests

Recursos mínimos solicitados ao scheduler.

requests:
  cpu: "100m"
  memory: "128Mi"

Uso:

  • ajuda o Kubernetes a escolher o nó;
  • garante reserva mínima.

CPU:

100m = 0,1 CPU
500m = 0,5 CPU
1 = 1 CPU

Memória:

128Mi
512Mi
1Gi

resources.limits

Limite máximo permitido.

limits:
  cpu: "500m"
  memory: "512Mi"

Uso:

  • evita consumo excessivo;
  • protege outros workloads.

Cuidado:

  • limite de memória muito baixo causa OOMKilled;
  • limite de CPU muito baixo pode degradar resposta.

volumeMounts

Monta volumes dentro do container.

volumeMounts:
  - name: config-volume
    mountPath: /app/config
    readOnly: true

Campos:

Campo Função
name nome do volume declarado em volumes
mountPath caminho dentro do container
readOnly monta como somente leitura

Use para:

  • ConfigMap como arquivo;
  • Secret como arquivo;
  • cache temporário;
  • PVC;
  • diretórios compartilhados entre containers.

Probes

Probes verificam saúde da aplicação.

Tipos principais:

Probe Função
readinessProbe diz se o Pod pode receber tráfego
livenessProbe diz se o Pod deve ser reiniciado
startupProbe dá tempo extra para aplicação iniciar

readinessProbe

Verifica se a aplicação está pronta para receber tráfego.

readinessProbe:
  httpGet:
    path: /ready
    port: http
  initialDelaySeconds: 10
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 3
  successThreshold: 1

Use sempre que possível.

Se falhar:

  • o Pod continua vivo;
  • mas sai dos endpoints do Service;
  • não recebe tráfego.

livenessProbe

Verifica se a aplicação está viva.

livenessProbe:
  httpGet:
    path: /health
    port: http
  initialDelaySeconds: 30
  periodSeconds: 20
  timeoutSeconds: 2
  failureThreshold: 3

Se falhar:

  • Kubernetes reinicia o container.

Cuidado:

  • uma livenessProbe mal configurada pode reiniciar aplicação saudável.

startupProbe

Verifica inicialização lenta.

startupProbe:
  httpGet:
    path: /startup
    port: http
  periodSeconds: 5
  failureThreshold: 30

Use quando:

  • aplicação demora para subir;
  • Java, grandes frameworks ou migrações lentas;
  • evitar que livenessProbe mate o container cedo demais.

Tipos de probe

httpGet

httpGet:
  path: /health
  port: 8080

Usa HTTP.

tcpSocket

tcpSocket:
  port: 5432

Testa se a porta TCP responde.

exec

exec:
  command:
    - sh
    - -c
    - "test -f /tmp/ok"

Executa comando dentro do container.


Campos comuns das probes

Campo Função
initialDelaySeconds espera inicial antes da primeira verificação
periodSeconds intervalo entre verificações
timeoutSeconds tempo máximo de espera
failureThreshold falhas antes de considerar problema
successThreshold sucessos necessários para considerar OK

lifecycle

Executa ações em momentos do ciclo de vida do container.

lifecycle:
  preStop:
    exec:
      command:
        - sh
        - -c
        - "sleep 10"

preStop

Executa antes de parar o container.

Uso:

  • dar tempo para conexões finalizarem;
  • retirar aplicação de balanceadores;
  • encerrar processos com segurança.

postStart

Executa logo após iniciar o container.

Uso menos comum.

Cuidado:

  • se falhar, pode afetar inicialização do container.

containers[].securityContext

Configura segurança do container.

securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: false
  capabilities:
    drop:
      - ALL

Campos comuns:

Campo Função
allowPrivilegeEscalation impede escalada de privilégio
readOnlyRootFilesystem deixa filesystem raiz somente leitura
capabilities.drop remove capacidades Linux
runAsUser UID do processo
runAsNonRoot exige não-root
privileged container privilegiado

Recomendação:

allowPrivilegeEscalation: false
capabilities:
  drop:
    - ALL

Evite:

privileged: true

volumes

Define volumes disponíveis para o Pod.

volumes:
  - name: config-volume
    configMap:
      name: minha-aplicacao-config
  - name: cache
    emptyDir: {}

Tipos comuns:

Tipo Uso
configMap montar configuração como arquivo
secret montar senha/certificado como arquivo
emptyDir diretório temporário do Pod
persistentVolumeClaim disco persistente
hostPath caminho do nó, evitar salvo necessidade
projected combina várias fontes em um volume

Volume configMap

volumes:
  - name: config-volume
    configMap:
      name: minha-aplicacao-config

Uso:

  • arquivos de configuração;
  • templates;
  • parâmetros não sensíveis.

Volume secret

volumes:
  - name: segredo-volume
    secret:
      secretName: minha-aplicacao-secret

Uso:

  • certificados;
  • chaves;
  • senhas;
  • tokens.

Volume emptyDir

volumes:
  - name: cache
    emptyDir: {}

Uso:

  • cache temporário;
  • arquivos gerados em runtime;
  • compartilhamento entre containers do mesmo Pod.

Cuidado:

  • é apagado quando o Pod morre.

Volume persistentVolumeClaim

volumes:
  - name: dados
    persistentVolumeClaim:
      claimName: minha-aplicacao-pvc

Uso:

  • dados persistentes;
  • uploads;
  • arquivos que precisam sobreviver à recriação do Pod.

Cuidado:

  • se a aplicação precisa identidade fixa por réplica, talvez StatefulSet seja melhor.

Campos de agendamento do Pod

nodeSelector

Seleciona nós por labels.

nodeSelector:
  kubernetes.io/os: linux

Uso:

  • rodar apenas em Linux;
  • rodar em nós com GPU;
  • rodar em nós de determinado perfil.

affinity

Define regras avançadas de afinidade.

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app: minha-aplicacao
          topologyKey: kubernetes.io/hostname

Usos:

  • espalhar réplicas em nós diferentes;
  • aproximar Pods relacionados;
  • evitar que réplicas fiquem todas no mesmo nó.

Tipos:

Campo Uso
nodeAffinity escolher nós
podAffinity aproximar Pods
podAntiAffinity separar Pods

tolerations

Permite que o Pod rode em nós com taints.

tolerations:
  - key: "dedicado"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

Use quando:

  • existem nós dedicados;
  • nós possuem taints;
  • workload precisa tolerar determinada restrição.

Campos:

Campo Função
key chave do taint
operator Equal ou Exists
value valor do taint
effect efeito do taint

Efeitos comuns:

effect: NoSchedule
effect: PreferNoSchedule
effect: NoExecute

topologySpreadConstraints

Distribui Pods entre domínios de topologia.

topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        app: minha-aplicacao

Uso:

  • espalhar réplicas entre nós;
  • aumentar disponibilidade;
  • evitar concentração de Pods.

Campos:

Campo Função
maxSkew diferença máxima entre domínios
topologyKey label usada como domínio
whenUnsatisfiable o que fazer se não conseguir cumprir
labelSelector quais Pods entram no cálculo

Valores de whenUnsatisfiable:

whenUnsatisfiable: DoNotSchedule
whenUnsatisfiable: ScheduleAnyway

priorityClassName

Define prioridade do Pod.

priorityClassName: alta-prioridade

Use quando:

  • há classes de prioridade configuradas;
  • workloads críticos precisam preferência.

Cuidado:

  • prioridade pode causar preempção de Pods menos prioritários.

runtimeClassName

Escolhe runtime alternativo.

runtimeClassName: gvisor

Use quando:

  • cluster tem RuntimeClass configurado;
  • precisa de sandboxing;
  • precisa de runtime especial.

Normalmente fica vazio ou ausente.


Campos gerais do Pod

restartPolicy

Para Deployment, normalmente deve ser:

restartPolicy: Always

Deployment foi feito para manter aplicação continuamente rodando.

Não use em Deployment:

restartPolicy: Never
restartPolicy: OnFailure

Esses valores são típicos de Job/CronJob.


terminationGracePeriodSeconds

Tempo para o container encerrar com elegância.

terminationGracePeriodSeconds: 30

Significado:

  • Kubernetes envia sinal para encerrar;
  • espera esse tempo;
  • se não encerrar, força finalização.

Use tempo maior quando:

  • aplicação precisa terminar requisições;
  • precisa fechar conexão;
  • precisa descarregar fila.

dnsPolicy

Política de DNS do Pod.

dnsPolicy: ClusterFirst

Valor comum em Deployment:

dnsPolicy: ClusterFirst

Significado:

  • usa DNS interno do cluster primeiro;
  • permite resolver Services por nome.

hostAliases

Adiciona entradas no /etc/hosts do Pod.

hostAliases:
  - ip: "10.0.0.10"
    hostnames:
      - "sistema.local"

Use apenas quando:

  • não há DNS adequado;
  • precisa compatibilidade temporária.

Evite como solução permanente.


status

status mostra o estado atual do Deployment.

No arquivo de referência aparecem campos como:

status:
  availableReplicas
  collisionCount
  conditions
  observedGeneration
  readyReplicas
  replicas
  unavailableReplicas
  updatedReplicas

Você normalmente não escreve status no YAML.

O Kubernetes preenche automaticamente.

Use para diagnóstico:

kubectl get deployment minha-aplicacao -n meu-projeto
kubectl describe deployment minha-aplicacao -n meu-projeto
kubectl rollout status deployment/minha-aplicacao -n meu-projeto

Campos úteis:

Campo Significado
replicas réplicas totais conhecidas
readyReplicas réplicas prontas
availableReplicas réplicas disponíveis
unavailableReplicas réplicas indisponíveis
updatedReplicas réplicas já atualizadas
conditions condições do rollout

Manifesto mínimo funcional

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-exemplo
  namespace: meu-projeto
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-exemplo
  template:
    metadata:
      labels:
        app: nginx-exemplo
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80

Aplicar:

kubectl apply -f deployment.yml

Verificar:

kubectl get deployments -n meu-projeto
kubectl get pods -n meu-projeto -l app=nginx-exemplo

Manifesto recomendado para aplicação web simples

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-web
  namespace: meu-projeto
  labels:
    app: app-web
spec:
  replicas: 2
  revisionHistoryLimit: 5
  progressDeadlineSeconds: 600
  selector:
    matchLabels:
      app: app-web
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: app-web
    spec:
      automountServiceAccountToken: false
      containers:
        - name: app
          image: registry.exemplo.local/projeto/app-web:1.0.0
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          readinessProbe:
            httpGet:
              path: /ready
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 30
            periodSeconds: 20

Comandos úteis

Aplicar

kubectl apply -f deployment.yml

Ver Deployment

kubectl get deployment -n meu-projeto

Ver Pods do Deployment

kubectl get pods -n meu-projeto -l app=minha-aplicacao

Ver detalhes

kubectl describe deployment minha-aplicacao -n meu-projeto

Acompanhar rollout

kubectl rollout status deployment/minha-aplicacao -n meu-projeto

Ver histórico

kubectl rollout history deployment/minha-aplicacao -n meu-projeto

Voltar versão

kubectl rollout undo deployment/minha-aplicacao -n meu-projeto

Pausar rollout

kubectl rollout pause deployment/minha-aplicacao -n meu-projeto

Retomar rollout

kubectl rollout resume deployment/minha-aplicacao -n meu-projeto

Escalar manualmente

kubectl scale deployment minha-aplicacao -n meu-projeto --replicas=5

Reiniciar Pods do Deployment

kubectl rollout restart deployment/minha-aplicacao -n meu-projeto

Ver YAML real aplicado

kubectl get deployment minha-aplicacao -n meu-projeto -o yaml

Relação com outros manifestos

Um Deployment sozinho normalmente não é suficiente para publicar uma aplicação.

Uso típico:

Namespace
  ├── ConfigMap
  ├── Secret
  ├── ServiceAccount
  ├── Deployment
  ├── Service
  ├── Ingress
  ├── NetworkPolicy
  ├── ResourceQuota
  └── LimitRange

Deployment + Service

Deployment cria Pods.

Service dá endereço estável para esses Pods.

Deployment + Ingress

Ingress publica o Service por domínio HTTP/HTTPS.

Deployment + ConfigMap

ConfigMap fornece configuração para o Deployment.

Deployment + Secret

Secret fornece credenciais para o Deployment.

Deployment + HPA

HPA ajusta replicas automaticamente.

Deployment + PDB

PDB evita indisponibilidade durante manutenção.


Erros comuns

Selector diferente das labels do template

Errado:

selector:
  matchLabels:
    app: app-a
template:
  metadata:
    labels:
      app: app-b

Correto:

selector:
  matchLabels:
    app: app-a
template:
  metadata:
    labels:
      app: app-a

Usar latest em produção

Evite:

image: minha-api:latest

Prefira:

image: minha-api:1.4.2

Ou:

image: minha-api@sha256:...

Não definir requests e limits

Evite:

resources: {}

Prefira:

resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "500m"
    memory: "512Mi"

Não configurar readinessProbe

Sem readinessProbe, o Pod pode receber tráfego antes de estar pronto.

Prefira:

readinessProbe:
  httpGet:
    path: /ready
    port: http

Rodar como root sem necessidade

Evite quando possível:

securityContext:
  runAsUser: 0

Prefira:

securityContext:
  runAsNonRoot: true
  runAsUser: 1000

Checklist para uso em produção

Antes de aplicar um Deployment em ambiente compartilhado:

  • namespace definido;
  • labels claras;
  • selector combinando com template.metadata.labels;
  • imagem com tag versionada;
  • replicas adequado;
  • resources.requests definidos;
  • resources.limits definidos;
  • readinessProbe configurada;
  • livenessProbe configurada quando fizer sentido;
  • startupProbe se a aplicação demora a iniciar;
  • strategy definida;
  • maxUnavailable adequado para evitar queda;
  • serviceAccountName com menor privilégio;
  • automountServiceAccountToken: false quando a API Kubernetes não for necessária;
  • Secrets fora do YAML do Deployment;
  • ConfigMaps fora do YAML do Deployment;
  • Service criado para expor os Pods;
  • Ingress criado se precisar domínio HTTP/HTTPS;
  • NetworkPolicy criada se houver isolamento de rede;
  • PDB criado se a aplicação precisar alta disponibilidade.

Resumo

Use Deployment para aplicações sem estado que precisam rodar continuamente no Kubernetes.

O Deployment controla:

  • quantas réplicas devem existir;
  • qual imagem deve rodar;
  • como atualizar a aplicação;
  • como substituir Pods antigos por novos;
  • como manter Pods funcionando;
  • como fazer rollback.

Para aplicação web comum, o conjunto mínimo geralmente é:

Namespace + Deployment + Service + Ingress

Para ambiente institucional compartilhado, o conjunto recomendado é:

Namespace + ResourceQuota + LimitRange + ServiceAccount + Role/RoleBinding
+ ConfigMap + Secret + Deployment + Service + Ingress + NetworkPolicy + PDB