Cron no Kubernetes vs crontab Linux: armadilhas de fuso

Por que a mesma expressão cron de cinco campos dispara em horários diferentes no GitHub Actions, CronJob K8s e crontab — e como visualizar com segurança.

0 9 * * 1-5 parece inequívoco: minuto zero, hora nove, dias úteis. Até você implantar em três plataformas e os backups rodarem às 09:00 local, 09:00 UTC e 09:00 no fuso do control plane — tudo com a mesma string.

Esta comparação é para quem copia linhas cron entre servidores Linux, Kubernetes e CI sem reler regras de fuso.

Mesma gramática, relógios diferentes

O cron Unix clássico usa cinco campos (minuto, hora, dia do mês, mês, dia da semana). A gramática é familiar; o relógio não é compartilhado:

PlataformaComportamento típico de fuso
crontab de usuário LinuxFuso local do servidor (timedatectl)
CronJob KubernetesDefault do controller salvo timeZone (1.25+)
schedule GitHub ActionsSempre UTC
Quartz / algumas cloudsMuitas vezes seis campos (segundos primeiro)

Uma linha copiada do /etc/crontab de uma VM em Shanghai para um workflow GitHub desloca oito horas se você não converter.

Crontab Linux: conheça o servidor

crontab -e na VM avalia expressões no fuso local da máquina. Mudanças de horário de verão podem pular ou repetir uma hora em agendamentos de relógio de parede como 30 2 * * *.

Runbooks devem registrar:

  • Expressão
  • Saída de timedatectl
  • Equivalente UTC esperado para correlacionar logs

Ao cruzar com timestamps no CloudWatch ou Loki, converta com o Conversor de timestamp em vez de conta mental no incidente.

Kubernetes: defina timeZone explicitamente

Desde Kubernetes 1.25, CronJob suporta:

spec:
  timeZone: "Asia/Shanghai"
  schedule: "0 9 * * 1-5"

Sem timeZone, o comportamento depende da configuração do controller — não assuma que bate com seu laptop. Trate timezone ausente no YAML como bloqueio em review.

Upgrades de cluster e control planes multi-região são motivo para zonas IANA explícitas em vez de “sempre usamos local”.

GitHub Actions: só UTC

on:
  schedule:
    - cron: "0 9 * * 1-5"

Isso é 09:00 UTC de segunda a sexta. Para 09:00 em Shanghai em dia útil, você precisa de 0 1 * * 1-5 em UTC no offset padrão — ou documente a tabela de offset no README do workflow.

Muitos tickets “por que o CI rodou de noite?” começam aqui.

Visualize antes do merge

Em qualquer plataforma:

  1. Faça parse na Expressão Cron
  2. Leia a descrição humana (atenção à semântica OR entre dia do mês e dia da semana)
  3. Visualize próximas execuções em UTC e no fuso alvo
  4. Acrescente timezone + plataforma na linha do runbook

Falhas comuns de copiar e colar

ErroResultado
Cron Actions pensado como 9h localJob no horário errado
K8s sem timeZoneDeriva após mudança de cluster
Quartz de seis campos colado como cincoAgenda inválida ou errada
DOM + DOW ambos setados esperando ANDExecuções extras inesperadas

Aprendizado relacionado

Sintaxe de campos, tabelas de plataforma e checklist de depuração no curso de expressões Cron. Para logs entre fusos, combine com Timestamps em logs entre fusos.

Conclusão

Strings cron são agnósticas de fuso; agendadores não são. Documente plataforma + zona ao lado de cada linha, visualize em UTC e local, e defina timeZone no Kubernetes de propósito — não por acidente.

Ferramentas relacionadas

Use as ferramentas deste artigo

Analisador de expressões Croncron / crontab / scheduleConversor de Timestamptimestamp / unix / epoch

Aprenda o formato

Curso de expressões CronSintaxe cron Unix: cinco campos, intervalos e passos, armadilhas de fuso, diferenças entre plataformas, padrões comuns de jobs e fluxo prático de depuração.Curso de Unix time e timestampsAprenda epoch Unix, segundos vs milissegundos, UTC, fusos, ISO 8601 e depuração em logs e APIs.

Voltar aos artigos