Este guia é uma referência para o uso do comando kubectl com a flag --dry-run. Ele foi projetado para auxiliar desde iniciantes até usuários avançados a gerar manifestos Kubernetes de forma eficiente, segura e declarativa, acelerando o fluxo de trabalho de “Infrastructure as Code” (IaC).
Índice
- O que é
dry-run e por que usar? - Fundamentos:
client vs. server - Guia de Início Rápido: Exemplos Essenciais
- Receitas por Recurso: Guia de Referência Avançado
- Fluxo de Trabalho Prático: Do Zero ao Deploy
- Dicas e Truques Avançados
- Limitações e Considerações
1. O que é dry-run e por que usar?
A flag --dry-run permite que você simule a execução de um comando kubectl sem, de fato, realizar qualquer alteração no seu cluster. Em vez de criar ou modificar um recurso, o comando exibe o que seria feito.
Principais Vantagens:
- Gerar Manifestos YAML: A principal utilidade é gerar rapidamente a estrutura básica de um manifesto YAML, que pode ser salvo, editado e versionado no Git.
- Validar Comandos: Permite verificar se a sintaxe do seu comando está correta antes de aplicá-lo.
- Aprender a Estrutura dos Objetos: É uma excelente ferramenta de aprendizado para entender a estrutura e os campos de diferentes recursos Kubernetes.
- Automatizar a Criação de Boilerplate: Reduz o trabalho manual de escrever YAML do zero.
2. Fundamentos: client vs. server
O dry-run possui dois modos principais:
--dry-run=client (Padrão e mais comum)- O que faz: Toda a operação é processada localmente no lado do cliente (
kubectl). Não há comunicação com o API Server do Kubernetes. - Vantagens: Extremamente rápido e não requer conexão com um cluster.
- Uso Ideal: Gerar manifestos YAML básicos.
--dry-run=server- O que faz: O comando é enviado ao API Server, que executa todas as etapas de validação (admissão, etc.), mas não persiste o objeto no etcd.
- Vantagens: Oferece uma validação muito mais completa, verificando se o manifesto é válido do ponto de vista do cluster.
- Uso Ideal: Validar um manifesto final antes de aplicá-lo.
| Modo | Validação | Requer Cluster | Uso Principal |
|---|
client | Apenas sintaxe básica | Não | Geração de YAML |
server | Completa (incluindo Admission Controllers) | Sim | Validação de YAML |
3. Guia de Início Rápido: Exemplos Essenciais
Para quem está começando, estes comandos cobrem 80% dos casos de uso diários.
1. Criar um Namespace
1
| kubectl create namespace meu-namespace --dry-run=client -o yaml > namespace.yaml
|
2. Criar um Deployment Simples
1
| kubectl create deployment nginx-web --image=nginx --dry-run=client -o yaml > deployment.yaml
|
1
| kubectl expose deployment nginx-web --port=80 --target-port=80 --dry-run=client -o yaml > service.yaml
|
4. Criar um Secret a partir de um arquivo de ambiente
Primeiro, crie o arquivo db-credentials.env:
1
2
| DB_USER=admin
DB_PASSWORD=senha-super-secreta
|
Depois, gere o manifesto do Secret:
1
| kubectl create secret generic db-secret --from-env-file=db-credentials.env --dry-run=client -o yaml > secret.yaml
|
5. Criar um Ingress Básico
1
| kubectl create ingress meu-ingress --class=nginx --rule="app.meudominio.com/*=nginx-web:80" --dry-run=client -o yaml > ingress.yaml
|
4. Receitas por Recurso: Guia de Referência Avançado
Esta seção contém exemplos mais detalhados para gerar uma vasta gama de recursos Kubernetes.
ConfigMap
1
2
3
4
5
6
7
8
| # A partir de múltiplos valores literais
kubectl create configmap app-config \
--from-literal=TZ="America/Sao_Paulo" \
--from-literal=DB_HOST="mysql-service" \
--dry-run=client -o yaml > configmap-literal.yaml
# A partir de um arquivo de configuração
kubectl create configmap nginx-config --from-file=nginx.conf --dry-run=client -o yaml > configmap-file.yaml
|
PersistentVolumeClaim (PVC)
1
2
3
4
5
| kubectl create pvc meu-pvc \
--storage-class=standard \
--access-mode=ReadWriteOnce \
--requests=storage=10Gi \
--dry-run=client -o yaml > pvc.yaml
|
Service (Variações)
1
2
3
4
5
6
7
8
| # LoadBalancer
kubectl create service loadbalancer meu-app-lb --tcp=80:8080 --dry-run=client -o yaml > service-lb.yaml
# NodePort
kubectl create service nodeport meu-app-np --tcp=80:8080 --node-port=30080 --dry-run=client -o yaml > service-np.yaml
# Headless (para StatefulSets)
kubectl create service clusterip db-service --clusterip="None" --tcp=3306:3306 --dry-run=client -o yaml > service-headless.yaml
|
Controle de Acesso (RBAC)
1
2
3
4
5
6
7
8
| # ServiceAccount
kubectl create serviceaccount meu-sa --dry-run=client -o yaml > sa.yaml
# Role
kubectl create role leitor-de-pods --verb=get,list,watch --resource=pods --dry-run=client -o yaml > role.yaml
# RoleBinding
kubectl create rolebinding bind-leitor --role=leitor-de-pods --serviceaccount=default:meu-sa --dry-run=client -o yaml > rolebinding.yaml
|
Políticas de Rede (NetworkPolicy)
1
2
| # Bloqueia todo o tráfego de entrada por padrão
kubectl create networkpolicy default-deny-ingress --pod-selector="" --policy-types=Ingress --dry-run=client -o yaml > netpol-deny.yaml
|
Cargas de Trabalho (Workloads)
1
2
3
4
5
6
7
8
| # Job (tarefa única)
kubectl create job meu-job --image=busybox --dry-run=client -o yaml -- echo "Hello, World!"
# CronJob (tarefa agendada)
kubectl create cronjob meu-cronjob --image=busybox --schedule="0 5 * * *" --dry-run=client -o yaml -- echo "Backup diário"
# StatefulSet (requer um Service headless)
kubectl create statefulset meu-sts --image=nginx --service=meu-headless-svc --replicas=3 --dry-run=client -o yaml > statefulset.yaml
|
Políticas e Limites
1
2
3
4
5
6
7
8
9
10
11
| # ResourceQuota
kubectl create quota minha-quota --hard=pods=10,requests.cpu=4,requests.memory=16Gi --dry-run=client -o yaml > quota.yaml
# LimitRange
kubectl create limitrange meus-limites --min-cpu=100m --max-cpu=2 --min-memory=128Mi --max-memory=4Gi --dry-run=client -o yaml > limitrange.yaml
# HorizontalPodAutoscaler (HPA)
kubectl autoscale deployment nginx-web --min=2 --max=10 --cpu-percent=80 --dry-run=client -o yaml > hpa.yaml
# PodDisruptionBudget (PDB)
kubectl create poddisruptionbudget meu-pdb --selector=app=nginx --min-available=2 --dry-run=client -o yaml > pdb.yaml
|
5. Fluxo de Trabalho Prático: Do Zero ao Deploy
O verdadeiro poder do dry-run se manifesta em um fluxo de trabalho estruturado.
Cenário: Deploy de uma aplicação web phpIPAM.
Crie um script generate-manifests.sh para gerar a estrutura inicial.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| #!/bin/bash
# generate-manifests.sh
NAMESPACE="phpipam-system"
echo "=== Gerando manifests para phpIPAM ==="
# 1. Namespace
kubectl create namespace $NAMESPACE --dry-run=client -o yaml > 01-namespace.yaml
# 2. Secret (com placeholders)
kubectl create secret generic phpipam-secrets \
--from-literal=DB_ROOT_PASSWORD="CHANGE_ME" \
--from-literal=DB_PASSWORD="CHANGE_ME" \
-n $NAMESPACE --dry-run=client -o yaml > 02-secrets.yaml
# 3. ConfigMap
kubectl create configmap phpipam-config \
--from-literal=IPAM_DATABASE_HOST="phpipam-db" \
-n $NAMESPACE --dry-run=client -o yaml > 03-configmap.yaml
# 4. PVC para o Banco de Dados
kubectl create pvc phpipam-db-pvc \
-n $NAMESPACE --access-mode=ReadWriteOnce --requests=storage=10Gi \
--dry-run=client -o yaml > 04-pvc.yaml
# 5. Deployment do Banco de Dados (MariaDB)
kubectl create deployment phpipam-db --image=mariadb:11.8 -n $NAMESPACE --dry-run=client -o yaml > 05-deployment-db.yaml
# 6. Service do Banco de Dados
kubectl create service clusterip phpipam-db --tcp=3306:3306 -n $NAMESPACE --dry-run=client -o yaml > 06-service-db.yaml
# 7. Deployment da Aplicação Web
kubectl create deployment phpipam-web --image=phpipam/phpipam-www:v1.7.4 -n $NAMESPACE --dry-run=client -o yaml > 07-deployment-web.yaml
# 8. Service da Aplicação Web
kubectl create service clusterip phpipam-web --tcp=80:80 -n $NAMESPACE --dry-run=client -o yaml > 08-service-web.yaml
# 9. Ingress
kubectl create ingress phpipam-ingress --class=nginx --rule="ipam.meudominio.com/*=phpipam-web:80" -n $NAMESPACE --dry-run=client -o yaml > 09-ingress.yaml
echo "Manifests gerados com sucesso!"
|
Passo 2: Editar e Adicionar Configurações Complexas
Os arquivos gerados são um ponto de partida. Agora, você deve editá-los para adicionar configurações que o dry-run não gera, como:
- No
05-deployment-db.yaml e 07-deployment-web.yaml:envFrom para carregar ConfigMap e Secret.volumeMounts para usar o PersistentVolumeClaim.volumes para definir os volumes.resources (requests e limits) para CPU e memória.livenessProbe e readinessProbe para health checks.securityContext (ex: runAsUser, runAsGroup).
Exemplo de edição no 07-deployment-web.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| # ... (início do arquivo)
spec:
template:
spec:
containers:
- name: phpipam-web
image: phpipam/phpipam-www:v1.7.4
# ADIÇÕES MANUAIS ABAIXO
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: phpipam-config
- secretRef:
name: phpipam-secrets
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
readinessProbe:
httpGet:
path: /login
port: 80
initialDelaySeconds: 15
periodSeconds: 10
# ... (resto do arquivo)
|
Passo 3: Validar e Aplicar
1
2
3
4
5
| # Validar todos os arquivos no diretório com dry-run=server
kubectl apply -f . --dry-run=server
# Se a validação passar, aplicar de verdade
kubectl apply -f .
|
6. Dicas e Truques Avançados
Depois de editar um manifesto, use kubectl diff para ver exatamente o que mudará no cluster antes de aplicar.
1
2
3
4
5
6
7
8
9
| # Salve a saída do dry-run em um arquivo
kubectl create deployment nginx-web --image=nginx:1.21 --dry-run=client -o yaml > nginx.yaml
# Aplique o arquivo
kubectl apply -f nginx.yaml
# Edite o arquivo (ex: mude a imagem para nginx:1.22)
# Agora, veja a diferença
kubectl diff -f nginx.yaml
|
Use yamllint para garantir que o YAML gerado é sintaticamente correto.
1
2
| # Requer que yamllint esteja instalado (pip install yamllint)
kubectl create deployment nginx --dry-run=client -o yaml | yamllint -
|
O dry-run não se limita ao YAML.
1
2
3
4
5
| # Gerar em JSON
kubectl create deployment nginx --dry-run=client -o json
# Obter uma visão mais ampla (útil para alguns recursos)
kubectl create deployment nginx --dry-run=client -o wide
|
7. Limitações e Considerações
O dry-run é poderoso, mas não é mágico. É crucial entender suas limitações.
- Não Gera Configurações Complexas:
- O
dry-run não adivinha sua lógica de aplicação. Configurações como securityContext, probes, volumeMounts, affinity, tolerations e strategy de deploy quase sempre precisam ser adicionadas manualmente.
- Não Valida Referências (
dry-run=client):- O modo cliente não verifica se os
ConfigMaps, Secrets ou Services que você referencia em um Deployment realmente existem. O modo server pode pegar alguns desses erros, mas não todos.
- Suporte Limitado para Alguns Recursos:
- Recursos mais complexos ou Custom Resource Definitions (CRDs) podem não ter suporte completo para geração via
kubectl create.
A regra de ouro é: Use dry-run para criar o esqueleto (80% do trabalho) e, em seguida, adicione os detalhes (os 20% restantes) manualmente.