목록으로

Programming Notes

Kubernetes v1.34: 잡(Job)의 파드 교체 정책 정식 출시 (GA)

Kubernetes v1.34에서 파드 교체 정책 기능이 정식 출시(GA)되었습니다. 이 블로그 게시물에서는 파드 교체 정책 기능과 이를 잡(Job)에서 사용하는 방법을 설명합니다. 파드 교체 정책에 대하여 기본적으로 잡 컨트롤러는 파드가 실패하거나 종료되기 시작하면(삭제...

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

더 자세히 알아보려면?

감사의 말

다른 쿠버네티스 기능과 마찬가지로, 이 기능을 완성하기 위해 테스트 및 버그 보고부터 코드 리뷰에 이르기까지 여러 사람이 기여했습니다.

이 기능이 2년 만에 안정화 단계로 접어들면서, 다음 분들께 감사의 말씀을 전하고 싶습니다:

참여하기

이 작업은 쿠버네티스 배치 워킹 그룹SIG 앱스 커뮤니티와 긴밀히 협력하여 지원했습니다.

이 분야의 새로운 기능 작업에 관심이 있다면, 저희 Slack 채널을 구독하고 정기 커뮤니티 회의에 참석하시기를 권장합니다.