쿠버네티스 패턴 - 8장 주기적 잡

오정재·2021년 5월 1일
4

쿠버네티스 패턴

목록 보기
9/12
post-thumbnail

👉 주기적 잡

주기적 잡 패턴Job시간을 추가하여 작업 단위 실행시간적 이벤트에 의해
시작 되도록 하여 배치 잡 패턴 을 확장하도록 합니다.

🍏 문제점

쿠버네티스 패턴 - 7장 배치 잡 에서 Job 에 대한 개념을 배웠습니다.
이 때 Job작은 단위의 작업을 완료를 목표로하는 컨테이너로 만들어 사용자에 의해서 실행됩니다.

하지만 작은 단위의 작업을 주기적으로 실행해야하는 경우 사용자를 번거롭게 하며
이메일 전송, 오래된 파일 정리 및 보관, 데이터베이스 조회와 같은 주기적 작업을 자동화하였을 때
하나의 관리 포인트가 되어 관리를 어렵게 만들었습니다.

🍏 해결책

쿠버네티스에서는 배치 잡 을 확장한 Cron Job 을 지원하여 이를 해결하였습니다.
Cron Job유닉스 크론탭과 동일하게 시간적 측면에서 Job 을 관리하도록 합니다.
따라서 지정된 시간에 주기적으로 Job 을 수행하는 것이 가능하여 위의 문제를 해결할 수 있습니다.

이번 글에서는 Cron 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 Jobkubectl 명령어를 통해서 시작하고 확인할 수 있습니다.

다음은 명세를 작성하는 법에 대해서 알아보도록 하겠습니다.

1) .spec.schedule

  • Job 이 실행되는 스케줄 시간으로 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 * * * *

2) .spec.startingDeadlineSeconds

  • Job 의 시작 기한을 초 단위로 나타내기 위해 사용되며 선택적 필드
  • Job 이 스케줄된 시간을 놓친 경우 해당 시간 안에 시작되지 않으면 실패한 작업으로 간주
  • Job 의 시작이 예정된 시간이 아닌 조금이라도 늦게 시작되면 안되는 경우에 유용

3) .spec.concurrencyPolicy

  • Cron Job 에 의해 생성된 Job 의 동시 실행을 처리하는 방법을 명시하는 필드
  • Allow
    • 동시에 실행되는 Job 을 허용
    • .spec.concurrencyPolicy 의 기본값
  • Forbid
    • 동시에 실행되는 Job 을 허용하지 않음
    • 새로운 Job 을 실행할 시간이지만 이전 Job 실행이 완료되지 않은 경우 Job의 실행을 건너뜀
  • Replace
    • 새로운 Job 을 실행할 시간이고 이전 Job 실행이 완료되지 않은 경우 새로운 Job 실행으로 대체

👌 참고로 해당 필드는 동일한 Cron Job 에 의해 생성된 Job 에만 허용됩니다.
따라서 Cron Job 이 여러 개인 경우, 각각의 Job 은 항상 동시에 실행될 수 있습니다.

4) .spec.suspend

  • true 로 설정되면 이미 시작된 실행에는 영향을 주지 않고 모든 후속 실행이 일시 정지 됨

👌 스케줄된 시간에 Job 이 일시정지 되어있다면 누락된 Job 으로 간주하며 .spec.startingDeadlineSeconds 가 설정되지 않은 상태에서 .spec.suspendtrue 에서 false 로 변경하면 누락된 Job 이 즉시 스케줄 됨

5) .spec.successfulJobsHistoryLimit / .spec.failedJobsHistoryLimit

  • 기록을 보관해야 하는 완료 및 실패한 잡의 개수를 지정하는 필드
  • 0 으로 설정하면 Job 의 완료 후에 기록을 보관하지 않음

Cron Job의 한계

Cron Job 은 일정의 실행시간 마다 약 한 번의 Job 오브젝트를 생성합니다.
즉, 특정 환경에서는 두 개 이상의 Job 이 만들어지거나 Job 이 생성이 되지 않을 수 있습니다.

👍 따라서 다음 한계를 생각하고 Cron Job 을 생성할 때는 항상 멱등성이 지켜지도록 만들어야합니다.

1) Job이 생성이 안되는 문제

Cron Job 을 생성할 때 계속 실패하는 Job 이 생길 수 있기 때문에
startingDeadlineSeconds 를 통해서 관리합니다.

하지만 Cron Job Controller10초 마다 Job 을 확인하기 때문에
startingDeadlineSeconds10초 보다 작은 경우 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.

2) Job이 두 개 이상 생기는 문제

만약 Job 의 실행 주기보다 Job 의 실행시간이 더 짧고
concurrencyPolicyAllow 로 되었다면 Job 이 두 개 이상 생길 수 있습니다.

만약 이메일 전송, 파일 삭제와 같은 작업이라면 불필요한 작업이 동시에 두번 이상 일어나는 경우가 생깁니다.
이를 위해서 concurrencyPolicyForbid 또는 Replace 로 하거나
startingDeadlineSeconds 를 적절한 값으로 세팅하는 것이 중요합니다.

3) 누락된 Job

Cron Job 은 정해진 일정에 Job 을 실행하지 못하면 누락되었다고 카운팅합니다.

예를 들어 concurrencyPolicyForbid 로 설정되었고
Cron Job 이 이전 일정이 끝나지 않은 상태에서 새로운 Job 을 실행할 때 누락되었다고 판단합니다.

여기서 누락된 Job 에 대한 처리는 startingDeadlineSeconds 의 설정에 따라 달라집니다.

3-1) startingDeadlineSeconds 이 설정 되지 않은 경우

컨트롤러는 마지막 일정부터 지금까지 누락된 Job 을 카운팅 합니다.

예를 들어 08:00 부터 매 분마다 새로운 잡을 실행하도록 설정이 되어있고
startingDeadlineSeconds 가 없는 상태에서 08:00 부터 10:00 까지 컨트롤러가 고장이 나면
누락된 Job 의 수가 100개를 초과하여 더 이상 Job 이 실행되지 않을 것 입니다.

3-2) startingDeadlineSeconds 이 설정 된 경우

컨트롤러는 마지막 일정부터 지금까지 누락된 Job을 카운팅 하지 않고
최근 startingDeadlineSecons 시간 내에 몇 개의 Job 이 누락되었는지 카운팅 합니다.

예를 들어 08:00 부터 매 분마다 새로운 잡을 실행하도록 설정이 되어있고
startingDeadlineSeconds200인 상태에서 08:00 부터 09:00 까지 컨트롤러가 고장이 나면
최근 200 초 내의 누락된 Job 인 3개09:01 에 스케줄 될 것 입니다.

🍏 정리

지금까지 살펴본 바와 같이 Cron Job 은 매우 간단하고 편리하게 주기적인 작업을 관리할 수 있습니다.
또한 쿠버네티스의 여러가지 기능과 결합될 때 매우 강력한 Job 스케줄링 시스템이 됩니다.

이를 통해서 개발자는 도메인 문제, 비즈니스 로직 수행만 생각하고 어플리케이션을 구현할 수 있습니다.

👉 Reference

profile
ohhong

1개의 댓글

comment-user-thumbnail
2021년 5월 13일

감사합니다 ~ :)

답글 달기