Jobs e CronJobs no Kubernetes
1. Introdução a Workloads Temporários no Kubernetes
No ecossistema Kubernetes, a maioria dos workloads são serviços contínuos — aplicações web, APIs, microserviços — que rodam indefinididamente. No entanto, uma parcela significativa das tarefas em ambientes de produção são temporárias: backups de banco de dados, processamento batch de arquivos, limpeza de logs antigos, envio de relatórios periódicos. Para esses cenários, o Kubernetes oferece dois recursos especializados: Job e CronJob.
1.1. Diferença entre Pods efêmeros e workloads batch
Pods comuns são efêmeros por natureza, mas sua finalidade principal é manter processos contínuos. Quando um container termina sua execução (exit code 0), o Pod é reiniciado pela política restartPolicy: Always. Já os workloads batch (Job e CronJob) são projetados para executar uma tarefa até a conclusão e depois parar. Eles gerenciam o ciclo de vida completo: criação de Pods, monitoramento de conclusão e limpeza.
1.2. Casos de uso
- Backups: dump de banco de dados PostgreSQL/MySQL armazenado em um volume persistente ou bucket S3
- Processamento de dados: transformação de arquivos CSV, geração de relatórios, ETL
- Tarefas agendadas: limpeza de diretórios temporários, rotação de logs, renovação de certificados SSL
- Migrações: execução de scripts de migração de banco de dados antes de um deployment
1.3. Visão geral dos recursos
- Job: executa um ou mais Pods até que um número específico de conclusões bem-sucedidas seja alcançado
- CronJob: cria Jobs em intervalos de tempo definidos por expressão cron, similar ao cron do Linux
2. Job: Execução Única e Garantida
2.1. Definição de um Job
Um Job básico define um template de Pod com restartPolicy: Never ou OnFailure. O campo backoffLimit controla quantas vezes o Job tentará reiniciar um Pod com falha antes de marcar o Job como falho.
apiVersion: batch/v1
kind: Job
metadata:
name: job-exemplo
spec:
template:
spec:
containers:
- name: worker
image: busybox:1.36
command: ["sh", "-c", "echo 'Tarefa executada'; sleep 5"]
restartPolicy: Never
backoffLimit: 4
2.2. Tipos de completude
- Non-parallel jobs: apenas um Pod é criado. Quando termina com sucesso, o Job é concluído
- Parallel jobs with fixed completion count:
completionsdefine quantos Pods bem-sucedidos são necessários;parallelismdefine quantos Pods rodam simultaneamente - Work queue jobs: o Job cria Pods até que um número suficiente de itens da fila seja processado (sem
completionsfixo)
apiVersion: batch/v1
kind: Job
metadata:
name: job-paralelo
spec:
completions: 6
parallelism: 2
template:
spec:
containers:
- name: worker
image: busybox:1.36
command: ["sh", "-c", "echo 'Processando...'; sleep 10"]
restartPolicy: Never
2.3. Monitoramento
Comandos essenciais para acompanhar Jobs:
# Listar Jobs
kubectl get jobs
# Ver detalhes completos
kubectl describe job job-exemplo
# Ver logs do Pod gerado pelo Job
kubectl logs job/job-exemplo
# Acompanhar em tempo real
kubectl get pods --watch -l job-name=job-exemplo
O status de um Job exibe campos como completions, active (Pods rodando) e failed (Pods que falharam).
3. Configuração Avançada de Jobs
3.1. Controle de paralelismo
Os campos parallelism e completions permitem ajustar o throughput:
parallelism: 3ecompletions: 9: 3 Pods rodam simultaneamente até que 9 tenham sucessoparallelism: 0: pausa a execução (útil para suspender temporariamente)
3.2. Timeout e retentativas
apiVersion: batch/v1
kind: Job
metadata:
name: job-com-timeout
spec:
activeDeadlineSeconds: 120 # Job falha se exceder 2 minutos
backoffLimit: 3 # Máximo de 3 tentativas por Pod
ttlSecondsAfterFinished: 3600 # Remove o Job 1 hora após conclusão
template:
spec:
containers:
- name: worker
image: busybox:1.36
command: ["sh", "-c", "exit 1"] # Simula falha
restartPolicy: Never
activeDeadlineSeconds: tempo máximo total do Job (incluindo retentativas)backoffLimit: número de tentativas antes de marcar como falhottlSecondsAfterFinished: limpeza automática após conclusão
3.3. Indexed Jobs
Para processamento de filas ou lotes numerados, use completionMode: Indexed:
apiVersion: batch/v1
kind: Job
metadata:
name: job-indexado
spec:
completions: 5
parallelism: 2
completionMode: Indexed
template:
spec:
containers:
- name: worker
image: busybox:1.36
command: ["sh", "-c", "echo 'Processando item $JOB_COMPLETION_INDEX'"]
restartPolicy: Never
Cada Pod recebe a variável de ambiente JOB_COMPLETION_INDEX com um valor de 0 a 4.
4. CronJob: Agendamento de Jobs no Tempo
4.1. Estrutura de um CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-diario
spec:
schedule: "0 2 * * *" # Todos os dias às 02:00
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: mysql:8.0
command: ["mysqldump", "-h", "mysql-service", "-u", "root", "--all-databases"]
restartPolicy: Never
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
O schedule segue o formato cron padrão: minuto hora dia mês dia-da-semana.
4.2. Políticas de concorrência
- Allow (padrão): permite que múltiplos Jobs do mesmo CronJob rodem simultaneamente
- Forbid: não cria novo Job se o anterior ainda estiver ativo
- Replace: cancela o Job anterior e cria um novo
4.3. Controle de histórico
successfulJobsHistoryLimit: quantos Jobs bem-sucedidos manter no histórico (padrão 3)failedJobsHistoryLimit: quantos Jobs falhos manter (padrão 1)
Jobs antigos são removidos automaticamente pelo controlador.
5. Boas Práticas para Jobs e CronJobs
5.1. Imagens idempotentes e stateless
Todo Job deve ser seguro para executar múltiplas vezes sem efeitos colaterais. Por exemplo, um backup deve sobrescrever o arquivo anterior ou usar timestamps. Um script de limpeza deve verificar se o arquivo já foi removido antes de tentar deletá-lo.
5.2. Gerenciamento de dependências
Use Jobs como pré-requisitos via initContainers ou orquestre sequências com ferramentas como Argo Workflows. Para dependências simples, um Job pode verificar a existência de um recurso antes de prosseguir.
5.3. Cleanup automático
Sempre defina ttlSecondsAfterFinished em Jobs e successfulJobsHistoryLimit/failedJobsHistoryLimit em CronJobs para evitar acúmulo de recursos no cluster.
6. Monitoramento e Observabilidade
6.1. Métricas nativas
O Kubernetes expõe métricas via /metrics do kube-controller-manager. Utilize Prometheus para coletar:
kube_job_status_succeeded: Jobs concluídos com sucessokube_job_status_failed: Jobs que falharamkube_job_status_active: Jobs em execuçãokube_cronjob_status_last_schedule_time: última execução do CronJob
6.2. Logs centralizados
Configure um agregador de logs (Loki, Elasticsearch, CloudWatch) para coletar logs de Jobs. Use labels como job-name e cronjob-name para filtragem.
6.3. Alertas
Alertas comuns usando Prometheus + Alertmanager:
# Falha recorrente: mais de 3 falhas em 10 minutos
- alert: JobFalhando
expr: rate(kube_job_status_failed[10m]) > 0.3
for: 5m
# Job travado: ativo por mais de 30 minutos
- alert: JobStuck
expr: kube_job_status_active > 0 and (time() - kube_job_start_time) > 1800
7. Exemplos Práticos e Integração com o Ecossistema
7.1. Job para backup de banco de dados (MySQL dump)
apiVersion: batch/v1
kind: Job
metadata:
name: backup-mysql
spec:
ttlSecondsAfterFinished: 86400
template:
spec:
containers:
- name: mysqldump
image: mysql:8.0
env:
- name: MYSQL_PWD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
command:
- sh
- -c
- |
mysqldump -h mysql-service -u root --all-databases > /backup/backup-$(date +%Y%m%d).sql
echo "Backup concluído: backup-$(date +%Y%m%d).sql"
volumeMounts:
- name: backup-storage
mountPath: /backup
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: backup-pvc
restartPolicy: Never
7.2. CronJob para limpeza de logs antigos
apiVersion: batch/v1
kind: CronJob
metadata:
name: limpeza-logs
spec:
schedule: "0 4 * * 0" # Todo domingo às 04:00
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
containers:
- name: cleaner
image: busybox:1.36
command:
- sh
- -c
- |
find /var/log/app -name "*.log" -mtime +30 -delete
echo "Logs com mais de 30 dias removidos"
volumeMounts:
- name: log-volume
mountPath: /var/log/app
volumes:
- name: log-volume
persistentVolumeClaim:
claimName: logs-pvc
restartPolicy: Never
backoffLimit: 2
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 1
7.3. Integração com Helm
Em charts Helm, Jobs e CronJobs são definidos como templates. Exemplo de templates/cronjob.yaml:
{{- if .Values.cronjob.enabled }}
apiVersion: batch/v1
kind: CronJob
metadata:
name: {{ .Release.Name }}-cronjob
spec:
schedule: "{{ .Values.cronjob.schedule }}"
concurrencyPolicy: {{ .Values.cronjob.concurrencyPolicy }}
jobTemplate:
spec:
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: {{ .Values.cronjob.command }}
restartPolicy: Never
successfulJobsHistoryLimit: {{ .Values.cronjob.successfulJobsHistoryLimit }}
failedJobsHistoryLimit: {{ .Values.cronjob.failedJobsHistoryLimit }}
{{- end }}
Com values.yaml correspondente:
cronjob:
enabled: true
schedule: "0 */6 * * *"
concurrencyPolicy: Forbid
command: ["/bin/sh", "-c", "python /app/process.py"]
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
Referências
- Kubernetes Official Documentation: Jobs — Documentação oficial sobre o recurso Job, incluindo paralelismo, índices e exemplos completos
- Kubernetes Official Documentation: CronJob — Documentação oficial sobre CronJobs, políticas de concorrência e gerenciamento de histórico
- Kubernetes Best Practices: Batch Workloads — Padrões de Jobs no Kubernetes: processamento em fila, jobs paralelos e boas práticas
- Prometheus Monitoring Mixin for Kubernetes — Dashboards e alertas para monitoramento de Jobs e CronJobs no Kubernetes
- Helm Charts: Batch Jobs Patterns — Melhores práticas da Helm Foundation para definição de Jobs e CronJobs em charts reutilizáveis
- Argo Workflows Documentation — Orquestração avançada de Jobs sequenciais e paralelos no Kubernetes
- Kubernetes Job Patterns: Indexed Jobs — Explicação detalhada sobre completionMode: Indexed para processamento de filas numeradas