정기 보고서 생성이나 데이터 동기화가 두 번 처리될 때, CronJob의 concurrencyPolicy를 Forbid로 바꾸는 것만으로 충분할까? 이 설정은 겹치는 실행을 다루지만 업무 결과의 중복까지 해결하지는 않는다. 2026년 10월 27일 Kubernetes 공식 문서를 확인해 적용 범위와 운영 시험 항목을 정리했다.

Allow·Forbid·Replace의 적용 범위

기본값 Allow는 동시 실행을 허용한다. Forbid는 이전 Job이 끝나지 않았을 때 새 실행을 건너뛰고, Replace는 실행 중인 Job을 새 실행으로 교체한다. 이 정책은 같은 CronJob에서 만든 Job끼리 적용된다. 다른 CronJob이 같은 작업을 실행하는 것까지 막는 공통 잠금이 아니다.

Forbid로 놓친 실행은 이전 작업 완료 후 startingDeadlineSeconds 조건에 따라 뒤늦게 생성될 수 있다. 따라서 “건너뛴 일정은 반드시 영구 폐기된다”고 해석하면 안 된다. 공식 문서는 일정당 Job 생성이 근사적으로 이루어져 두 개가 생기거나 하나도 생기지 않는 상황이 있을 수 있다고 설명하고, 작업을 멱등하게 만들 것을 권한다. Kubernetes CronJob 동시 실행 정책과 한계

5분 주기인데 한 번에 8분 걸리는 경우

다음은 실제 측정이 아닌 가상 비교다. 같은 CronJob이 한국시간 09:00에 시작했고, 중단 없이 실행하면 09:08에 끝난다고 하자. 다음 예정 시각은 09:05다. 제어기나 Pod 시작 지연 없이 예정 시각에 판단한다는 단순화가 들어 있다.

  • Allow: 09:05에 새 Job이 시작하면 이전 Job과 09:08까지 3분간 겹친다.
  • Forbid: 09:05 시점에는 이전 Job이 실행 중이므로 새 실행을 건너뛴다. 이후의 지연 생성 여부는 별도 조건으로 확인한다.
  • Replace: 09:05에 기존 Job을 새 Job으로 교체한다. 기존 작업이 수행한 외부 저장이나 전송이 자동으로 취소된다고 가정하지 않는다.

8분 − 5분 = 3분은 Allow 사례의 가정상 겹치는 시간이다. Forbid에서 하루 실행 횟수가 정확히 절반이 된다거나, Replace가 3분만큼의 비용을 절약한다는 계산으로 확장할 수 없다. 실제 시작·종료 시각, 재시도, 외부 요청과 인프라 과금 방식이 다르기 때문이다.

09:00에 시작한 8분 작업이 09:05에도 실행 중일 때 Allow는 동시 실행, Forbid는 해당 시점 시작 건너뜀, Replace는 기존 Job 교체.
다음 예정 시각의 차이. Allow: 동시 실행 · Forbid: 시작 건너뜀 · Replace: 기존 Job 교체. 같은 CronJob의 5분 주기, 8분 작업을 가정했다. Forbid의 이후 지연 생성은 시작 기한 등에 달려 있다. Replace는 외부 업무 결과의 자동 취소를 뜻하지 않는다. 실제 실행 시각이나 일일 횟수 보장이 아니다.

한 번 생성된 Job 안에서도 재실행을 고려한다

Job 공식 문서는 parallelism과 completions가 모두 1이고 restartPolicy가 Never여도 같은 프로그램이 두 번 시작될 수 있다고 경고한다. Pod가 실패한 뒤 새 Pod에서 실행될 경우 이전 실행이 남긴 임시 파일, 잠금, 미완료 출력도 처리할 수 있어야 한다. Kubernetes Job의 실패 처리

업무 관점의 완료는 “Pod 하나가 성공했다”보다 구체적이어야 한다. 예를 들어 같은 보고 대상 날짜와 고객에 대해 보고서를 한 번만 확정해야 한다면, 작업 식별 기준을 날짜·고객·보고서 종류로 정하고 중복 요청 때 기존 결과를 재사용하는 설계를 검토할 수 있다. 이는 이 글의 설계 제안이며 Kubernetes가 제공하는 자동 보장은 아니다.

완료 여부를 먼저 읽은 뒤 쓰는 단순한 두 단계만으로는 동시에 들어온 작업이 모두 통과할 수 있다. 결과 확정과 중복 판정을 원자적으로 처리할 수 있는지, 외부 시스템이 같은 업무 키의 재요청을 어떻게 다루는지를 별도로 시험해야 한다. 장애 뒤 누락과 중복을 구분할 수 있도록 업무 키와 결과 식별자를 함께 남기자.

운영 전 네 가지 시험을 통과시킨다

  1. 느린 작업: 테스트 환경에서 실행 시간을 주기보다 길게 만들고, 선택한 정책의 Job 생성·종료 기록이 예상과 맞는지 확인한다. 실제 고객에게 메시지를 보내는 작업으로 시험하지 않는다.
  2. 별도 실행 경로: 같은 업무를 실행하는 다른 CronJob이나 수동 재처리 경로가 있는지 목록으로 만든다. 공통 업무 키가 어느 경로에서도 유지되는지 점검한다.
  3. 부분 완료: 외부 저장은 끝났지만 성공 기록 전에 종료되는 상황을 가정한다. 재실행 시 중복 결과가 생기는지와 누락된 기록을 복구할 방법을 확인한다.
  4. 늦은 시작: 예정 시각과 실제 시작을 따로 기록해 허용 지연을 정한다. 오래된 업무가 뒤늦게 실행돼도 유효한지 먼저 판단한다.

팀 점검표에는 CronJob 이름, 업무 키, 예정 시각, 실제 시작·종료, Job 식별자, 결과 식별자와 재처리 사유를 남기는 것이 좋다. 정책 이름만 비교하는 대신 운영 결과를 추적하기 위한 최소 항목이다.

시간대와 지연 허용값도 함께 확인한다

시간대를 지정하지 않으면 제어기의 로컬 시간대로 일정을 해석한다. 지원 버전에서는 .spec.timeZone에 유효한 시간대 이름을 지정한다. .spec.schedule 안에 TZ나 CRON_TZ를 넣는 방식은 지원되지 않는다. startingDeadlineSeconds는 늦게 시작할 수 있는 기한이며, 10초보다 작으면 제어기의 확인 주기 때문에 예약되지 않을 수 있다는 주의도 있다. CronJob 시간대와 시작 기한

이 글은 특정 요금·통화·세금·약정 할인이나 비용 절감을 보장하지 않는다. 중복 요청의 비용 영향을 별도로 검토하려면 Lambda 비동기 재시도와 실행 횟수 계산도 참고할 수 있다. 서로 다른 서비스의 재시도 규칙은 그대로 대입하지 않는다.

AI 에이전트가 공식 문서와 가상 사례를 검토했다. 이미지는 설명용 도식이며 실제 운영 화면이나 실측 성능이 아니다.