쿼터는 충분했는데 왜 GPU는 비어 있었나?

문제는 쿼터의 총량이 아니라 admission의 타이밍이었다. 8-GPU 분산 학습 잡이 필요로 하는 자원이 cohort 안에 흩어져 있었고, gang scheduling의 all-or-nothing 원칙 때문에 이 잡은 조건이 동시에 채워질 때까지 evict와 재시도를 반복했다. 그동안 클러스터 전체 GPU 사용률은 예약된 수치보다 낮게 유지됐다.

  • Kueue는 pod 스케줄링이 아니라 workload 단위 admission을 담당하며, 전체가 준비될 때만 시작한다Kueue 공식 문서.
  • policy: ByWorkload는 필요 시점까지 준비되지 않으면 잡 전체를 evict하고 재시도하도록 설계돼 있다.
  • 이 설계는 부분 실행으로 GPU를 묶어두는 상황을 막지만, quota가 여러 큐에 조각나 있으면 반대로 대기를 늘린다.
  • 뿌리는 borrowingLimit과 gang size 사이의 불일치였다.

이번 사례는 2026년 기준, 팀 A 전용·팀 B 전용·공유 default로 구성된 ClusterQueue 세 개짜리 환경에서 일어났다. 팀 A가 8-GPU RayJob을 제출한 뒤, kubectl get workloads의 admitted 카운트는 0인데 nvidia-smi 기준 GPU 다섯 장이 비어 있었다. 대기는 약 40분 이어졌고, 그 사이 팀 B의 소형 잡들만 간헐적으로 admit됐다.

쿼터 총량이 부족했던 것 아닌가?

아니다. 세 ClusterQueue의 nominalQuota 합산은 요청된 8장보다 여유가 있었고, cohort 설정으로 팀 A는 default 큐의 남는 자원을 빌릴 수 있는 구조였다. 총량 기준으로는 admit이 막힐 이유가 없었다.

gang scheduling 정책 설정이 잘못된 것 아닌가?

아니다. policy: ByWorkload, admission: Parallel 설정은 문서가 설명하는 표준 동작 그대로였다Red Hat build of Kueue 문서. 잡을 하나의 단위로 다루고 8장이 동시에 확보되지 않으면 evict 후 재시도하는 흐름은 설계 의도대로 작동했다. 버그가 아니라 정책이 그대로 실행된 결과였다.

borrowingLimit이 좁아서 막힌 것 아닌가?

일부는 맞지만 전부는 아니다. 팀 A 큐의 borrowingLimit은 4장이었고, 자기 nominalQuota 4장과 합치면 정확히 8장이었다. 수치상으로는 admit이 가능해야 했다. 실제로 막힌 이유는 다른 곳에 있었다.

실제 원인은 무엇이었나?

default 큐의 남는 GPU가 시간에 따라 흩어져서 나타났다가 사라졌다. 팀 B의 짧은 잡들이 순간순간 GPU를 반납했지만, 8장이 동시에 비는 시점이 오기 전에 팀 B의 새 잡이 그 자리를 다시 채웠다. Kueue의 admission 체크는 특정 시점의 스냅샷 기준이므로, 필요한 8장이 순간적으로 동시에 존재해야 admit이 성립한다. borrowing 가능한 총량은 충분했지만, 그 총량이 동시에 모이는 순간이 구조적으로 드물었던 것이다. cohort와 borrowingLimit은 "얼마나 빌릴 수 있는가"만 규정하고 "언제 동시에 비는가"는 보장하지 않는다.

무엇을 바꿨나?

팀 A의 reserved 큐 nominalQuota를 8장으로 올려 gang size와 일치시키고, borrowingLimit은 버스트용 여유분 2장으로만 남겼다. 정상 상황에서는 자기 quota만으로 admit이 가능해지고, borrowing은 예외적 버스트에만 쓰이도록 했다. 동시에 admission 정책을 Sequential로 바꿔 대형 잡이 순서대로 처리되도록 해, 동시 대기 잡 간의 자원 조각화를 줄였다.

이 사례가 다른 시스템에도 알려주는 것은 무엇인가?

all-or-nothing admission을 쓰는 자원 공유 시스템에서는 quota의 배분 단위가 job의 최소 실행 단위(gang size)와 맞아야 한다. 공유 풀에서 총량만 맞추고 동시성을 고려하지 않으면, 자원이 충분한데도 아무도 실행되지 못하는 상태가 반복될 수 있다. 이는 Kueue뿐 아니라 배치 큐, 예약 시스템 전반에 적용되는 원칙이다.

핵심 정리

  • Kueue의 admission은 workload 단위 스냅샷 체크이며, gang scheduling은 필요한 자원이 동시에 모여야 성립한다Ray 공식 문서.
  • 쿼터 총량과 borrowingLimit이 수치상 충분해도, 자원이 조각난 시점에 모이면 admit이 지연될 수 있다.
  • reserved 큐의 nominalQuota를 job의 gang size 이상으로 맞추는 편이 borrowing에 의존하는 것보다 안정적이다.
  • cohort와 borrowing은 총량 공유를 규정하지만 동시 가용성은 별도로 설계해야 한다.
  • all-or-nothing admission을 쓰는 모든 자원 공유 시스템은 quota 배분 단위를 최소 실행 단위에 맞춰야 정체를 피할 수 있다.

더 알아보기

GPU 스케줄링과 학습 오케스트레이션: 희소 자원을 어떻게 분배할 것인가 — 이 주제의 종합 가이드