LabHub
배우기 러닝패스 코스

GPU Operator 와 타임슬라이싱 · 컨테이너만 GPU 를 쓰는 게 아니다 · 실습

샌드박스 워크로드 — 라벨이 정하는 자원 이름과 갈라지는 재고

LabHub 에서 이어서 보기

목표

노드 세 대를 각각 다른 GPU 워크로드 용도로 세우고, 용도마다 자원 이름이 달라진다는 것과 그 결과 재고가 갈라진다는 것을 실제 스케줄러로 확인한 뒤, 라벨과 광고가 맞는지 판정하는 점검기를 만듭니다.

왜 중요한가

GPU 를 쓰는 워크로드가 전부 컨테이너인 것은 아닙니다. 라이선스나 레거시 때문에 가상 머신 안에서 돌아야 하는 것이 있고, 그런 VM 에 카드를 넘기려면 노드에 깔리는 드라이버부터 달라야 합니다 — 컨테이너에는 데이터센터 드라이버, 패스스루에는 vfio-pci, vGPU 에는 vGPU Manager 입니다. GPU Operator 는 그 선택을 노드 라벨 한 줄로 받습니다. 그리고 그 선택의 결과가 노드가 광고하는 자원 이름까지 바꿉니다. 이름이 다르면 스케줄러에게는 서로 다른 자원이라 한쪽 대기열이 길어도 다른 쪽 자리는 비어 있는 채로 남습니다. 재고를 용도별로 나누는 일이 왜 되돌리기 어려운 결정인지가 여기서 나옵니다.

단계

1. /root/gpuwl/out /root/gpuwl/bin /root/gpuwl/k8s 를 만들고 네임스페이스 gpu-vm 을 만드세요. 노드 세 대에 라벨 nvidia.com/gpu.workload.config 를 붙이세요 — lab-node-0container, lab-node-1vm-passthrough, lab-node-2vm-vgpu 입니다. 그리고 /root/gpuwl/out/01-nodes.txt 에 세 줄을 적으세요 — 한 줄에 <노드이름> <라벨값> 입니다(노드 이름 오름차순).
2. /root/gpuwl/out/operands.txt 에 다섯 줄을 적으세요. 앞 세 줄은 <라벨값>=<오퍼랜드 목록> 이고 목록은 쉼표로 잇습니다(순서는 상관없습니다) — containerdatacenter-driver container-toolkit device-plugin dcgm-exporter, vm-passthroughvfio-manager sandbox-device-plugin, vm-vgpuvgpu-manager vgpu-device-manager sandbox-device-plugin 입니다. 네 번째 줄은 NO_LABEL= 에 라벨이 없을 때 오퍼레이터가 가정하는 값을, 다섯 번째 줄은 ENABLE_FLAG= 에 이 라벨을 쓰이게 만드는 ClusterPolicy 플래그 이름을 적습니다.
3. 세 노드의 status.capacitystatus.allocatable 양쪽에 각자의 자원을 넣으세요 — lab-node-0nvidia.com/gpu"4", lab-node-1nvidia.com/GA102GL_A10"2", lab-node-2nvidia.com/NVIDIA_A10-12Q"4" 입니다. 그리고 /root/gpuwl/out/03-resources.txt 에 세 줄을 적으세요 — 한 줄에 <노드이름> <자원이름> <광고량> 입니다(노드 이름 오름차순).
4. /root/gpuwl/k8s/pod-container.yaml 에 파드 job-container 를 쓰세요 — 네임스페이스 gpu-vm, 컨테이너 이름 cuda, 이미지 nvcr.io/nvidia/cuda:12.4.1-base-ubuntu22.04, limitsnvidia.com/gpu: 1. nodeSelector 는 쓰지 마세요. 적용한 뒤 어느 노드에 떴는지 /root/gpuwl/out/04-container.txt 에 한 줄로 적으세요 — NODE=<노드이름>.
5. /root/gpuwl/k8s/pod-passthrough.yaml 에 파드 vmi-passthrough 를 쓰세요 — 네임스페이스 gpu-vm, limitsnvidia.com/GA102GL_A10: 1, nodeSelector 없음. 나머지는 4단계와 같습니다. 적용한 뒤 /root/gpuwl/out/05-passthrough.txt 에 두 줄을 적으세요 — NODE=RESOURCE= (요청한 자원 이름 그대로).
6. /root/gpuwl/k8s/pod-vgpu.yaml 에 파드 vmi-vgpu 를 쓰세요 — 네임스페이스 gpu-vm, limitsnvidia.com/NVIDIA_A10-12Q: 1, nodeSelector 없음. 적용한 뒤 /root/gpuwl/out/06-placement.txt 에 세 줄을 적으세요 — 지금까지 만든 파드 셋이 각각 어디에 떴는지 <파드이름> <노드이름> 으로, 파드 이름 오름차순입니다.
7. /root/gpuwl/k8s/pod-cross.yaml 에 파드 job-cross 를 쓰세요 — 네임스페이스 gpu-vm, nodeSelectornvidia.com/gpu.workload.config: vm-passthrough 를 걸고 limits 에는 nvidia.com/gpu: 1 을 요구합니다. 패스스루 노드에 컨테이너용 자원을 달라고 하는 셈입니다. 적용한 뒤 /root/gpuwl/out/07-cross.txt 에 세 줄을 적으세요 — PHASE=, NODE=(비어 있으면 none), MESSAGE=(PodScheduled 조건의 메시지).
8. /root/gpuwl/out/nodes.jsonkubectl get nodes -o json 결과를 저장하고, /root/gpuwl/bin/check-config.sh <노드JSON파일> 을 만드세요. 파일 안의 노드 가운데 nvidia.com/gpu.workload.config 라벨이 있는 것만 보고, 그 값과 광고한 nvidia.com/ 자원 이름이 맞는지 판정합니다 — containernvidia.com/gpu 여야 하고, vm-vgpu 는 vGPU 프로파일 이름(번호와 대문자로 끝나는 것)이어야 하며, vm-passthrough 는 그 둘 중 어느 쪽도 아닌 장치 모델 이름이어야 합니다. 어긋난 노드마다 MISMATCH=<노드이름> <이유> 를 한 줄씩 내고 1 로 끝내고, 전부 맞으면 OK=<검사한 노드 수> 를 내고 0 으로 끝냅니다. 만든 뒤 저장한 덤프에 물려 출력을 /root/gpuwl/out/consistency.txt 에 저장하세요.

참고

단계 8개

  1. 노드 세 대에 용도를 적는다
  2. 라벨 값마다 무엇이 올라오는지 표로 세운다
  3. 용도마다 다른 자원 이름을 광고한다
  4. 컨테이너 워크로드는 컨테이너 노드로 간다
  5. 패스스루 요청은 장치 모델 이름을 부른다
  6. vGPU 요청은 프로파일 이름을 부른다
  7. 남의 자원을 부르면 어디에도 못 간다
  8. 라벨과 자원 광고가 서로 맞는지 판정하는 점검기