본문 바로가기
Q&A해결2026년 5월 1일1분 읽기

Kubernetes CronJob이 매번 실행되지 않고 가끔 건너뜁니다

K
K8s운영자
조회 770댓글 3

매일 새벽 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

김김영삼6개월 전

K8s CronJob의 가장 유명한 함정입니다. startingDeadlineSeconds 미설정 + concurrencyPolicy 미설정이 결합되면 controller가 혼란스러워하면서 실행을 건너뜁니다.


왜 스킵되나


CronJob controller는 매 10초마다 "지금 실행할 시간이 지난 Job이 있나"를 체크합니다. 만약 controller가 (1) 다운됐다가 부팅 (2) leader election 진행 (3) 부하로 늦게 응답한 경우, "예정 시간이 100초 이상 지난" Job은 기본적으로 missed 상태가 되어 건너뜁니다.


해결 — startingDeadlineSeconds 명시


apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-report
spec:
schedule: "0 3 * * *"
startingDeadlineSeconds: 3600 # ← 1시간 안에 시작했으면 OK
concurrencyPolicy: Forbid # ← 이전 Job이 아직 돌면 새거 안 띄움
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
backoffLimit: 2 # ← 실패 시 2번 재시도
activeDeadlineSeconds: 1800 # ← 30분 넘으면 강제 종료
template:
spec:
containers:
- name: reporter
image: myapp/reporter:v1
resources:
requests: { cpu: 100m, memory: 256Mi }
limits: { cpu: 500m, memory: 1Gi }
restartPolicy: OnFailure

concurrencyPolicy 3가지


값동작적합한 워크로드
Allow (default)병렬 실행idempotent 작업
Forbid이전 끝날 때까지 새 Job 안 띄움리포트 생성 (권장)
Replace이전 Job 죽이고 새 거 시작최신 데이터 우선 작업

모니터링 — 스킵 자체를 알람


# Prometheus
- alert: CronJobSkipped
expr: time() - kube_cronjob_status_last_schedule_time{cronjob="nightly-report"} > 90000
for: 5m
annotations:
summary: "nightly-report가 25시간 넘게 실행 안 됐음"
서서버지기영호6개월 전

한 가지 더 — 운영 환경 critical CronJob이라면 K8s CronJob 자체에 의존하지 말라는 게 SRE 진영의 정설입니다.



  • K8s CronJob: 노드 장애·클러스터 재시작에 약함

  • 대안 1: 외부 스케줄러(Airflow·Argo Workflows·Temporal) → K8s에 Job 트리거

  • 대안 2: 다중 클러스터 redundancy — 같은 CronJob을 2개 클러스터에 두고 dedup 로직 추가

  • 대안 3: cron-as-a-service(EventBridge·Cloud Scheduler) → K8s API 호출


저희 팀은 매일 돌리는 critical CronJob은 GCP Cloud Scheduler에서 GKE Job을 직접 trigger합니다. K8s CronJob 컨트롤러 의존을 끊었더니 6개월간 100% 실행됐어요.

KK8s운영자(guest)6개월 전
startingDeadlineSeconds 추가하고, 알람도 거니까 안정됐습니다. 운영 환경은 외부 스케줄러로 분리하는 패턴도 검토하겠습니다. 두 분 답변 모두 큰 도움이 됐어요!
Ctrl+Enter로 등록