[쿠버네티스 패턴] 8장 CronJob

bocopile·2025년 9월 10일

쿠버네티스 패턴

목록 보기
6/28

1. 내용 정리

1) CronJob의 개념

  • Job: 한 번 실행해서 성공/실패 여부가 명확한 배치 작업.
  • CronJob: Job을 일정한 주기로 반복 실행하도록 스케줄링한 리소스.
  • 리눅스의 crontab 과 유사하게 Cron 표현식을 사용해 실행 주기를 지정.

2) Cron 표현식

  • 포맷: 분 시 일 월 요일
  • 예시:
    • 0 * * * * → 매 시 정각
    • /5 * * * * → 5분마다 실행
    • 0 2 * * 1 → 매주 월요일 새벽 2시
  • CronJob은 이 표현식을 기반으로 Job을 생성합니다.

3) CronJob 리소스 정의

apiVersion: batch/v1
kind: CronJob
metadata:
  name: sample-cronjob
spec:
  schedule: "*/5 * * * *"         # 5분마다 실행
  suspend: false                  # false → 정상 동작 / true → 일시 중지
  concurrencyPolicy: Forbid       # 이전 Job이 끝나야 새 Job 실행
  startingDeadlineSeconds: 100    # 실행 지연 허용 시간
  successfulJobsHistoryLimit: 3   # 성공 Job 3개까지 기록 유지
  failedJobsHistoryLimit: 1       # 실패 Job 1개까지 기록 유지
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo "Hello from CronJob"
  • .spec.schedule
    • Cron 표현식으로 실행 주기 지정
  • .spec.jobTemplate
    • 실제 실행할 Job의 Pod 정의 포함
  • .spec.suspend
    • true → CronJob 실행 일시 중지 (새 Job 생성 안 됨)
    • false → 정상 동작 (기본값)
  • .spec.startingDeadlineSeconds
    • 스케줄이 지났을 때, 지연 실행을 허용하는 최대 초 단위 시간
  • .spec.concurrencyPolicy
    • Allow: 동시에 여러 Job 실행 허용 (기본값)
    • Forbid: 이전 Job이 끝날 때까지 대기
    • Replace: 실행 중 Job을 종료하고 새 Job으로 교체
  • .spec.successfulJobsHistoryLimit
    • 성공한 Job의 기록 보존 개수
  • .spec.failedJobsHistoryLimit
    • 실패한 Job의 기록 보존 개수

4) CronJob 동작 방식

  1. Cron 표현식에 따라 스케줄러가 Job 생성
  2. Job이 Pod를 생성하여 실행
  3. 성공/실패 여부에 따라 Job 상태 기록
  4. 기록 보존 개수(historyLimit)를 넘어가면 오래된 Job은 삭제됨

5) CronJob의 활용 사례

  • 주기적인 로그 정리
  • 백업 작업 (DB dump 등)
  • 정기 보고서 생성
  • 배치 데이터 처리

6) CronJob 주의 사항

  • Job 실행 시간이 길 경우 → 스케줄과 겹치면 중복 실행 가능 → concurrencyPolicy로 제어 필요
  • 스케줄이 너무 짧으면 (* * *) → 관리 비용과 부하가 증가
  • 실패 시 재시도(backoffLimit 등) 설정 고려
  • Controller가 생성한 Job/Pod를 통해 상태를 확인해야 함

7. 내용 보강 (kubernetes v1.34 버전 기준)

  • 쿠버네티스 v1.34 버전에선 CronJob에 대한 정의나, 동작 방식이 변경되진 않았지마 Job 실행 및 리소스 관리 측면에서 두 가지 중요한 개선 사항이 적용되어 CronJob 기반 배치 작업의 안정성과 효율이 한층 강화되었습니다.

1) Pod 교체 타이밍 제어 (Pod Replacement Policy GA)

기존에는 Job이 Pod를 다시 생성할 때 주로 실패하거나 종료 중(Terminating)인 경우에 새 Pod가 생성되었습니다. 하지만 v1.34부터는 Pod 교체 정책(Pod Replacement Policy) 이 정식으로 GA(General Availability) 상태에 도달하여, CronJob이 생성하는 Job에도 더 세밀한 제어가 가능해졌습니다.

  • TerminatingOrFailed (기본값) Pod가 종료 중이거나 실패한 경우 새 Pod 생성 가능
  • Failed Pod가 완전히 실패(Failed) 상태일 때만 새 Pod 생성

3. 실습

1) CronJob 기본 실습 (성공)

  • 코드 작성 (cronjob-success.yaml)
    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: success-cronjob
      annotations:
        email: "gjrjr4545@gmail.com"
    spec:
      schedule: "*/2 * * * *"       # 2분마다 실행
      concurrencyPolicy: Forbid     # 중복 실행 방지
      jobTemplate:
        spec:
          template:
            spec:
              restartPolicy: OnFailure
              containers:
                - name: success
                  image: busybox:1.36.1
                  args:
                    - /bin/sh
                    - -c
                    - "date; echo 'Success CronJob executed successfully'"
                  securityContext:
                    runAsNonRoot: true
                    runAsUser: 1000
                    readOnlyRootFilesystem: true
                  resources:
                    requests:
                      cpu: "50m"
                      memory: "32Mi"
                    limits:
                      cpu: "100m"
                      memory: "64Mi"
    
  • 코드 배포 및 확인
    kubectl apply -f cronjob-success.yaml
    kubectl get cronjobs,pods,jobs
    kubectl describe cronjob success-cronjob
    
    # 성공한 파드 조회
    kubectl get pods -A --field-selector=status.phase=Succeeded
    kubectl logs <pod이름>
  • 확인 결과

2) CronJob 기본 실습 (실패)

  • 코드 작성
    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: fail-cronjob
      annotations:
        email: "gjrjr4545@gmail.com"
    spec:
      schedule: "*/2 * * * *"       # 2분마다 실행
      concurrencyPolicy: Forbid     # 중복 실행 방지
      jobTemplate:
        spec:
          template:
            spec:
              restartPolicy: OnFailure
              containers:
                - name: fail
                  image: busybox:1.36.1
                  args:
                    - /bin/sh
                    - -c
                    - "echo 'Fail CronJob executed'; exit 1"
                  securityContext:
                    runAsNonRoot: true
                    runAsUser: 1000
                    readOnlyRootFilesystem: true
                  resources:
                    requests:
                      cpu: "50m"
                      memory: "32Mi"
                    limits:
                      cpu: "100m"
                      memory: "64Mi"
    
  • 코드 배포 및 확인
    kubectl apply -f cronjob-fail.yaml
    
    kubectl get cronjob,pods,jobs 
    kubectl describe cronjob fail-cronjob
    
    kubectl logs <pod이름>
  • 확인 결과

3) Pod Replacement Policy 실습

  • 코드 작성
    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: replacement-cronjob
      annotations:
        email: "gjrjr4545@gmail.com"
    spec:
      schedule: "*/3 * * * *"   # 3분마다 실행
      jobTemplate:
        spec:
          podReplacementPolicy: Failed   # v1.34 GA 기능
          template:
            spec:
              restartPolicy: OnFailure
              containers:
                - name: fail-test
                  image: busybox:1.36.1
                  args:
                    - /bin/sh
                    - -c
                    - "echo 'Test Replacement Policy'; exit 1"
                  securityContext:
                    runAsNonRoot: true
                    runAsUser: 1000
                    readOnlyRootFilesystem: true
                  resources:
                    requests:
                      cpu: "50m"
                      memory: "32Mi"
                    limits:
                      cpu: "100m"
                      memory: "64Mi"
    
  • 코드 적용
    kubectl apply -f cronjob-replacement.yaml
  • 배포 확인
    kubectl get cronjobs
    kubectl get pods -w
    kubectl describe cronjob replacement-cronjob
  • 확인 결과 : Error → CrashLoopBackOff 하여 지속적으로 파드 교체

4. 출처

profile
DevOps Engineer

2개의 댓글

comment-user-thumbnail
2025년 9월 14일

안녕하세요. 작성해주신 글 잘 읽었습니다. 혹시 podReplacementPolicy 이 필드가 미치는 영향이 restartPolicy와 어떻게 다른지 알 수 있을까요? 특히 restartPolicy: OnFailure 를 사용할 경우 Pod가 재시작될 것 같은데 이 경우엔 podReplacementPolicy을 설정하여도 영향을 받지 않는걸까요?

1개의 답글