본문으로 건너뛰기
김신건의 로그

[K8s] Job / CronJob: 일회성 + 스케줄 작업

· 수정 · 📖 약 1분 · 229자/단어 #kubernetes #job #cronjob #batch #k8s
K8s Job, K8s CronJob, completions, parallelism, backoffLimit, TTLAfterFinished

정의

컨트롤러의미
Job완료까지 실행하는 일회성 작업
CronJob스케줄 (cron) 에 따라 Job 생성

Job

apiVersion: batch/v1
kind: Job
metadata: { name: migrate }
spec:
  backoffLimit: 3                # 실패 시 재시도 한도
  ttlSecondsAfterFinished: 3600  # 완료 후 1시간 뒤 정리
  template:
    spec:
      restartPolicy: OnFailure
      containers:
        - name: migrate
          image: app:v2
          command: ['python', 'manage.py', 'migrate']

흐름

stateDiagram-v2
    [*] --> Active: Job 생성
    Active --> Succeeded: completions 달성
    Active --> Failed: backoffLimit 초과
    Succeeded --> Cleaned: TTL 후 자동 삭제
    Failed --> Cleaned: TTL 후

병렬 실행 (parallelism / completions)

spec:
  completions: 10       # 총 10개 완료 필요
  parallelism: 3        # 동시 3개 실행
패턴의미
completions=1, parallelism=1단일 작업 (기본)
completions=N, parallelism=NN개 병렬
completions=N, parallelism=M < N동시 M, 총 N
completions=null, parallelism=M무한 (작업 큐 패턴)

작업 큐 패턴

flowchart LR
    Queue[(Job Queue<br/>Redis / SQS)] --> P1[Pod 1]
    Queue --> P2[Pod 2]
    Queue --> P3[Pod 3]
    P1 --> Output[(처리 완료)]
    P2 --> Output
    P3 --> Output

각 pod 가 큐에서 work 가져와 처리 후 종료. completions 없이 queue 가 빌 때까지.

Indexed Job (1.24+)

spec:
  completions: 10
  parallelism: 3
  completionMode: Indexed
  template:
    spec:
      containers:
        - name: worker
          image: app:v1
          env:
            - name: JOB_COMPLETION_INDEX
              valueFrom:
                fieldRef:
                  fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index']

각 pod 가 고유 인덱스 (0..N-1). 파티션된 작업 분배.

CronJob

apiVersion: batch/v1
kind: CronJob
metadata: { name: nightly-backup }
spec:
  schedule: "0 2 * * *"           # 매일 2시
  timeZone: "Asia/Seoul"           # K8s 1.27+
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  concurrencyPolicy: Forbid       # 이전 job 끝나기 전 새 job 안 만듦
  startingDeadlineSeconds: 300    # 5분 안에 시작 못 하면 skip
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: backup
              image: db-backup:v1

concurrencyPolicy

정책의미
Allow (기본)동시 실행 허용
Forbid이전 job 끝나기 전 새 job skip
Replace이전 job 중단 + 새 job

Cron 식

┌──── 분 (0-59)
│ ┌── 시 (0-23)
│ │ ┌── 일 (1-31)
│ │ │ ┌── 월 (1-12)
│ │ │ │ ┌── 요일 (0-6, 0=Sun)
│ │ │ │ │
0 2 * * *    매일 2시
*/15 * * * * 15분마다
0 9 * * 1-5  평일 9시

흔한 함정

WARNING

  1. restartPolicy: Always = Job 의 의미 깨짐. OnFailure 또는 Never.
  2. ttlSecondsAfterFinished 없음 = 완료된 Job 누적. cluster cluttered.
  3. CronJob 의 시간대 = K8s 1.27+ 까지 UTC 만. timeZone 명시 권장.
  4. concurrencyPolicy: Allow + 무거운 작업 = job 들이 겹쳐 시스템 부하. Forbid 안전.
  5. JOB 실패 알림 부재 = silent fail. Prometheus + Alertmanager 로 failed Job 알림.

관련 위키

이 글의 용어 (4개)
[Distributed] Kafka: 분산 로그, partition, consumer groupdistributed-systems
정의 Apache Kafka = 분산 commit log. 고처리량 (수백만 msg/s), 영속, 수평 확장. event-driven 아키텍처 의 de facto. 핵심 개념: …
[K8s] Deployment: ReplicaSet, rolling update, rollbackkubernetes
정의 Deployment = stateless 워크로드를 위한 컨트롤러. 내부적으로 ReplicaSet 관리 + rolling update / rollback. 계층 | 객체 |…
[K8s] Pod: 컨테이너의 최소 단위, sidecar, lifecyclekubernetes
정의 Pod = K8s 의 가장 작은 배포 단위. 1개 이상의 컨테이너 + 공유 네트워크 + 공유 스토리지. [!IMPORTANT] Pod 는 컨테이너의 wrapping 이 아니…
[Observability] Prometheus: pull 기반 메트릭, PromQLdevops
정의 Prometheus = pull 기반 시계열 metric 시스템. PromQL 로 쿼리. CNCF graduated. 2026 클라우드 네이티브 메트릭 표준. 아키텍처 Pu…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기