Kubernetes v1.34에서 파드 교체 정책 기능이 정식 출시(GA)되었습니다. 이 블로그 게시물에서는 파드 교체 정책 기능과 이를 잡(Job)에서 사용하는 방법을 설명합니다.
파드 교체 정책에 대하여
기본적으로 잡 컨트롤러는 파드가 실패하거나 종료되기 시작하면(삭제 타임스탬프를 가질 때) 즉시 파드를 재생성합니다.
결과적으로 일부 파드가 종료되는 동안 잡의 총 실행 파드 수가 지정된 병렬 처리(parallelism) 수를 일시적으로 초과할 수 있습니다. 인덱스 잡(Indexed Jobs)의 경우, 이는 동일한 인덱스에 대해 여러 파드가 동시에 실행됨을 의미할 수도 있습니다.
이 동작은 많은 워크로드에서 잘 작동하지만, 특정 경우에는 문제를 일으킬 수 있습니다.
예를 들어, TensorFlow 및 JAX와 같은 인기 있는 머신러닝 프레임워크는 작업자 인덱스당 정확히 하나의 파드를 예상합니다. 두 개의 파드가 동시에 실행되면 다음과 같은 오류가 발생할 수 있습니다:
/job:worker/task:4: Duplicate task registration with task_name=/job:worker/replica:0/task:4
또한, 이전 파드가 완전히 종료되기 전에 교체 파드를 시작하면 다음과 같은 문제가 발생할 수 있습니다:
- 노드가 점유된 상태로 남아 있어 kube-scheduler에 의한 스케줄링 지연.
- 교체 파드를 수용하기 위한 불필요한 클러스터 스케일업.
- Kueue와 같은 워크로드 오케스트레이터에 의한 할당량(quota) 검사 일시적 우회.
파드 교체 정책을 통해 쿠버네티스는 컨트롤 플레인이 종료 중인 파드를 언제 교체할지 제어할 수 있도록 하여 이러한 문제를 방지하는 데 도움을 줍니다.
파드 교체 정책 작동 방식
이 개선 사항은 쿠버네티스의 잡(Job)에 선택적 필드인 .spec.podReplacementPolicy가 있음을 의미합니다. 다음 두 가지 정책 중 하나를 선택할 수 있습니다:
TerminatingOrFailed(기본값): 파드가 종료되기 시작하는 즉시 교체합니다.Failed: 파드가 완전히 종료되어Failed상태로 전환된 후에만 교체합니다.
정책을 Failed로 설정하면 이전 파드가 완전히 종료된 후에만 새 파드가 생성되도록 보장합니다.
파드 실패 정책(Pod Failure Policy)을 사용하는 잡의 경우, podReplacementPolicy의 기본값은 Failed이며 다른 값은 허용되지 않습니다. 잡의 파드 실패 정책에 대해 더 알아보려면 파드 실패 정책을 참조하세요.
잡의 .status.terminating 필드를 검사하여 현재 종료 중인 파드 수를 확인할 수 있습니다:
kubectl get job myjob -o=jsonpath='{.status.terminating}'
예시
다음은 작업을 두 번(spec.completions: 2) 병렬로(spec.parallelism: 2) 실행하고 파드가 완전히 종료된 후에만 교체하는(spec.podReplacementPolicy: Failed) 잡 예시입니다:
apiVersion: batch/v1
kind: Job
metadata:
name: example-job
spec:
completions: 2
parallelism: 2
podReplacementPolicy: Failed
template:
spec:
restartPolicy: Never
containers:
- name: worker
image: your-image
파드가 SIGTERM 신호(삭제, 축출, 선점 등)를 받으면 종료되기 시작합니다. 컨테이너가 정상적으로 종료를 처리하는 경우 정리하는 데 시간이 걸릴 수 있습니다.
잡이 시작되면 두 개의 파드가 실행되는 것을 볼 수 있습니다:
kubectl get pods
NAME READY STATUS RESTARTS AGE
example-job-qr8kf 1/1 Running 0 2s
example-job-stvb4 1/1 Running 0 2s
파드 중 하나(example-job-qr8kf)를 삭제해 봅시다.
TerminatingOrFailed 정책을 사용하면 하나의 파드(example-job-qr8kf)가 종료되기 시작하는 즉시 잡 컨트롤러가 이를 교체하기 위해 새 파드(example-job-b59zk)를 즉시 생성합니다.
kubectl get pods
NAME READY STATUS RESTARTS AGE
example-job-b59zk 1/1 Running 0 1s
example-job-qr8kf 1/1 Terminating 0 17s
example-job-stvb4 1/1 Running 0 17s
Failed 정책을 사용하면 이전 파드(example-job-qr8kf)가 종료되는 동안 새 파드(example-job-b59zk)는 생성되지 않습니다.
kubectl get pods
NAME READY STATUS RESTARTS AGE
example-job-qr8kf 1/1 Terminating 0 17s
example-job-stvb4 1/1 Running 0 17s
종료 중인 파드가 Failed 상태로 완전히 전환되면 새 파드가 생성됩니다:
kubectl get pods
NAME READY STATUS RESTARTS AGE
example-job-b59zk 1/1 Running 0 1s
example-job-stvb4 1/1 Running 0 25s
더 자세히 알아보려면?
- 파드 교체 정책, 인덱스당 백오프 제한, 그리고 파드 실패 정책에 대한 사용자 문서를 읽어보세요.
- 파드 교체 정책, 인덱스당 백오프 제한, 그리고 파드 실패 정책에 대한 KEP를 읽어보세요.
감사의 말
다른 쿠버네티스 기능과 마찬가지로, 이 기능을 완성하기 위해 테스트 및 버그 보고부터 코드 리뷰에 이르기까지 여러 사람이 기여했습니다.
이 기능이 2년 만에 안정화 단계로 접어들면서, 다음 분들께 감사의 말씀을 전하고 싶습니다:
- Kevin Hannon - KEP 작성 및 초기 구현.
- MichaÅ‚ Woźniak - 지도, 멘토링 및 검토.
- Aldo Culquicondor - 지도, 멘토링 및 검토.
- Maciej Szulik - 지도, 멘토링 및 검토.
- Dejan Zele Pejchev - 이 기능을 인수하여 알파(Alpha)부터 베타(Beta)를 거쳐 GA로 승격시켰습니다.
참여하기
이 작업은 쿠버네티스 배치 워킹 그룹이 SIG 앱스 커뮤니티와 긴밀히 협력하여 지원했습니다.
이 분야의 새로운 기능 작업에 관심이 있다면, 저희 Slack 채널을 구독하고 정기 커뮤니티 회의에 참석하시기를 권장합니다.