Agendamento de Tarefas no Kubernetes: Jobs, CronJobs e Backup Automatizado de PostgreSQL

O Kubernetes vai muito além de manter containers em execução de forma contínua e resiliente. Ele também oferece recursos poderosos para rodar tarefas temporárias ou programadas dentro do cluster. Os principais objetos para esse fim são Jobs e CronJobs, que permitem executar workloads pontuais ou recorrentes.

1. Conceitos básicos

Job

Um Job cria um ou mais Pods que executam uma tarefa até que ela seja concluída com sucesso. Ele garante que a operação seja finalizada, reexecutando os Pods que falharem, conforme a política de reinício (geralmente OnFailure), que significa que o Pod será reiniciado apenas se falhar.

Principais características

  • Ideal para trabalhos batch ou pontuais.
  • Persiste até obter sucesso.
  • Suporta execução paralela de múltiplas instâncias.
  • Reinicia Pods falhos de acordo com a política definida.

Exemplo simples

apiVersion: batch/v1
kind: Job
metadata:
  name: exemplo-job
spec:
  template:
    spec:
      containers:
      - name: tarefa
        image: busybox
        command: ["echo", "Executando tarefa pontual!"]
      restartPolicy: OnFailure

Esse Job cria um Pod que exibe uma mensagem e termina.

CronJob

Um CronJob estende o Job adicionando agendamento recorrente via expressão cron (como no Linux). A cada disparo, ele gera um novo Job.

Casos de uso típicos

  • Backups periódicos
  • Limpeza e manutenção programada
  • Geração de relatórios regulares
  • Sincronização de dados em horários específicos

Principais atributos

  • schedule: expressão cron (minuto hora dia mês dia_da_semana).
  • concurrencyPolicy: controla como lidar com execuções simultâneas (Allow, Forbid ou Replace).
  • startingDeadlineSeconds: define o tempo máximo para iniciar um Job atrasado.

Exemplo que roda a cada 5 minutos

apiVersion: batch/v1
kind: CronJob
metadata:
  name: exemplo-cronjob
spec:
  schedule: "*/5 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: tarefa-periodica
            image: busybox
            command: ["date"]
          restartPolicy: OnFailure

Esse CronJob cria um Job que imprime a data a cada 5 minutos.

2. Caso prático: backup automático de PostgreSQL

Manter backups regulares de um banco de dados é essencial para recuperação de desastres. Com o Kubernetes, podemos automatizar esse processo usando um CronJob que executa pg_dump e grava o arquivo em um volume persistente.

2.1. PersistentVolumeClaim para armazenar os dumps

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pg-backup-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

O PVC garante que os arquivos de backup sobrevivam ao ciclo de vida dos Pods.

2.2. Secret com as credenciais do PostgreSQL

kubectl create secret generic pg-secret \
  --from-literal=POSTGRES_USER=usuario \
  --from-literal=POSTGRES_PASSWORD=minhasenha \
  --from-literal=POSTGRES_DB=meubanco

Armazenar usuário, senha e nome do banco em um Secret evita exposição de credenciais no manifesto.

2.3. CronJob que realiza o backup

apiVersion: batch/v1
kind: CronJob
metadata:
  name: backup-postgres
spec:
  schedule: "0 3 * * *"   # Todos os dias, às 03:00
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: postgres:13
            envFrom:
            - secretRef:
                name: pg-secret
            env:
            - name: PGHOST
              value: "meu-servico-postgres"   # Service que expõe o banco
            command:
            - /bin/sh
            - -c
            - |
              pg_dump -h $PGHOST -U $POSTGRES_USER $POSTGRES_DB -Fc \
                > /backup/dump-$(date +%Y%m%d_%H%M%S).dump
            volumeMounts:
            - name: backup-volume
              mountPath: /backup
          restartPolicy: OnFailure
          volumes:
          - name: backup-volume
            persistentVolumeClaim:
              claimName: pg-backup-pvc

O que acontece aqui?

  • schedule: o Job será disparado diariamente às 03:00.
  • container: usa a imagem oficial postgres, que já contém o pg_dump.
  • command: executa pg_dump no formato customizado (-Fc) e salva o dump com timestamp no diretório /backup.
  • envFrom: injeta as variáveis POSTGRES_USER, POSTGRES_PASSWORD e POSTGRES_DB a partir do Secret.
  • volumeMounts: monta o PVC em /backup para garantir persistência.

2.4. Aplicando os recursos

kubectl apply -f pvc.yaml
kubectl apply -f cronjob-backup.yaml

2.5. Monitoramento

  • Os arquivos de backup ficam disponíveis no PVC; você pode montar o volume em outro Pod para restaurar ou copiar para armazenamento externo.

Ver logs de um Job específico (o nome inclui um timestamp gerado pelo controller):

kubectl logs job/backup-postgres-XXXXX -c backup

Listar o CronJob e seus Jobs:

kubectl get cronjob backup-postgres
kubectl get jobs --watch

3. Boas práticas

  • Gerenciamento de espaço: implemente política de retenção, por exemplo, usando ttlSecondsAfterFinished (disponível a partir do Kubernetes v1.21) ou um script de limpeza para evitar que o PVC encha com backups antigos.
  • Segurança: além de usar Secrets, considere criptografar os dumps antes de armazená‑los para proteção adicional.
  • Validação: periodicamente restaure um dump de teste para garantir que os backups estejam íntegros e funcionais.
  • Ajustes finos: use concurrencyPolicy: Forbid se não quiser que duas execuções se sobreponham, e ajuste startingDeadlineSeconds para lidar com atrasos eventuais na execução do Job.

4. Conclusão

Jobs e CronJobs são ferramentas nativas do Kubernetes que simplificam a execução de workloads pontuais e recorrentes. Automatizar backups de PostgreSQL com um CronJob demonstra como essas abstrações permitem que equipes foquem no desenvolvimento da aplicação, enquanto tarefas críticas de manutenção são orquestradas de forma confiável dentro do próprio cluster.

Explore mais sobre monitoramento de Jobs, políticas de retenção de dados e estratégias avançadas de armazenamento para tirar ainda mais proveito dessas funcionalidades no seu ambiente Kubernetes.