본문 바로가기

Cloud-native/Kubernetes

[Kubernetes]How to use Kubernetes CronJob and Job

Contents

  • CronJob의 Manifest 정의 및 배포
  • CronJob의 실행 시간 제약
  • CronJob의 동시성 관리
  • CronJob의 History Limit
  • Job의 Manifest 정의 및 배포

CronJob Manifest 정의 및 배포

cronjob-concurrency.yaml

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello-concurrency
spec:
  schedule: "*/1 * * * *"
  startingDeadlineSeconds: 600
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster; sleep 6000 # 6000초 동안 안끝나고 대기
          restartPolicy: OnFailure

이 CronJob은 1분마다 시간, 날짜, Hello from ~ 를 출력하는 새 컨테이너를 배포한다.

CronJob의 실행 시간 제약

.spec.startingDeadlineSeconds

  • 지정된 시간에 크론잡이 실행되지 못했을 때 필드 값으로 설정한 시간까지 지나면 크론잡이 실행되지 않게 한다. 이 필드 값을 설정하지 않으면 실행 시간이 지나더라도 제약 없이 잡이 실행된다.

CronJob의 동시성 관리

.spec.concurrencyPolicy

  • 크론잡이 실행하는 잡의 동시성을 관리한다.
    • 기본 값은 Allow고 크론 잡이 여러개 잡을 동시에 실행할 수 있도록 한다.
    • Forbid 로 설정하면 잡을 동시에 실행하지 않도록 한다. 새로운 잡을 실행할 시간이고 이전 잡 실행이 아직 완료되지 않은 경우, 크론 잡은 새로운 잡 실행을 건너뛴다.
    • Replace 로 설정하면 새로운 잡을 실행할 시간이고 이전 잡 실행이 아직 완료되지 않은 경우, 크론 잡은 현재 실행 중인 잡 실행을 새로운 잡 실행으로 대체한다.

적용

$ kubectl apply -f cronjob-concurrency.yaml
cronjob.batch/hello-concurrency created

$ kubectl get po | grep hello
hello-concurrency-1600782180-qt5vn            1/1     Running            0          20s
  • 6000초를 대기하도록 설정하였으므로, 1분이 지나고 다음 잡을 실행하려고 할때 기존 잡이 남아 있는 상태가 된다.
  • concurrencyPolicy: Forbid 로 설정하였으므로 잡이 동시에 실행되지 않고 기다린다. 즉, 처음 실행했던 작업이 끝나야 다음 작업이 실행된다.

.spec.concurrencyPolicy: Allow 로 변경

$ kubectl edit cronjob hello-concurrency
cronjob.batch/hello-concurrency edited

concurrencyPolicy: Allow

$ kubectl get po | grep hello
hello-concurrency-1600782180-qt5vn            1/1     Running   0          4m14s
hello-concurrency-1600782360-gjhtj            1/1     Running   0          24s
hello-concurrency-1600782420-fkhxg            1/1     Running   0          14s
  • 크론잡이 여러개 잡을 동시에 실행할 수 있도록 한다.

새로운 파드가 실행 됨을 확인 할 수 있다.

.spec.concurrencyPolicy: Replace 로 변경

$ kubectl edit cronjob hello-concurrency
cronjob.batch/hello-concurrency edited
concurrencyPolicy: Replace

$ kubectl get po | grep hello
hello-concurrency-1600782180-qt5vn            1/1     Terminating        0          6m50s
hello-concurrency-1600782360-gjhtj            1/1     Terminating        0          3m
hello-concurrency-1600782420-fkhxg            1/1     Terminating        0          2m50s
hello-concurrency-1600782480-swgnw            1/1     Terminating        0          109s
hello-concurrency-1600782540-2gmrg            1/1     Running            0          10s
  • 새로운 잡을 실행할 시간이고 이전 잡 실행이 아직 완료되지 않은 경우, 크론 잡은 현재 실행 중인 잡 실행을 새로운 잡 실행으로 대체한다.

남아 있던 잡들을 모두 종료시키고 새로 잡이 실행됨을 볼 수 있다.

suspend: false → true

$ kubectl get cronjob,po | grep hello
NAME                SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello-concurrency   */1 * * * *   True      1        2m50s           11m
pod/hello-concurrency-1600782660-fgk27            1/1     Running            0          2m28s

더이상 크론잡이 실행되지 않고 멈춘다. 단, 기존 실행중이던 잡이 멈추지는 않는다.

시간이 지나 확인해보면 .spec.concurrencyPolicy: Replace 라서 기존 파드를 종료하고 새로 파드를 설정해야하지만 대기 중임을 알 수 있다.

CronJob의 History Limit

cronjob.batch/hello-concurrency   */1 * * * *   True      1        13m             22m
pod/hello-1600783320-lx4xg                        0/1     Completed          0          2m40s
pod/hello-1600783380-cmk6w                        0/1     Completed          0          100s
pod/hello-1600783440-79s6n                        0/1     Completed          0          39s
pod/hello-concurrency-1600782660-fgk27            1/1     Running            0          13m

.spec.successfulJobsHistoryLimit

  • default: 3
    • 첫번째 예제는 default로 설정되어 잡이 3개 남아 있음을 확인할 수 있다.

.spec.failedJobsHistroyLimit

  • default 1
  • 0으로 설정하면 잡이 종료된 다음 내역을 저장하지 않는다.

Job 매니페스트 정의 및 배포

  • 이 Job은 파이 값을 2,000자리까지 계산한 다음 결과를 출력합니다.
apiVersion: batch/v1
kind: Job
metadata:
  # Unique key of the Job instance
  name: example-job
spec:
  template:
    metadata:
      name: example-job
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl"]
        args: ["-Mbignum=bpi", "-wle", "print bpi(2000)"]
      # Do not restart containers after they exit
      restartPolicy: Never

spec.restartPolicy: Never

  • Do not restart containers after they exit
$ kubectl describe job example-job
Name:             example-job
Namespace:        default
Selector:         controller-uid=ceac4dd2-d06a-4d9a-b8d4-3f891ab1a834
Labels:           controller-uid=ceac4dd2-d06a-4d9a-b8d4-3f891ab1a834
                  job-name=example-job
Annotations:      <none>
Parallelism:      1
Completions:      1
Completion Mode:  NonIndexed
Start Time:       Sun, 09 Oct 2022 09:56:43 +0000
Completed At:     Sun, 09 Oct 2022 09:57:16 +0000
Duration:         33s
Pods Statuses:    0 Active / 1 Succeeded / 0 Failed
Pod Template:
  Labels:  controller-uid=ceac4dd2-d06a-4d9a-b8d4-3f891ab1a834
           job-name=example-job
  Containers:
   pi:
    Image:      perl:5.34
    Port:       <none>
    Host Port:  <none>
    Command:
      perl
    Args:
      -Mbignum=bpi
      -wle
      print bpi(2000)
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  110s  job-controller  Created pod: example-job-2mhb7
  Normal  Completed         77s   job-controller  Job completed
$ kubectl get pods
NAME                READY   STATUS      RESTARTS   AGE
example-job-2mhb7   0/1     Completed   0          2m13s
$ kubectl get jobs
NAME          COMPLETIONS   DURATION   AGE
example-job   1/1           33s        2m32s
$ kubectl logs example-job-2mhb7
3.14159265358979323846264338327950288##중략

⚠️참고

CronJob은 Unix 표준 crontab 형식으로 시간을 허용하는 필수 schedule 필드를 사용합니다. 모든 CronJob 시간은 UTC 형식입니다.

  • 첫 번째 값은 분(0~59)을 나타냅니다.
  • 두 번째 값은 시간(0~23)을 나타냅니다.
  • 세 번째 값은 월중 일(1~31)을 나타냅니다.
  • 네 번째 값은 월(1~12)을 나타냅니다.
  • 다섯 번째 값은 주중 요일(0~6)을 나타냅니다.

schedule 필드는 *와 ?도 와일드 카드 값으로 허용합니다. 범위와 함께 /를 사용하면 태스크가 일정 간격으로 반복되도록 지정할 수 있습니다. 이 예에서 */1 * * * *는 태스크가 매월 매일에 1분마다 반복되어야 함을 나타냅니다.


https://kubernetes.io/ko/docs/tasks/job/automated-tasks-with-cron-jobs/