Post

Guia de Referência: kubectl dry-run

Guia de Referência: kubectl dry-run

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

  1. O que é dry-run e por que usar?
  2. Fundamentos: client vs. server
  3. Guia de Início Rápido: Exemplos Essenciais
  4. Receitas por Recurso: Guia de Referência Avançado
  5. Fluxo de Trabalho Prático: Do Zero ao Deploy
  6. Dicas e Truques Avançados
  7. 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.
ModoValidaçãoRequer ClusterUso Principal
clientApenas sintaxe básicaNãoGeração de YAML
serverCompleta (incluindo Admission Controllers)SimValidaçã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

3. Expor um Deployment com um Service

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.

Passo 1: Gerar os Manifestos Básicos com um Script

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

Visualizar Diferenças com kubectl diff

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

Validar Sintaxe com Ferramentas Externas

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 -

Gerar em Diferentes Formatos

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.

  1. 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.
  2. 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.
  3. 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.

This post is licensed under CC BY 4.0 by the author.