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
Namespacepor projeto, sistema, disciplina, laboratório ou ambiente; - um
Deploymentpor aplicação; - um
Servicepara expor os Pods internamente; - um
Ingresspara publicar por domínio; ResourceQuotaeLimitRangepara evitar consumo exagerado de CPU/memória;NetworkPolicypara isolar projetos diferentes;ServiceAccount,RoleeRoleBindingpara permissões mínimas;- GitLab, Argo CD ou outro GitOps/CI para aplicar os manifestos;
- imagens versionadas, evitando
latestem produção; readinessProbeelivenessProbepara 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:
Serviceusa labels para encontrar Pods;Deployment.spec.selectorusa labels para gerenciar Pods;kubectlpode 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;2ou mais: alta disponibilidade básica;0: desliga a aplicação sem apagar o Deployment.
Exemplo:
replicas: 1
Uso comum:
- desenvolvimento:
1; - homologação:
1ou2; - produção:
2ou 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:
3a10costuma 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.matchLabelsdeve combinar comspec.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
StatefulSetseja 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:
-
namespacedefinido; -
labelsclaras; -
selectorcombinando comtemplate.metadata.labels; - imagem com tag versionada;
-
replicasadequado; -
resources.requestsdefinidos; -
resources.limitsdefinidos; -
readinessProbeconfigurada; -
livenessProbeconfigurada quando fizer sentido; -
startupProbese a aplicação demora a iniciar; -
strategydefinida; -
maxUnavailableadequado para evitar queda; -
serviceAccountNamecom menor privilégio; -
automountServiceAccountToken: falsequando 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