목록으로

Programming Notes

Kubernetes v1.35: 인플레이스(in-place) Pod 재시작으로 효율성의 새로운 지평을 열다

Kubernetes 1.35 릴리스는 오랫동안 요청되었던 강력한 새 기능을 선보입니다. 바로 Pod를 완전히 제자리에서(in-place) 재시작하는 기능입니다. 이 기능인 Restart All Containers (1.35에서 알파 기능)는 전체 Pod를 삭제하고 다시 생성하는...

Kubernetes 1.35 릴리스는 오랫동안 요청되었던 강력한 새 기능을 선보입니다. 바로 Pod를 완전히 제자리에서(in-place) 재시작하는 기능입니다. 이 기능인 Restart All Containers (1.35에서 알파 기능)는 전체 Pod를 삭제하고 다시 생성하는 자원 집약적인 방식에 비해 Pod의 상태를 효율적으로 재설정할 수 있도록 합니다. 이 기능은 AI/ML 워크로드에 특히 유용하여, 애플리케이션 개발자가 복잡한 장애 처리 및 복구 메커니즘을 사이드카와 선언적 Kubernetes 구성으로 오프로드(offload)하는 동안 핵심 훈련 로직에 집중할 수 있게 합니다. RestartAllContainers 및 기타 계획된 개선 사항을 통해 Kubernetes는 AI/ML 워크로드를 위한 가장 유연하고 강력하며 효율적인 플랫폼을 구축하기 위한 빌딩 블록을 계속 추가하고 있습니다.

이 새로운 기능은 RestartAllContainersOnContainerExits 피처 게이트를 활성화하여 사용할 수 있습니다. 이 알파 기능은 Kubernetes 1.35에서 베타 기능으로 승격된 컨테이너 재시작 규칙 기능을 확장합니다.

문제: 단일 컨테이너 재시작으로는 충분하지 않고 Pod 재생성은 비용이 너무 많이 들 때

Kubernetes는 오랫동안 Pod 수준(restartPolicy)과 최근에는 개별 컨테이너 수준에서 재시작 정책을 지원해왔습니다. 이러한 정책은 단일의 고립된 프로세스에서 발생하는 크래시를 처리하는 데 매우 유용합니다. 하지만 많은 최신 애플리케이션은 컨테이너 간에 더 복잡한 의존성을 가집니다. 예를 들어:

  • Init 컨테이너는 볼륨을 마운트하거나 구성 파일을 생성하여 환경을 준비합니다. 만약 메인 애플리케이션 컨테이너가 이 환경을 손상시킨다면, 단순히 해당 컨테이너 하나만 재시작하는 것으로는 충분하지 않습니다. 전체 초기화 프로세스가 다시 실행되어야 합니다.
  • 감시자(watcher) 사이드카는 시스템 상태를 모니터링합니다. 만약 복구할 수 없지만 재시도 가능한 오류 상태를 감지하면, 메인 애플리케이션 컨테이너를 초기 상태(clean slate)부터 다시 시작하도록 트리거해야 합니다.
  • 원격 리소스를 관리하는 사이드카가 실패합니다. 사이드카가 자체적으로 재시작하더라도, 메인 컨테이너는 오래되거나 끊어진 연결에 접근하려고 시도하며 멈춰있을 수 있습니다.

이 모든 경우에서 원하는 동작은 단일 컨테이너를 재시작하는 것이 아니라 모든 컨테이너를 재시작하는 것입니다. 이전에는 이를 달성하는 유일한 방법은 Pod를 삭제하고 컨트롤러(예: Job 또는 ReplicaSet)가 새로운 Pod를 생성하도록 하는 것이었습니다. 이 과정은 스케줄러, 노드 리소스 할당, 네트워킹 및 스토리지 재초기화를 포함하므로 느리고 비용이 많이 듭니다.

이러한 비효율성은 대규모 AI/ML 워크로드(노드당 하나의 Pod를 가진 1,000개 이상의 노드)를 처리할 때 더욱 심해집니다. 이러한 동기화 워크로드의 일반적인 요구 사항은 장애(예: 노드 크래시)가 발생할 경우, 다른 모든 Pod가 장애의 직접적인 영향을 받지 않았더라도, 훈련을 재개하기 전에 전체 플릿의 모든 Pod가 상태를 재설정하기 위해 재생성되어야 한다는 것입니다. 수천 개의 Pod를 동시에 삭제, 생성 및 스케줄링하는 것은 막대한 병목 현상을 초래합니다. 이러한 장애로 인한 추정 오버헤드는 월 10만 달러의 자원 낭비를 초래할 수 있습니다.

AI/ML 훈련 작업에서 이러한 장애를 처리하려면 훈련 프레임워크와 Kubernetes 모두에 걸쳐 복잡한 통합이 필요하며, 이는 종종 불안정하고 번거롭습니다. 이 기능은 Kubernetes 네이티브 솔루션을 도입하여 시스템 견고성을 향상시키고 애플리케이션 개발자가 핵심 훈련 로직에 집중할 수 있도록 합니다.

Pod를 인플레이스(in-place)로 재시작하는 또 다른 주요 이점은 Pod를 할당된 노드에 유지함으로써 추가적인 최적화가 가능하다는 점입니다. 예를 들어, 특정 Pod ID에 연결된 노드 수준 캐싱을 구현할 수 있는데, 이는 Pod가 불필요하게 다른 노드에 재생성될 때는 불가능한 일입니다.

RestartAllContainers 액션 소개

이를 해결하기 위해 Kubernetes v1.35는 컨테이너 재시작 규칙에 새로운 액션인 RestartAllContainers를 추가합니다. 컨테이너가 이 액션을 가진 규칙과 일치하는 방식으로 종료되면, kubelet은 Pod의 빠르고 인플레이스(in-place) 재시작을 시작합니다.

이 인플레이스 재시작은 Pod의 가장 중요한 리소스를 보존하므로 매우 효율적입니다.

  • Pod의 UID, IP 주소 및 네트워크 네임스페이스.
  • Pod의 샌드박스 및 연결된 모든 장치.
  • emptyDir과 PVC에서 마운트된 볼륨을 포함한 모든 볼륨.

모든 실행 중인 컨테이너를 종료한 후, Pod의 시작 시퀀스는 처음부터 다시 실행됩니다. 이는 모든 init 컨테이너가 순서대로 다시 실행되고, 이어서 사이드카 및 일반 컨테이너가 실행되어 알려진 양호한 환경에서 완전히 새로운 시작을 보장한다는 의미입니다. 임시(ephemeral) 컨테이너(종료됨)를 제외하고, 이전에 성공했든 실패했든 상관없이 다른 모든 컨테이너는 개별 재시작 정책과 무관하게 재시작됩니다.

사용 사례

1. ML/배치 작업의 효율적인 재시작

ML 훈련 작업의 경우, 장애 발생 시 워커 Pod를 재스케줄링하는 것은 귀중한 컴퓨팅 리소스를 낭비하는 비용이 많이 드는 작업입니다. 1,000노드 훈련 클러스터에서 재스케줄링 오버헤드는 매달 10만 달러 이상의 컴퓨팅 리소스를 낭비할 수 있습니다.

RestartAllContainers 액션을 사용하면 훨씬 빠르고 하이브리드적인 복구 전략을 활성화하여 이 문제를 해결할 수 있습니다. 즉, "불량" Pod (예: 비정상 노드의 Pod)만 다시 생성하고, 나머지 정상 Pod에 대해서는 RestartAllContainers를 트리거하는 방식입니다. 벤치마크에 따르면 이 방식은 복구 오버헤드를 몇 분에서 몇 초로 줄입니다.

인플레이스 재시작을 통해 감시자 사이드카는 메인 훈련 프로세스를 모니터링할 수 있습니다. 만약 특정, 재시도 가능한 오류를 만나면, 감시자는 지정된 코드로 종료하여 워커 Pod의 빠른 리셋을 트리거할 수 있으며, Job 컨트롤러를 개입시키지 않고 마지막 체크포인트에서 다시 시작할 수 있도록 합니다. 이 기능은 이제 Kubernetes에서 네이티브로 지원됩니다.

향후 개발 및 JobSet 기능에 대한 자세한 내용은 KEP-467 JobSet 인플레이스 재시작에서 확인하십시오.

apiVersion: v1
kind: Pod
metadata:
  name: ml-worker-pod
spec:
  restartPolicy: Never
  initContainers:
  # 이 init 컨테이너는 모든 인플레이스 재시작 시 다시 실행됩니다.
  - name: setup-environment
    image: my-repo/setup-worker:1.0
  - name: watcher-sidecar
    image: my-repo/watcher:1.0
    restartPolicy: Always
    restartPolicyRules:
    - action: RestartAllContainers
      exitCodes:
        operator: In
        # 감시자로부터의 특정 종료 코드가 전체 Pod 재시작을 트리거합니다.
        values: [88]
  containers:
  - name: main-application
    image: my-repo/training-app:1.0

2. Init 컨테이너를 다시 실행하여 깨끗한 상태 유지

init 컨테이너가 자격 증명을 가져오거나 공유 볼륨을 설정하는 역할을 하는 시나리오를 상상해 보십시오. 만약 메인 애플리케이션이 이 공유 상태를 손상시키는 방식으로 실패한다면, init 컨테이너가 다시 실행되어야 합니다.

이러한 손상을 감지하면 메인 애플리케이션이 특정 코드로 종료되도록 구성함으로써, RestartAllContainers 액션을 트리거하여 애플리케이션이 다시 시작하기 전에 init 컨테이너가 깨끗한 설정을 제공하도록 보장할 수 있습니다.

3. 유사 작업의 높은 실행 속도 처리

작업이 Pod 실행으로 가장 잘 표현되는 경우가 있습니다. 그리고 각 작업은 깨끗한 실행을 필요로 합니다. 이 작업은 게임 세션 백엔드 또는 일부 큐 항목 처리일 수 있습니다. 작업 속도가 높다면, 특히 작업 시간이 짧을 때 Pod 생성, 스케줄링 및 초기화의 전체 주기를 실행하는 것은 너무 많은 비용이 듭니다. 모든 컨테이너를 처음부터 다시 시작할 수 있는 기능은 사용자 지정 솔루션이나 프레임워크 없이 이 시나리오를 처리하는 Kubernetes 네이티브 방식을 가능하게 합니다.

사용 방법

이 기능을 사용해 보려면 Kubernetes v1.35+를 실행하는 Kubernetes 클러스터 구성 요소(API 서버 및 kubelet)에서 RestartAllContainersOnContainerExits 피처 게이트를 활성화해야 합니다. 이 알파 기능은 v1.35에서 베타로 승격되었고 기본적으로 활성화된 ContainerRestartRules 기능을 확장합니다.

활성화되면, 모든 컨테이너(init, 사이드카 또는 일반)에 restartPolicyRules를 추가하고 RestartAllContainers 액션을 사용할 수 있습니다.

이 기능은 기존 애플리케이션에서 쉽게 사용할 수 있도록 설계되었습니다. 하지만 애플리케이션이 일부 모범 사례를 따르지 않으면 애플리케이션 또는 관찰성 도구에 문제가 발생할 수 있습니다. 이 기능을 활성화할 때, 모든 컨테이너가 재진입 가능하며 외부 도구가 init 컨테이너의 재실행에 대비할 수 있도록 하십시오. 또한 모든 컨테이너를 재시작할 때 kubelet은 preStop 훅을 실행하지 않습니다. 이는 컨테이너가 정상적인 종료를 위해 preStop 훅에 의존하지 않고 갑작스러운 종료를 처리하도록 설계되어야 함을 의미합니다.

재시작 관찰하기

이 프로세스를 관찰 가능하게 하기 위해 Pod의 상태에 새로운 Pod 컨디션인 AllContainersRestarting이 추가됩니다. 재시작이 트리거되면 이 컨디션은 True가 되고, 모든 컨테이너가 종료되고 Pod가 수명 주기를 새로 시작할 준비가 되면 False로 되돌아갑니다. 이는 Pod의 상태에 대해 사용자 및 다른 클러스터 구성 요소에 명확한 신호를 제공합니다.

이 액션으로 재시작된 모든 컨테이너는 컨테이너 상태에서 재시작 횟수가 증가합니다.

더 알아보기

피드백을 기다립니다!

알파 기능인 RestartAllContainers는 여러분이 실험해 볼 준비가 되어 있으며, 모든 사용 사례와 피드백을 환영합니다. 이 기능은 SIG Node 커뮤니티에 의해 주도됩니다. 참여하거나, 의견을 공유하거나, 기여하는 데 관심이 있다면 저희와 함께하십시오!

SIG Node는 다음 채널을 통해 연락할 수 있습니다.