Skip to main content

GPU 공유 기능 (Time-Slicing)

대상: BRICK 사용자 전체, 클러스터 관리자 이 문서는 BRICK의 GPU Time-Slicing 지원 개요, 사용자 화면 안내, 관리자 운영 절차를 함께 다룹니다. 문서 구성: 1. 개요 → 2. 사용자 가이드 → 3. 관리자 가이드 → 4. 용어집


1. 개요​

1.1 왜 GPU 공유가 필요한가​

BRICK은 지금까지 GPU를 하나의 사용자(또는 Pod)가 물리 GPU 하나를 독점하는 방식(Exclusive)으로만 제공했습니다. 그러나 실험·추론·경량 학습처럼 GPU 자원을 전부 쓰지 않는 워크로드도 많아, 물리 GPU 1개를 여러 사용자가 시간 분할(Time-Slicing)로 나눠 쓸 수 있도록 지원을 확장합니다.

1.2 BRICK이 지원하는 GPU 유형 3가지​

유형설명리소스 이름격리 수준
Exclusive물리 GPU 1개를 한 사용자가 독점nvidia.com/gpu완전 격리
Shared (Time-Slicing)물리 GPU 1개를 여러 사용자가 시간 분할로 공유nvidia.com/gpu.shared메모리 격리 없음 (아래 3.3 참고)
MIG물리 GPU를 하드웨어 단위로 분할한 인스턴스nvidia.com/mig-<profile> (예: nvidia.com/mig-1g.5gb)하드웨어 격리

BRICK은 Kubernetes 리소스를 직접 다루지 않고, Workspace → Application/Job 단위로 GPU를 추상화하여 제공합니다. 사용자는 물리 노드나 GPU를 직접 선택하지 않으며, GPU 종류와 개수만 지정합니다.

1.3 물리(Physical) vs 논리(Logical)​

Time-Slicing 도입으로 GPU 개수의 의미가 두 갈래로 나뉩니다.

  • 물리(Physical): 실제 장착된 GPU 장치 수. Time-Slicing 여부와 무관하게 고정.
  • 논리(Logical): 스케줄링 가능한 단위 수. Exclusive는 물리와 동일하지만, Shared는 물리 GPU 1개가 설정된 배수(replicas)만큼의 논리 GPU로 보입니다.

예) 물리 GPU 1개에 Time-Slicing replicas=2 설정 시 → 사용자에게는 논리 GPU 2개로 보임.

이 구분은 Dashboard, Workspace 생성 화면, Node 상세 화면에서 서로 다르게 나타납니다 (2절 참고).


2. 사용자 가이드​

2.1 Workspace 생성 시 GPU 신청​

Workspace 생성 화면에서 사용자는 GPU 개수만 입력합니다. GPU 유형(Exclusive/Shared/MIG)은 지정하지 않으며, 관리자가 승인 단계에서 클러스터 상황에 맞는 유형을 배정합니다.

Resources
GPU [ 0 ] (Max 0 GPU)
CPU [ 2 ] (Max 2 CPU)
Memory [ 8 ] (Max 8 GiB)
Storage [20 ] (Max 20 GiB)

신청 후 관리자 승인이 완료되면, 배정된 GPU 유형에 따라 Workspace의 실제 리소스 이름(nvidia.com/gpu 또는 nvidia.com/gpu.shared)이 결정됩니다. 사용자는 승인 결과를 통해 어떤 유형이 배정되었는지 확인할 수 있습니다.

2.2 Workspace 생성 화면의 GPU 현황 표시​

Workspace 생성 화면에서는 GPU 종류별로 Total / Used / Available을 확인할 수 있습니다.

GPU Type Total Used Available
nvidia.com/gpu 1 1 0
nvidia.com/gpu.shared 2 1 1
  • nvidia.com/gpu.shared의 Total은 논리 개수입니다. 물리 GPU 1개에 replicas=2가 설정되어 있다면 Total은 2로 표시됩니다.
  • Available이 0인 유형은 지금 신청해도 승인 시 배치가 지연될 수 있습니다.

2.3 Dashboard에서 GPU 현황 확인​

Dashboard 메인 화면의 GPU 카드는 논리 개수 기준으로 전체 GPU 현황을 보여줍니다. 카드의 돋보기(🔍)를 클릭하면 모델별 상세 화면이 열립니다.

NVIDIA A30 Total 1 Used 0
NVIDIA A30 (Shared) Total 2 Used 0

같은 모델이어도 Exclusive와 Shared는 별도 행으로 표시됩니다. (Shared) 표기가 붙은 행은 Time-Slicing이 적용된 GPU입니다.

2.4 Job 생성 시 GPU 선택 — Exclusive GPU만 지원​

Job(학습 작업)은 현재 Exclusive GPU만 지원합니다. Job 생성 화면의 노드 선택 목록에서 Shared/MIG 전용 노드는 아래와 같이 비활성 표시됩니다.

● dev-a1-ws04 nvidia.com/gpu 1 / 1 available
○ dev-a1-ws02 nvidia.com/gpu.shared — Time-Slicing 노드는 Job을 지원하지 않습니다

지원하지 않는 이유:

  • Time-Slicing은 물리 GPU의 시간만 나눌 뿐, 메모리 격리가 없습니다. 학습 작업은 GPU 메모리를 한계까지 사용하는 경우가 많아, 같은 GPU를 쓰는 다른 워크로드(Workspace 애플리케이션 등)의 안정성에 영향을 줄 수 있습니다.
  • MIG는 하드웨어 격리가 되어 안전하지만, MIG 인스턴스 간에는 분산 학습(NCCL) 통신이 지원되지 않고 한 프로세스가 인스턴스 하나만 사용할 수 있어 활용도가 제한적입니다.

이 정책은 향후 실사용 요구가 확인되면 재검토될 수 있습니다 (3.5절 참고).


3. 관리자 가이드​

3.1 아키텍처 개요​

BRICK의 GPU 공유는 노드 단위로 모드를 지정합니다. 한 노드는 Exclusive 또는 Time-Slicing 둘 중 하나의 모드로만 동작하며, 혼합 배치(Mixed workload)는 지원하지 않습니다. 반면 MIG는 migStrategy: mixed 설정으로 한 노드 안에 Full GPU와 MIG 인스턴스가 공존할 수 있습니다.

노드 라벨 체계 (단일 진실 소스):

brick.cloud/gpu.type=nvidia # 모든 GPU 노드 공통
brick.cloud/gpu.sharing=none # Exclusive 노드
brick.cloud/gpu.sharing=timeslicing # Time-Slicing 노드

이 라벨이 Device Plugin의 DaemonSet 배치(nodeSelector)와 Prometheus recording rule의 GPU 타입 판별에 공통으로 사용됩니다.

GPU 도메인 용어:

용어의미
logical (total)스케줄 가능한 논리 디바이스 수 (kubelet allocatable 기준)
allocatedWorkspace에 배정된 quota 상한
requestedPod가 실제 점유 요청한 양
physical물리 장치 수 (DCGM 기준)
physical_usedRunning Pod가 붙어 있는 물리 장치 수

3.2 Device Plugin 설정​

NVIDIA Device Plugin을 Exclusive용/Time-Slicing용 두 개의 ConfigMap + DaemonSet으로 분리 운영합니다. (Operator 미사용, driver/container-runtime은 노드에 직접 설치하는 환경 기준)

Exclusive ConfigMap (nvidia-device-plugin-config-default):

version: v1
flags:
migStrategy: mixed

Time-Slicing ConfigMap (nvidia-device-plugin-config-timeslicing):

version: v1
flags:
migStrategy: mixed

sharing:
timeSlicing:
renameByDefault: true
failRequestsGreaterThanOne: true
resources:
- name: nvidia.com/gpu
replicas: 2

핵심 옵션 설명:

  • renameByDefault: true — Time-Slicing GPU를 nvidia.com/gpu.shared라는 별도 리소스 이름으로 노출합니다. 이 옵션이 없으면 Exclusive와 Shared가 동일한 nvidia.com/gpu로 노출되어, ResourceQuota에서 두 유형을 구분할 방법이 없어집니다. BRICK의 Time-Slicing 지원 전체가 이 옵션을 전제로 설계되어 있습니다.
  • failRequestsGreaterThanOne: true — 한 Pod가 Shared GPU를 2개 이상 요청하는 것을 차단합니다. Time-Slicing은 같은 물리 GPU의 시간을 나누는 것이라, 한 Pod가 여러 slice를 요청해도 성능 이득이 없기 때문입니다.

두 DaemonSet은 nodeSelector로 노드 라벨을 참조하며, toleration은 반드시 동일하게 유지해야 합니다 (GPU 노드에 taint를 운영하는 경우, 한쪽만 toleration이 없으면 해당 모드의 노드에서 plugin이 스케줄되지 않아 GPU가 아예 노출되지 않는 장애로 이어집니다).

매니페스트 실물은 별도 파일(brick-nvidia-device-plugin.yaml)로 관리되며, ConfigMap 수정 후에는 **반드시 kubectl rollout restart**가 필요합니다 (--config-file 방식은 시작 시점에만 설정을 읽음).

3.3 Time-Slicing의 제약 사항 (운영 시 반드시 인지)​

  • 메모리 격리 없음: 같은 물리 GPU의 slice들이 VRAM을 공유합니다. 한 워크로드가 메모리를 과점하면 같은 GPU의 다른 워크로드가 OOM으로 실패할 수 있습니다. 이 때문에 Job(학습)은 Shared GPU를 지원하지 않습니다 (2.4절).
  • 성능 격리 없음: 시간 분할이라 동시 사용 시 각 워크로드의 처리량이 저하될 수 있습니다.
  • replicas 변경 시 기존 할당량과의 정합: replicas를 늘리면 Total이 즉시 증가하지만 이미 할당된 Workspace quota는 그대로라 Available이 갑자기 커 보입니다. replicas를 줄이는 경우 기존 quota 합이 새 Total을 초과할 수 있어, 변경 전 반드시 해당 타입의 Workspace 할당 현황을 확인해야 합니다.

3.4 Job의 자원 통제 모델 (참고)​

Job은 Workspace의 ResourceQuota 범위 밖에서 동작하는 "기회 계층(scavenging)" 워크로드입니다. brick-user-priority(PriorityClass, value > 0)가 적용된 Workspace 워크로드가 필요 시 Job을 선점(Preempt)하므로, Workspace의 quota 기반 가용량 표시는 Job의 존재와 무관하게 신뢰할 수 있습니다. 다만 Job 자체에는 별도 자원 상한이 없어(Job 승인 기능으로 통제), 관리자가 Job 승인을 비활성화하는 경우 이 통제 장치가 사라진다는 점에 유의해야 합니다.

3.5 향후 계획​

  • MIG Job 지원: 현재는 미지원(2.4절)이나, 고객사에서 "MIG 인스턴스가 유휴 상태인데 Job이 대기 중"인 상황이 관측되면 지원을 검토합니다. 지원 시에도 인스턴스 1개 고정, 멀티 워커 Job과 조합 금지가 전제 조건입니다.
  • Shared GPU 자원 통제: Job 승인 비활성화 시의 무제한 리스크에 대응해, Workspace별 Job 자원 상한 설정 기능을 제품화하는 방안을 검토 중입니다.

4. 운영 절차​

이 절은 노드 단위 Time-Slicing 전환·확장 작업을 다룹니다. 절차를 따르지 않고 임의로 설정을 변경하면 GPU 리소스 노출 오류, 스케줄링 오류가 발생할 수 있으니 반드시 순서대로 진행하십시오.

운영 원칙​

  1. 모든 변경은 매니페스트 파일 수정 → kubectl apply. kubectl edit 사용 금지 (live 상태와 파일이 어긋나면, 이후 누군가 예전 파일로 apply할 때 설정이 조용히 되돌아갑니다).
  2. 노드 모드 전환은 반드시 노드를 비운 상태(drain)에서 수행합니다.
  3. 두 DaemonSet의 toleration은 항상 동일하게 유지합니다.
  4. DaemonSet의 spec.selector는 불변입니다. 변경이 필요하면 DS를 삭제 후 재생성합니다 (기존 GPU Pod 실행에는 영향 없음).

절차 A — 노드 전환: Exclusive → Time-Slicing​

예시: dev-a1-ws02를 Exclusive → Time-Slicing으로 전환.

1) 노드 격리 및 배수

kubectl cordon dev-a1-ws02
kubectl drain dev-a1-ws02 --ignore-daemonsets --delete-emptydir-data

2) 라벨 변경

kubectl label node dev-a1-ws02 brick.cloud/gpu.sharing=timeslicing --overwrite

3) Device Plugin 교체 확인

kubectl -n brick-nvidia get pod -o wide \
-l app.kubernetes.io/component=timeslicing \
--field-selector spec.nodeName=dev-a1-ws02

4) 새 리소스 노출 확인

kubectl describe node dev-a1-ws02 | grep -A 10 Allocatable
# nvidia.com/gpu.shared: <물리 GPU 수 × replicas> 확인

5) 이전 리소스 잔재 정리 (필수)

kubelet은 이전 리소스(nvidia.com/gpu)의 capacity를 스스로 지우지 않습니다. 방치하면 상황에 따라 allocatable로 부활하여, 해당 리소스를 요청하는 Pod가 이 노드에 잘못 스케줄된 뒤 UnexpectedAdmissionError로 실패할 수 있습니다.

kubectl patch node dev-a1-ws02 --subresource=status --type=json -p='[
{"op":"remove","path":"/status/capacity/nvidia.com~1gpu"},
{"op":"remove","path":"/status/allocatable/nvidia.com~1gpu"}
]'

⚠️ kubelet 체크포인트 파일(kubelet_internal_checkpoint) 삭제 방식은 사용하지 않습니다. kubelet이 해당 리소스를 잊으면서 오히려 잔재 capacity가 allocatable로 부활하는 부작용이 확인되었습니다. 반드시 위의 API patch 방식을 사용하십시오.

6) 정리 결과 확인 및 노드 복귀

kubectl describe node dev-a1-ws02 | grep nvidia
kubectl uncordon dev-a1-ws02

7) Prometheus 반영 확인

kube_node_status_allocatable{node="dev-a1-ws02", resource=~"nvidia_com.+"}

resource="nvidia_com_gpu_shared" 값이 (물리 수 × replicas)로 잡히는지 확인합니다.


절차 B — 노드 전환: Time-Slicing → Exclusive​

절차 A와 골격은 같으나, 클러스터의 shared GPU Total이 줄어드는 방향이라 사전 확인 단계가 추가됩니다.

0) 사전 확인 — Shared GPU 할당 정합

# 전환 후 남을 shared Total (대상 노드 제외)
sum(kube_node_status_allocatable{resource="nvidia_com_gpu_shared", node!="dev-a1-ws02"})

# 현재 할당된 shared quota 합
sum(kube_resourcequota{resource="requests.nvidia.com/gpu.shared", type="hard"})

전자가 후자 이상이어야 안전합니다. 초과한다면 해당 Workspace들의 quota를 먼저 조정한 뒤 진행하십시오. 이 노드가 클러스터의 유일한 Time-Slicing 노드라면, drain으로 밀려나는 Shared GPU 요청 Pod들이 갈 곳이 없어 Pending 상태가 되므로 사전에 소유 Workspace 사용자와 협의가 필요합니다.

14) 절차 A의 14단계와 동일 (라벨 값만 none으로)

5) 이전 리소스(nvidia.com/gpu.shared) 잔재 정리

kubectl patch node dev-a1-ws02 --subresource=status --type=json -p='[
{"op":"remove","path":"/status/capacity/nvidia.com~1gpu.shared"},
{"op":"remove","path":"/status/allocatable/nvidia.com~1gpu.shared"}
]'

67) 절차 A의 67단계와 동일


절차 C — Time-Slicing replicas 변경​

예시: replicas 2 → 4

1) 매니페스트 수정 및 적용

resources:
- name: nvidia.com/gpu
replicas: 4
kubectl apply -f brick-nvidia-device-plugin.yaml

2) Plugin 재시작 (필수 — apply만으로는 반영되지 않음)

kubectl -n brick-nvidia rollout restart ds/nvidia-device-plugin-timeslicing
kubectl -n brick-nvidia rollout status ds/nvidia-device-plugin-timeslicing

3) 반영 확인

kubectl describe node <timeslicing 노드> | grep gpu.shared

4) 주의: replicas를 늘리면 Total이 즉시 늘어나 Available이 부풀어 보입니다. 정책적으로 문제가 없는지 검토 후 변경하십시오. 줄이는 경우, 기존 Workspace 할당량 합이 새 Total을 초과하지 않는지 먼저 확인해야 합니다. Recording rule과 백엔드는 allocatable 실측 기반이라 이 변경에 대해 별도 수정이 필요 없습니다.


절차 D — 신규 GPU 노드 추가​

  1. 노드에 NVIDIA driver(run 파일), nvidia-container-runtime(rpm) 설치 (기존 노드 구축 가이드 따름)
  2. 라벨 부여 — gpu.type과 gpu.sharing을 반드시 함께 지정:
kubectl label node <노드> brick.cloud/gpu.type=nvidia brick.cloud/gpu.sharing=none
# Time-Slicing 노드로 추가하려면 sharing=timeslicing
  1. plugin pod 배치 및 리소스 노출 확인 (절차 A의 3~4단계와 동일)
  2. 신규 노드는 잔재가 없으므로 status patch 불필요

트러블슈팅​

증상원인 및 조치
describe node에 이전 모드의 리소스가 남아 있음capacity에만 남고 allocatable이 0이면 스케줄에는 영향 없으나 절차 A/B의 5단계로 정리 권장. capacity·allocatable 양쪽에 값이 있으면 즉시 정리 필요 (잘못된 스케줄 위험)
GPU Pod가 UnexpectedAdmissionError로 실패노드가 실제로 serving하지 않는 리소스가 allocatable에 남아 스케줄러가 배치했으나 kubelet에서 거부됨. 절차 A/B의 5단계 실행 후 Pod 재생성
Time-Slicing 노드에서 GPU 리소스가 아예 안 보임plugin pod가 해당 노드에 떠 있는지 확인. Pending이면 노드 taint 대비 toleration 누락 확인. 노드 라벨 오타(sharing=timeslicing 정확한 문자열) 확인
리부팅 직후 allocatable이 잠시 0plugin이 아직 등록 전인 정상 방어 동작. pod Running 후 자동 복구
ConfigMap 수정 후 replicas 미반영rollout restart 누락 (절차 C-2)

4. 용어집 / FAQ​

용어집​

용어정의
Exclusive GPU물리 GPU 1개를 한 사용자가 독점 사용
Shared GPU (Time-Slicing)물리 GPU 1개를 여러 사용자가 시간 분할로 공유
MIGNVIDIA Multi-Instance GPU. 물리 GPU를 하드웨어 단위로 분할
Logical GPU스케줄링 가능한 논리적 GPU 단위 수 (Time-Slicing 반영)
Physical GPU실제 장착된 물리 GPU 장치 수
replicasTime-Slicing 시 물리 GPU 1개를 몇 개의 논리 GPU로 나눌지 결정하는 배수
renameByDefaultTime-Slicing GPU를 별도 리소스 이름(nvidia.com/gpu.shared)으로 노출하는 Device Plugin 옵션

FAQ​

Q. 신청한 GPU 개수가 실제로 Exclusive인지 Shared인지 어떻게 아나요? A. Workspace 승인이 완료되면 관리자가 배정한 유형이 확정됩니다. Workspace 상세 화면에서 실제 GPU 리소스 이름을 확인할 수 있습니다.

Q. Job에서 Shared GPU를 쓸 수 있나요? A. 현재는 지원하지 않습니다 (2.4절). Exclusive GPU가 있는 노드만 Job 생성 화면에 활성화되어 표시됩니다.

Q. Dashboard의 GPU 개수와 Workspace 생성 화면의 GPU 개수가 다르게 보입니다. A. 정상입니다. Dashboard는 논리(Logical) 기준, Node 상세 화면은 물리(Physical) 기준으로 표시되어 Time-Slicing 적용 시 서로 다른 숫자가 나옵니다 (1.3절).

Q. GPU 자원이 부족하다고 나오는데 실제로는 비어 있는 것 같습니다. A. 관리자에게 노드 상태 확인을 요청하십시오. Device Plugin 전환 과정에서 이전 리소스 잔재가 남아 스케줄링에 영향을 줄 수 있습니다 (3절 트러블슈팅 참고).


관련 문서​