배치 작업을 Job으로 돌렸는데 실패한 Pod가 끝없이 쌓이거나, 반대로 일시적 오류 한 번에 Job 전체가 Failed로 끝나버린 경험이 있을 겁니다. 핵심은 backoffLimit입니다. 이 값은 Job이 실패를 몇 번까지 재시도할지 정하는 한도이고, 기본값은 6입니다.
재시도가 어떻게 도는지
Job이 만든 Pod가 실패하면 컨트롤러가 새 Pod를 만들어 재시도합니다. 재시도 간격은 10초에서 시작해 두 배씩 늘어나며 최대 6분까지 지수적으로 증가합니다. 재시도 횟수가 backoffLimit에 도달하면 Job은 Failed로 확정되고 더 이상 Pod를 만들지 않습니다.
Kubernetes
# Job 상태와 완료/실패 카운트 확인
kubectl get job <job> -o wide
# 실패 사유와 backoff 이벤트 확인
kubectl describe job <job>
describe 출력의 Pods Statuses와 Events에서 BackoffLimitExceeded가 보이면 한도를 모두 소진한 것입니다.
핵심 필드 3가지
| 필드 | 역할 | 권장 |
|---|---|---|
backoffLimit | 실패 재시도 한도 | 멱등 작업은 그대로, 비멱등은 0~2 |
restartPolicy | Pod 내 컨테이너 재시작 정책 | Job은 Never 또는 OnFailure만 허용 |
activeDeadlineSeconds | Job 전체 제한 시간 | 멈춰서 매달리는 작업 강제 종료 |
restartPolicy: OnFailure는 같은 Pod 안에서 컨테이너를 재시작하고, Never는 매번 새 Pod를 만듭니다. 실패 로그를 남기려면 Never가 디버깅에 유리합니다.
설정 예시
YAML
apiVersion: batch/v1
kind: Job
metadata:
name: data-migrate
spec:
backoffLimit: 2 # 최대 2회까지만 재시도
activeDeadlineSeconds: 600 # 10분 넘기면 강제 종료
template:
spec:
restartPolicy: Never # 실패 Pod를 남겨 로그 확인
containers:
- name: migrate
image: myapp:1.4
command: ["python", "migrate.py"]
backoffLimit: 0으로 두면 첫 실패에서 바로 Job이 종료되어, 재시도가 위험한 비멱등 작업(중복 결제·중복 발송 등)에 안전합니다.
확인 체크리스트
Kubernetes
# 실패한 Pod 로그(삭제 전에)
kubectl logs job/<job>
# 완료된 Job 자동 정리 — ttlSecondsAfterFinished 사용
kubectl get job <job> -o jsonpath='{.spec.ttlSecondsAfterFinished}'
# 재시도 한도 초과 여부
kubectl describe job <job> | grep -i backoff
작업이 멱등인지부터 판단하세요. 멱등이면 backoffLimit을 넉넉히 두어 일시 오류를 흡수하고, 비멱등이면 0~2로 묶어 중복 실행을 막는 것이 원칙입니다.
Job의 재시도와 실패 처리를 직접 돌려 보며 backoffLimit 동작을 확인하는 실습은 쿠버네티스 트랙에서 해볼 수 있습니다 — 회원가입 없이 무료로.