주기적 잡 패턴 은 Job 에 시간을 추가하여 작업 단위 실행이 시간적 이벤트에 의해
시작 되도록 하여 배치 잡 패턴 을 확장하도록 합니다.
쿠버네티스 패턴 - 7장 배치 잡 에서 Job 에 대한 개념을 배웠습니다.
이 때 Job 은 작은 단위의 작업을 완료를 목표로하는 컨테이너로 만들어 사용자에 의해서 실행됩니다.
하지만 작은 단위의 작업을 주기적으로 실행해야하는 경우 사용자를 번거롭게 하며
이메일 전송, 오래된 파일 정리 및 보관, 데이터베이스 조회와 같은 주기적 작업을 자동화하였을 때
또 하나의 관리 포인트가 되어 관리를 어렵게 만들었습니다.
쿠버네티스에서는 배치 잡 을 확장한 Cron Job 을 지원하여 이를 해결하였습니다.
Cron Job 은 유닉스 크론탭과 동일하게 시간적 측면에서 Job 을 관리하도록 합니다.
따라서 지정된 시간에 주기적으로 Job 을 수행하는 것이 가능하여 위의 문제를 해결할 수 있습니다.
이번 글에서는 Cron Job 의 사용 방법, 특징, 한계점에 대해서 알아보도록 하겠습니다.
Cron Job은 Job 을 확장한 것이기 때문에 job 의 Template 와 유사하게 작성하면됩니다.
다음은 yaml 예시입니다.
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
위의 예시는 매 분마다 현재 시간과 hello 메시지를 출력하는 Cron Job 입니다.
Cron Job 은 kubectl
명령어를 통해서 시작하고 확인할 수 있습니다.
다음은 명세를 작성하는 법에 대해서 알아보도록 하겠습니다.
0 * * * *
또는 @hourly
와 같이 Cron 형식의 문자열로 작성vixie cron
스텝 값도 포함하며 이 내용은 FreeBSD 매뉴얼 을 참고다음은 스케줄 문법에 대한 자세한 설명입니다.
# ┌───────────── 분 (0 - 59)
# │ ┌───────────── 시 (0 - 23)
# │ │ ┌───────────── 일 (1 - 31)
# │ │ │ ┌───────────── 월 (1 - 12)
# │ │ │ │ ┌───────────── 요일 (0 - 6) (일요일부터 토요일까지;
# │ │ │ │ │ 특정 시스템에서는 7도 일요일)
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
항목 | 설명 | 상응 표현 |
---|---|---|
@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 * * * * |
Allow
.spec.concurrencyPolicy
의 기본값Forbid
Replace
👌 참고로 해당 필드는 동일한 Cron Job 에 의해 생성된 Job 에만 허용됩니다.
따라서 Cron Job 이 여러 개인 경우, 각각의 Job 은 항상 동시에 실행될 수 있습니다.
true
로 설정되면 이미 시작된 실행에는 영향을 주지 않고 모든 후속 실행이 일시 정지 됨👌 스케줄된 시간에 Job 이 일시정지 되어있다면 누락된 Job 으로 간주하며
.spec.startingDeadlineSeconds
가 설정되지 않은 상태에서.spec.suspend
를true
에서false
로 변경하면 누락된 Job 이 즉시 스케줄 됨
0
으로 설정하면 Job 의 완료 후에 기록을 보관하지 않음Cron Job 은 일정의 실행시간 마다 약 한 번의 Job 오브젝트를 생성합니다.
즉, 특정 환경에서는 두 개 이상의 Job 이 만들어지거나 Job 이 생성이 되지 않을 수 있습니다.
👍 따라서 다음 한계를 생각하고 Cron Job 을 생성할 때는 항상 멱등성이 지켜지도록 만들어야합니다.
Cron Job 을 생성할 때 계속 실패하는 Job 이 생길 수 있기 때문에
startingDeadlineSeconds
를 통해서 관리합니다.
하지만 Cron Job Controller 는 10초 마다 Job 을 확인하기 때문에
startingDeadlineSeconds
가 10초 보다 작은 경우 Job 이 스케줄되지 않을 수 있습니다.
이 때 스케줄 되지 않은 Job 은 누락된 Job 으로 간주하며
100회 이상 누락될 경우 더 이상 Job을 실행하지 않고 다음과 같은 에러 로그를 남깁니다.
Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.
만약 Job 의 실행 주기보다 Job 의 실행시간이 더 짧고
concurrencyPolicy
가 Allow
로 되었다면 Job 이 두 개 이상 생길 수 있습니다.
만약 이메일 전송, 파일 삭제와 같은 작업이라면 불필요한 작업이 동시에 두번 이상 일어나는 경우가 생깁니다.
이를 위해서 concurrencyPolicy
를 Forbid
또는 Replace
로 하거나
startingDeadlineSeconds
를 적절한 값으로 세팅하는 것이 중요합니다.
Cron Job 은 정해진 일정에 Job 을 실행하지 못하면 누락되었다고 카운팅합니다.
예를 들어 concurrencyPolicy
가 Forbid
로 설정되었고
Cron Job 이 이전 일정이 끝나지 않은 상태에서 새로운 Job 을 실행할 때 누락되었다고 판단합니다.
여기서 누락된 Job 에 대한 처리는 startingDeadlineSeconds
의 설정에 따라 달라집니다.
startingDeadlineSeconds
이 설정 되지 않은 경우컨트롤러는 마지막 일정부터 지금까지 누락된 Job 을 카운팅 합니다.
예를 들어 08:00
부터 매 분마다 새로운 잡을 실행하도록 설정이 되어있고
startingDeadlineSeconds
가 없는 상태에서 08:00
부터 10:00
까지 컨트롤러가 고장이 나면
누락된 Job 의 수가 100개를 초과하여 더 이상 Job 이 실행되지 않을 것 입니다.
startingDeadlineSeconds
이 설정 된 경우컨트롤러는 마지막 일정부터 지금까지 누락된 Job을 카운팅 하지 않고
최근 startingDeadlineSecons
시간 내에 몇 개의 Job 이 누락되었는지 카운팅 합니다.
예를 들어 08:00
부터 매 분마다 새로운 잡을 실행하도록 설정이 되어있고
startingDeadlineSeconds
가 200
인 상태에서 08:00
부터 09:00
까지 컨트롤러가 고장이 나면
최근 200
초 내의 누락된 Job 인 3개가 09:01
에 스케줄 될 것 입니다.
지금까지 살펴본 바와 같이 Cron Job 은 매우 간단하고 편리하게 주기적인 작업을 관리할 수 있습니다.
또한 쿠버네티스의 여러가지 기능과 결합될 때 매우 강력한 Job 스케줄링 시스템이 됩니다.
이를 통해서 개발자는 도메인 문제, 비즈니스 로직 수행만 생각하고 어플리케이션을 구현할 수 있습니다.
감사합니다 ~ :)