TT Lab
블로그 시작하기
배우기 러닝패스 코스

쿠버네티스 GPU 스케줄링과 AI 배치

DRA 로 장치를 고르고 나눠 쓴다

TT Lab 에서 이어서 보기

이 실습은 진짜 쿠버네티스에서 돕니다

VM 안에 k3s 한 대(v1.36.5)가 떠 있고, dra-example-driver 0.5.0 가 가짜 장치 8개를 ResourceSlice 로 공개합니다. 처음 뜨는 데 2분쯤 걸립니다. 세션이 끝나면 VM 과 파일은 사라집니다.

목표

DRA 의 네 객체(ResourceSlice·DeviceClass·ResourceClaim·ResourceClaimTemplate)를 직접 만들고 읽어, 「장치를 고르는 일」 이 스케줄러 안에서 어떻게 끝나는지 봅니다.

왜 중요한가

장치 플러그인은 숫자 하나로 모든 것을 말해야 해서, 모델 고르기·나눠 쓰기·함께 받기를 노드 라벨과 숫자 부풀리기로 우회했습니다. DRA 에서는 그 결정이 요청서의 status 에 남습니다. 무엇이 어디에 할당됐는지 객체만 읽으면 알 수 있으니, 공유와 쿼터를 정직하게 셀 수 있습니다. NVIDIA 를 포함한 장치 드라이버들이 이쪽으로 옮겨 가고 있습니다.

단계

  1. ResourceSlice 를 읽어 /root/gsb-dra/slices.txt 에 driver=, devices=, node=, model= 을 적습니다.
  2. DeviceClass gpu.example.com 의 선택식을 /root/gsb-dra/class.txt 에 deviceclass=, selector= 로 적습니다.
  3. ResourceClaimTemplate one-gpu 와 Pod dra-1 을 /root/gsb-dra/one.yaml 로 만들어 Running 으로 둡니다.
  4. dra-1 의 요청서 이름·할당 장치·환경 변수 이름을 /root/gsb-dra/claim.json 에 claim, device, env_var 로 적습니다.
  5. index 7 장치만 고르는 ResourceClaim pick-seven 과 Pod dra-7 을 /root/gsb-dra/pick.yaml 로 만듭니다.
  6. ResourceClaim shared 를 Pod share-a, share-b 가 함께 쓰게 /root/gsb-dra/shared.yaml 로 만듭니다.
  7. 장치 둘을 받는 ResourceClaimTemplate two-gpus 와 Pod dra-2x 를 /root/gsb-dra/two.yaml 로 만듭니다.
  8. 장치 4개를 요청하는 Pod dra-big 을 만들어 Pending 을 보고, /root/gsb-dra/report.json 에 allocated_devices, free_devices, pending_pods 를 적습니다.

참고

드라이버가 공개한 장치 목록을 읽는다

ResourceSlice 를 읽어 「/root/gsb-dra/slices.txt」 에 driver=, devices=(그 드라이버가 공개한 장치 수의 합), node=, model=(장치 속성 model 의 값) 네 줄로 적으세요.

ResourceSlice 는 클러스터 범위 객체입니다. spec.devices 가 장치 목록이고, 장치마다 attributes 아래에 이름 → 형식 → 값의 꼴로 속성이 있습니다.

DeviceClass 는 무엇을 고르나

DeviceClass gpu.example.com 의 선택식을 「/root/gsb-dra/class.txt」 에 deviceclass= 와 selector=(CEL 식 그대로) 두 줄로 적으세요. 그리고 노드 allocatable 에 이 장치가 나타나지 않는다는 것을 직접 확인해 보세요.

DeviceClass 의 spec.selectors 아래 cel.expression 에 있습니다. 장치 플러그인과 달리 DRA 장치는 노드 status 의 숫자로 광고되지 않습니다.

틀로 요청서를 찍어 파드에 장치를 준다

dra-lab 네임스페이스에 ResourceClaimTemplate one-gpu(DeviceClass gpu.example.com 에서 장치 1개)와 그 틀을 쓰는 Pod dra-1 을 「/root/gsb-dra/one.yaml」 한 파일에 적어 적용하세요. dra-1 은 Running 이어야 합니다.

파드의 spec.resourceClaims 에 틀 이름을 적고, 컨테이너의 resources.claims 에서 그 이름을 가리킵니다. 둘 중 하나라도 빠지면 장치가 컨테이너에 들어가지 않습니다.

찍혀 나온 요청서와 할당 결과를 읽는다

dra-1 을 위해 만들어진 요청서의 이름, 할당된 장치 이름, 그리고 그 장치가 컨테이너에 들어온 환경 변수 이름을 「/root/gsb-dra/claim.json」 에 claim, device, env_var 세 키로 적으세요.

요청서 이름은 파드의 status.resourceClaimStatuses 에, 할당은 요청서의 status.allocation.devices.results 에 있습니다. 이 드라이버는 장치마다 GPU_DEVICE_<번호> 변수를 넣습니다.

CEL 로 장치 하나를 정확히 고른다

속성 index 가 7 인 장치만 고르는 ResourceClaim pick-seven 과 그것을 쓰는 Pod dra-7 을 「/root/gsb-dra/pick.yaml」 에 적어 적용하세요. pick-seven 에 gpu-7 이 할당되어야 합니다.

요청의 selectors 에 CEL 식을 적습니다. 속성은 device.attributes['드라이버 이름'].속성이름 으로 읽고, 정수는 따옴표 없이 비교합니다.

요청서 하나를 두 파드가 함께 쓴다

ResourceClaim shared(장치 1개)와 그 요청서를 함께 가리키는 Pod share-a, share-b 를 「/root/gsb-dra/shared.yaml」 에 적어 적용하세요. 두 파드가 Running 이고 같은 장치를 받아야 합니다.

틀이 아니라 이름 있는 요청서를 두 파드가 resourceClaimName 으로 가리킵니다. 요청서의 status.reservedFor 에 두 파드가 모두 올라야 합니다.

장치 둘을 한 요청서로 받는다

장치 2개를 한 요청으로 받는 ResourceClaimTemplate two-gpus(allocationMode: ExactCount, count: 2)와 그 틀을 쓰는 Pod dra-2x 를 「/root/gsb-dra/two.yaml」 에 적어 적용하세요.

exactly 아래에 allocationMode 와 count 를 함께 적습니다. 할당 결과(results)에 장치가 두 줄 생겨야 합니다.

남은 장치보다 많이 요청하고 장부를 계산한다

장치 4개를 요청하는 Pod dra-big 을 dra-lab 에 만드세요(틀 이름은 자유). 남은 장치가 모자라 Pending 이 되어야 합니다. 그리고 「/root/gsb-dra/report.json」 에 allocated_devices(할당된 서로 다른 장치 수), free_devices(8 에서 뺀 수), pending_pods(dra-lab 의 Pending 파드 이름 목록)를 적으세요.

함께 쓰는 요청서의 장치는 한 번만 셉니다. 할당이 없는 요청서(Pending 파드의 것)는 세지 않습니다.