매일 새벽 3시에 실행되는 CronJob이 있는데, 한 달에 2~3번 정도 스킵됩니다. 로그도 안 찍히고 그냥 건너뜁니다. 매니페스트는 평범한데:
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-report
spec:
schedule: "0 3 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: reporter
image: myapp/reporter:v1
restartPolicy: OnFailure
댓글 3
K8s CronJob의 가장 유명한 함정입니다. startingDeadlineSeconds 미설정 + concurrencyPolicy 미설정이 결합되면 controller가 혼란스러워하면서 실행을 건너뜁니다.
왜 스킵되나
CronJob controller는 매 10초마다 "지금 실행할 시간이 지난 Job이 있나"를 체크합니다. 만약 controller가 (1) 다운됐다가 부팅 (2) leader election 진행 (3) 부하로 늦게 응답한 경우, "예정 시간이 100초 이상 지난" Job은 기본적으로 missed 상태가 되어 건너뜁니다.
해결 — startingDeadlineSeconds 명시
concurrencyPolicy 3가지
값동작적합한 워크로드
Allow (default)병렬 실행idempotent 작업
Forbid이전 끝날 때까지 새 Job 안 띄움리포트 생성 (권장)
Replace이전 Job 죽이고 새 거 시작최신 데이터 우선 작업
모니터링 — 스킵 자체를 알람
한 가지 더 — 운영 환경 critical CronJob이라면 K8s CronJob 자체에 의존하지 말라는 게 SRE 진영의 정설입니다.
저희 팀은 매일 돌리는 critical CronJob은 GCP Cloud Scheduler에서 GKE Job을 직접 trigger합니다. K8s CronJob 컨트롤러 의존을 끊었더니 6개월간 100% 실행됐어요.