본문 바로가기

Infrastructure/Kubernetes

[워크로드 리소스] 크론잡

크론잡

쿠버네티스 공식문서를 확인하며 크론잡에 대해서 기억해야 하는 부분을 기록한다.

  • 크론잡은 반복 일정에 따라 잡을 만든다.
  • 하나의 크론잡 오브젝트는 크론탭 파일의 한 줄과 같으며, 크론잡은 잡을 크론 형식으로 쓰여진 주어진 일정에 따라 주기적으로 동작시킨다.
  • 모든 크론잡의 일정: 시간은 kube-controller-manager의 시간대를 기준으로 한다.
  • 컨트롤 플레인이 파드 또는 베어 컨테이너에서 kube-controller-manager를 실행하는 경우, kube-controller-manager 컨테이너에 설정된 시간대는 크론잡 컨트롤러가 사용하는 시간대로 결정한다.
  • v1 CronJob API는 위에서 알아본 타임존 설정을 공식적으로 지원하지는 않는다.
    CRON_TZ 또는 TZ와 같은 변수를 설정하는 것은 쿠버네티스 프로젝트에서 공식적으로 지원하지는 않는다.
    CRON_TZ 또는 TZ와 같은 변수를 설정하는 것은 크론탭을 파싱하고 다음 잡 생성 시간을 계산하는 내부 라이브러리의 구현 상세사항이므로 프로덕션 클러스터에서는 사용을 권장하지 않는다.
  • 크론잡 리소스에 대한 매니페스트를 생성할 때에는 제공하는 이름이 유효한 DNS 서브도메인 이름이어야 한다. 이름은 52자 이하여야 하는데 최대 길이 63자에서 크론잡 컨트롤러가 제공된 이름에 11자를 자동으로 추가하기 때문이다.

크론잡

  • 크론잡은 백업, 리포트 생성 등의 정기적인 작업을 수행하기 위해 사용되며, 각 작업은 무기한 반복되도록 구성해야 한다. 작업을 시작해야 하는 해당 간격 내 특정 시점을 정의할 수 있다.

  • 아래는 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
# │ │ │ │ │
# * * * * *
항목 설명 상응 표현
@year 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 * * * *

[정리]

크론잡은 일정 주기로 잡을 생성하여 작업을 해야할 때 사용된다. 리소스의 이름은 최대 52자까지 사용이 가능하다. 스케줄에 사용되는 문법은 Linux 크론에서 사용되는 문법과 동일하다.


타임존

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

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

  • spec.timeZone을 유효한 타임존 이름으로 지정하여 기능을 활성화할 수 있다. 만약 협정 세계시를 기준으로 스케줄하고 싶다면 아래와 같이 설정하면 된다.

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

[정리]

타임존을 설정하지 않으면 로컬 타임 존을 기준으로 스케줄을 해석한다. 만약 CronJobTimeZone 기능을 활성화하지 않거나 지원하지 않는 쿠버네티스 버전을 사용하고 있다면 타임존을 지정하지 않은 것과 동일하게 작동한다.


크론잡의 한계

  • 크론잡은 일정의 실행시간마다 “약” 한 번의 잡 오브젝트를 생성한다. 특정 환경에서 두 개의 잡이 만들어지거나, 잡이 생성되지 않는 경우도 있을 수 있기 때문에 무조건 한 번의 잡 오브젝트가 생성된다는 표현은 맞지 않다.

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

  • startingDeadlineSeconds가 10초 미만의 값으로 설정되면, 크론잡 컨트롤러가 10초마다 항목을 확인하기 때문에 크론잡이 스케줄되지 않을 수 있다.

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

      Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.
  • startingDeadlineSecondsnull이 아닌 값으로 설정되면, 컨트롤러는 마지막 일정부터 지금까지 대신 startingDeadlineSeconds 값에서 몇 개의 잡이 누락되었는지 카운팅한다.

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

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

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

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

[정리]

크론잡은 특별한 경우가 아니라면 일정 시간마다 한 번의 잡 오브젝트를 생성한다. 크론잡 컨트롤러는 마지막 일정부터 지금까지 얼마나 많은 잡이 누락되었는지 확인하는데 100회 이상 누락되었다면 더 이상 잡을 실행시키지 않기 때문에 관리자는 이점을 기억해야 한다.

크론잡은 잡을 생성하는 책임이 있고, 잡은 잡을 대표하는 파드를 관리하는 데 책임이 있다.


컨트롤러 버전

  • 쿠버네티스 v1.21부터 크론잡 컨트롤러의 두 번째 버전이 기본 구현이다.

  • 기본 크론잡 컨트롤러를 비활성화하고 대신 기존의 크론잡 컨트롤러를 사용하려면, CronJobControllerV2 기능 게이트 플래그를 kube-controller-manager에 전달하고, 해당 플래그를 false로 설정한다. 예시는 아래와 같다.

      --feature-gates="CronJobControllerV2=false" 

[정리]

최신 쿠버네티스 버전에서 크론잡 컨트롤러는 CronJobControllerV2가 공식버전이며, 이전 버전을 사용하기 위해서는 특정 플래그의 값을 변경 해주어야 한다.


참고 자료