CronJob
Kubernetes CronJob
주기적으로 Job을 실행하는 Kubernetes 리소스. cron 문법으로 스케줄 정의.
Kubernetes CronJob
주기적으로 Job을 실행하는 Kubernetes 리소스. cron 문법으로 스케줄 정의.
CronJob은 Kubernetes에서 반복적인 작업을 자동화하는 워크로드 리소스입니다. Linux의 crontab과 동일한 문법(분 시 일 월 요일)을 사용하여 스케줄을 정의하며, 지정된 시간에 Job을 생성하고 Pod를 실행합니다.
CronJob이 도입되기 전에는 외부 스케줄러(Jenkins, Airflow)나 호스트의 crontab에 의존해야 했습니다. Kubernetes 1.21부터 CronJob이 정식(GA) 기능이 되면서, 클러스터 내부에서 스케줄링과 실행을 통합 관리할 수 있게 되었습니다.
CronJob은 내부적으로 Job 컨트롤러를 사용합니다. 스케줄 시간이 되면 CronJob 컨트롤러가 새로운 Job 오브젝트를 생성하고, Job 컨트롤러가 해당 Job의 Pod를 생성하여 작업을 수행합니다. 작업 완료 후 Pod는 종료되며, 히스토리 관리 정책에 따라 이전 Job들이 정리됩니다.
실무에서 CronJob은 데이터베이스 백업, 로그 정리, 리포트 생성, 캐시 갱신, 인증서 갱신 등 다양한 배치 작업에 활용됩니다. concurrencyPolicy와 startingDeadlineSeconds 설정을 통해 중복 실행과 지연 처리를 세밀하게 제어할 수 있습니다.
# 기본 CronJob 예제: 매일 새벽 2시 DB 백업
apiVersion: batch/v1
kind: CronJob
metadata:
name: db-backup
namespace: production
spec:
schedule: "0 2 * * *" # 매일 02:00 UTC
timeZone: "Asia/Seoul" # K8s 1.27+ 타임존 지원
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: postgres:15
command:
- /bin/sh
- -c
- |
pg_dump -h $DB_HOST -U $DB_USER $DB_NAME | \
gzip > /backup/db-$(date +%Y%m%d).sql.gz
env:
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-credentials
key: host
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: backup-volume
mountPath: /backup
restartPolicy: OnFailure
volumes:
- name: backup-volume
persistentVolumeClaim:
claimName: backup-pvc
"DB 백업을 CronJob으로 전환하면 Jenkins 의존성을 없앨 수 있어요. concurrencyPolicy를 Forbid로 설정해서 이전 백업이 진행 중이면 새 Job이 스킵되도록 하고, 실패 시 Slack 알림 연동도 추가합시다."
"CronJob과 Job의 차이를 설명드리면, Job은 한 번 실행되는 배치 작업이고 CronJob은 스케줄에 따라 Job을 반복 생성합니다. CronJob에서 startingDeadlineSeconds를 설정하면 컨트롤러 다운타임 동안 누락된 스케줄을 어느 범위까지 보정할지 제어할 수 있습니다."
"CronJob이 실행 안 된 원인을 확인해보니 startingDeadlineSeconds가 너무 짧게 설정되어 있었네요. 마스터 노드 롤링 업데이트 중에 데드라인을 넘겨서 스킵됐습니다. 300초 이상으로 늘리고 수동 Job으로 누락분 실행하겠습니다."
기본값은 kube-controller-manager의 타임존(보통 UTC)입니다. "0 9 * * *"이 한국시간 9시가 아닌 UTC 9시(한국 18시)에 실행됩니다. Kubernetes 1.27+에서는 spec.timeZone을 명시하세요.
successfulJobsHistoryLimit 기본값은 3이지만, 변경 시 무제한으로 두면 완료된 Job과 Pod가 계속 쌓여 etcd 부하가 증가합니다. 반드시 적절한 값을 설정하세요.
운영 환경에서는 ttlSecondsAfterFinished로 완료된 Job 자동 정리, activeDeadlineSeconds로 무한 실행 방지, 그리고 PrometheusRule로 Job 실패 알림을 설정하는 것이 좋습니다.