해당 문서의 쿠버네티스 버전: v1.25

Kubernetes v1.25 문서는 더 이상 적극적으로 관리되지 않음. 현재 보고있는 문서는 정적 스냅샷임. 최신 문서를 위해서는, 다음을 참고. 최신 버전.

크론잡

기능 상태: Kubernetes v1.21 [stable]

크론잡은 반복 일정에 따라 을 만든다.

하나의 크론잡 오브젝트는 크론탭 (크론 테이블) 파일의 한 줄과 같다. 크론잡은 잡을 크론 형식으로 쓰여진 주어진 일정에 따라 주기적으로 동작시킨다.

크론잡 리소스에 대한 매니페스트를 생성할 때에는 제공하는 이름이 유효한 DNS 서브도메인 이름이어야 한다. 이름은 52자 이하여야 한다. 이는 크론잡 컨트롤러는 제공된 잡 이름에 11자를 자동으로 추가하고, 작업 이름의 최대 길이는 63자라는 제약 조건이 있기 때문이다.

크론잡

크론잡은 백업, 리포트 생성 등의 정기적 작업을 수행하기 위해 사용된다. 각 작업은 무기한 반복되도록 구성해야 한다(예: 1일/1주/1달마다 1회). 작업을 시작해야 하는 해당 간격 내 특정 시점을 정의할 수 있다.

예시

이 크론잡 매니페스트 예제는 현재 시간과 hello 메시지를 1분마다 출력한다.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

(크론잡으로 자동화된 작업 실행하기는 이 예시를 더 자세히 설명한다.)

크론 스케줄 문법

# ┌───────────── 분 (0 - 59)
# │ ┌───────────── 시 (0 - 23)
# │ │ ┌───────────── 일 (1 - 31)
# │ │ │ ┌───────────── 월 (1 - 12)
# │ │ │ │ ┌───────────── 요일 (0 - 6) (일요일부터 토요일까지;
# │ │ │ │ │                                   특정 시스템에서는 7도 일요일)
# │ │ │ │ │                                   또는 sun, mon, tue, wed, thu, fri, sat
# │ │ │ │ │
# * * * * *
항목설명상응 표현
@yearly (or @annually)매년 1월 1일 자정에 실행0 0 1 1 *
@monthly매월 1일 자정에 실행0 0 1 * *
@weekly매주 일요일 자정에 실행0 0 * * 0
@daily (or @midnight)매일 자정에 실행0 0 * * *
@hourly매시 0분에 시작0 * * * *

예를 들면, 다음은 해당 작업이 매주 금요일 자정에 시작되어야 하고, 매월 13일 자정에도 시작되어야 한다는 뜻이다.

0 0 13 * 5

크론잡 스케줄 표현을 생성하기 위해서 crontab.guru와 같은 웹 도구를 사용할 수도 있다.

타임 존

크론잡에 타임 존이 명시되어 있지 않으면, kube-controller-manager는 로컬 타임 존을 기준으로 스케줄을 해석한다.

기능 상태: Kubernetes v1.25 [beta]

CronJobTimeZone 기능 게이트를 활성화하면, 크론잡에 대해 타임 존을 명시할 수 있다(기능 게이트를 활성화하지 않거나, 타임 존에 대한 실험적 지원을 제공하지 않는 쿠버네티스 버전을 사용 중인 경우, 클러스터의 모든 크론잡은 타임 존이 명시되지 않은 것으로 동작한다).

이 기능을 활성화하면, spec.timeZone을 유효한 타임 존 이름으로 지정할 수 있다. 예를 들어, spec.timeZone: "Etc/UTC"와 같이 설정하면 쿠버네티스는 협정 세계시를 기준으로 스케줄을 해석한다.

Go 표준 라이브러리의 타임 존 데이터베이스가 바이너리로 인클루드되며, 시스템에서 외부 데이터베이스를 사용할 수 없을 때 폴백(fallback)으로 사용된다.

크론잡의 한계

크론잡은 일정의 실행시간 마다 한 번의 잡 오브젝트를 생성한다. "약" 이라고 하는 이유는 특정 환경에서는 두 개의 잡이 만들어지거나, 잡이 생성되지 않기도 하기 때문이다. 보통 이렇게 하지 않도록 해야겠지만, 완벽히 그럴 수는 없다. 따라서 잡은 멱등원 이 된다.

만약 startingDeadlineSeconds 가 큰 값으로 설정되거나, 설정되지 않고(디폴트 값), concurrencyPolicyAllow 로 설정될 경우, 잡은 항상 적어도 한 번은 실행될 것이다.

모든 크론잡에 대해 크론잡 컨트롤러 는 마지막 일정부터 지금까지 얼마나 많은 일정이 누락되었는지 확인한다. 만약 100회 이상의 일정이 누락되었다면, 잡을 실행하지 않고 아래와 같은 에러 로그를 남긴다.

Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.

중요한 것은 만약 startingDeadlineSeconds 필드가 설정이 되면(nil 이 아닌 값으로), 컨트롤러는 마지막 일정부터 지금까지 대신 startingDeadlineSeconds 값에서 몇 개의 잡이 누락되었는지 카운팅한다. 예를 들면, startingDeadlineSeconds200 이면, 컨트롤러는 최근 200초 내 몇 개의 잡이 누락되었는지 카운팅한다.

크론잡은 정해진 일정에 잡 실행을 실패하면 놓쳤다고 카운팅된다. 예를 들면, concurrencyPolicyForbid 로 설정되었고, 크론잡이 이전 일정이 스케줄되어 여전히 시도하고 있을 때, 그 때 누락되었다고 판단한다.

즉, 크론잡이 08:30:00 에 시작하여 매 분마다 새로운 잡을 실행하도록 설정이 되었고, startingDeadlineSeconds 값이 설정되어 있지 않는다고 가정해보자. 만약 크론잡 컨트롤러가 08:29:00 부터 10:21:00 까지 고장이 나면, 일정을 놓친 작업 수가 100개를 초과하여 잡이 실행되지 않을 것이다.

이 개념을 더 자세히 설명하자면, 크론잡이 08:30:00 부터 매 분 실행되는 일정으로 설정되고, startingDeadlineSeconds 이 200이라고 가정한다. 크론잡 컨트롤러가 전의 예시와 같이 고장났다고 하면 (08:29:00 부터 10:21:00 까지), 잡은 10:22:00 부터 시작될 것이다. 이 경우, 컨트롤러가 마지막 일정부터 지금까지가 아니라, 최근 200초 안에 얼마나 놓쳤는지 체크하기 때문이다. (여기서는 3번 놓쳤다고 체크함)

크론잡은 오직 그 일정에 맞는 잡 생성에 책임이 있고, 잡은 그 잡이 대표하는 파드 관리에 책임이 있다.

컨트롤러 버전

쿠버네티스 v1.21부터 크론잡 컨트롤러의 두 번째 버전이 기본 구현이다. 기본 크론잡 컨트롤러를 비활성화하고 대신 원래 크론잡 컨트롤러를 사용하려면, CronJobControllerV2 기능 게이트 플래그를 kube-controller-manager에 전달하고, 이 플래그를 false 로 설정한다. 예를 들면, 다음과 같다.

--feature-gates="CronJobControllerV2=false"

다음 내용

  • 크론잡이 의존하고 있는 파드 두 개념에 대해 배운다.
  • 크론잡 .spec.schedule 필드의 형식에 대해서 읽는다.
  • 크론잡을 생성하고 다루기 위한 지침 및 크론잡 매니페스트의 예제로 크론잡으로 자동화된 작업 실행를 읽는다.
  • 실패했거나 완료된 잡을 자동으로 정리하도록 하려면, 완료된 잡을 자동으로 정리를 확인한다.
  • CronJob은 쿠버네티스 REST API의 일부이다. CronJob 오브젝트 정의를 읽고 쿠버네티스 크론잡 API에 대해 이해한다.
최종 수정 March 12, 2024 at 8:26 AM PST: Merge pull request #45495 from steve-hardman/fix-1.25 (8eb33af)