본문으로 건너뛰기
버전: 1.0.3

8.3. 디바이스 (GPU 공유)

어떨 때 보는가

  • GPU 를 쓰는 애플리케이션을 배포할 때
  • GPU 파드가 Pending 에서 넘어가지 않을 때
  • 남은 GPU 가 있는지 확인할 때
  • 여러 팀이 GPU 를 나눠 쓰는지 확인할 때

GPU 를 나눠 쓰기 어려운 이유

CPU 와 메모리는 소수점 단위로 쪼갤 수 있습니다. "CPU 0.5개" 를 요청하면 스케줄러가 알아서 나눠 줍니다.

GPU 는 그렇지 않습니다.

CPU · 메모리GPU
나누기소수점까지 쪼갤 수 있습니다장치 단위가 기본입니다
종류 구분없습니다모델·메모리 크기가 제각각입니다
요청 방법숫자로 적습니다"어떤 조건의 장치" 를 적어야 합니다
여럿이 함께 쓰기당연합니다드라이버가 지원해야 합니다

"GPU 1개" 라고만 적으면 어느 모델을 받을지 알 수 없습니다. 8GB 짜리로는 안 되는 작업이 있고, 특정 세대에서만 도는 라이브러리도 있습니다.

DRA 란

DRA(Dynamic Resource Allocation)는 이런 복잡한 장치를 다루기 위한 Kubernetes 할당 방식 입니다.

숫자로 요청하는 대신 별도의 요청 자원을 만들고 파드가 그것을 참조 합니다. 요청에는 "어떤 클래스의 장치가 필요하고, 어떤 조건을 만족해야 하는지" 를 적습니다.

디바이스 자원 구조

이 방식이 주는 것은 이렇습니다.

할 수 있는 것설명
조건으로 고르기"메모리 16GB 이상인 GPU" 처럼 요청합니다
여러 파드가 공유드라이버가 지원하면 한 장치를 나눠 씁니다
네임스페이스를 넘는 공유팀이 달라도 같은 장치를 함께 씁니다
장치별 상태 확인어느 장치가 어디에 배정됐는지 화면에서 봅니다

드라이버가 있어야 동작합니다. DRA 는 Kubernetes 의 틀이고, 실제 장치를 발견하고 배정하는 것은 GPU 제조사가 제공하는 드라이버입니다. 드라이버가 없으면 목록이 전부 비어 있습니다.

자원 네 가지와 역할

자원범위누가 만드나역할
디바이스 클래스클러스터드라이버·운영자장치의 종류와 고르는 조건
리소스 슬라이스클러스터드라이버가 자동노드별 실제 장치 목록
리소스 클레임네임스페이스사용자장치를 쓰겠다는 요청
리소스 클레임 템플릿네임스페이스사용자파드마다 요청을 자동 생성하는 틀

앞의 둘은 읽기만 합니다. 뒤의 둘을 사용자가 만듭니다.

디바이스 클래스

장치의 종류 를 정의합니다. 디바이스 > 디바이스 클래스 로 들어갑니다.

디바이스 클래스 목록
항목설명
이름요청할 때 쓰는 이름
선택 조건이 클래스에 속하는 장치의 조건
기본 설정이 클래스로 요청할 때 자동으로 붙는 설정

GPU 모델별로 클래스가 등록됩니다. 파드는 클래스 이름으로 "이런 종류의 장치가 필요하다" 고 요청하고, 어느 노드의 몇 번째 장치인지는 지정하지 않습니다.

리소스 슬라이스

노드에 실제로 장착된 장치 목록입니다. 디바이스 > 리소스 슬라이스 에서 봅니다.

드라이버가 노드를 검사해 자동으로 등록 합니다. 사용자가 만들거나 고치지 않습니다.

확인할 것설명
드라이버이 목록을 발행한 드라이버
노드어느 노드에 장착되어 있는지
장치 목록그 노드의 장치와 각각의 속성

요청한 장치가 배정되지 않으면 여기서 남은 장치가 있는지 먼저 확인하십시오.

공유 가능 장치 읽는 법

장치 상세에 다음 값이 있으면 여러 파드가 함께 쓸 수 있는 장치 입니다.

항목
공유 가능이 장치를 여럿이 나눠 쓸 수 있는지
용량나눠 쓸 수 있는 총량. 예: 메모리 16311Mi
요청 범위한 요청이 가져갈 수 있는 범위와 단위

공유가 켜져 있으면 네임스페이스가 달라도 같은 장치를 함께 씁니다. 팀 A 가 GPU 를 잡아도 팀 B 가 나머지를 쓸 수 있습니다.

공유가 꺼져 있으면 한 파드가 장치를 통째로 차지합니다. 이때는 먼저 잡은 쪽이 놓을 때까지 다른 요청이 기다립니다.

공유 지원 여부는 드라이버 버전에 달려 있습니다. 공유가 안 되는 것 같으면 운영 담당자에게 드라이버 버전을 확인하십시오.

리소스 클레임

장치를 쓰겠다는 요청 입니다. 디바이스 > 리소스 클레임 에서 봅니다.

상태
Pending배정할 장치를 찾는 중
Allocated장치가 배정됨

상세 화면에서 다음을 확인합니다.

항목무엇을 알 수 있는가
요청어떤 클래스의 장치를 몇 개, 어떤 조건으로 요청했는지
할당 결과어느 노드의 어느 장치가 배정됐는지
사용 주체어떤 파드가 이 요청을 쓰고 있는지
장치 상태배정된 장치의 드라이버·풀·이름과 공유 식별자

사용 주체가 비어 있는데 상태가 Allocated 장치를 잡아 두고 쓰지 않는 것입니다. 다른 파드가 기다리고 있다면 정리 대상입니다.

리소스 클레임 템플릿

같은 요청을 여러 파드가 되풀이해서 쓴다면 디바이스 > 리소스 클레임 템플릿 으로 만들어 둡니다.

Deployment 가 파드를 3개 띄우면 템플릿에서 클레임이 3개 자동으로 만들어집니다. 파드마다 클레임을 손으로 만들 필요가 없습니다.

상황쓸 것
파드 하나가 특정 장치를 오래 씀리소스 클레임
복제본이 여럿이고 각각 장치가 필요함리소스 클레임 템플릿
파드가 사라지면 요청도 사라져야 함템플릿

템플릿으로 만들어진 클레임은 파드와 수명을 같이합니다. 파드가 지워지면 클레임도 함께 지워져 장치가 풀립니다. 손으로 만든 클레임은 파드가 사라져도 남으니 직접 정리해야 합니다.

GPU 를 쓰는 순서

  1. 디바이스 클래스 에서 쓸 수 있는 장치 종류를 확인합니다.
  2. 리소스 슬라이스 에서 남은 장치와 공유 가능 여부를 봅니다.
  3. 파드 정의에 리소스 클레임(또는 템플릿)을 넣어 배포합니다.
  4. 리소스 클레임Allocated 가 되는지 확인합니다.
  5. 파드가 Running 이 되는지 확인합니다(3.1 장).

파드에서 GPU 를 쓰는 방법 — YAML

요청 방식 두 가지를 먼저 고릅니다

파드에 장치를 붙이는 방법은 두 가지이고, 어느 쪽을 쓰느냐가 공유 여부를 가릅니다.

참조 방식결과언제 쓰는가
resourceClaimName — 미리 만든 클레임을 이름으로 가리킴여러 파드가 같은 장치를 나눠 씁니다GPU 가 모자라고 여러 워크로드가 함께 써야 할 때
resourceClaimTemplateName — 템플릿을 가리킴파드마다 클레임이 새로 생겨 장치를 하나씩 독점합니다복제본마다 장치가 따로 필요할 때

이 둘을 혼동하면 증상이 헷갈립니다. 공유하려던 것을 템플릿으로 쓰면 GPU 가 1장인 노드에서 두 번째 파드부터 Pending 에 머뭅니다. 첫 파드는 정상이라 설정이 맞는 것처럼 보입니다.

방법 1 — 여러 파드가 GPU 한 장을 나눠 쓰기

먼저 클레임을 하나 만듭니다. 파드보다 먼저 있어야 합니다.

apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
name: shared-gpu
namespace: my-app
spec:
devices:
requests:
- name: gpu
exactly:
deviceClassName: gpu.nvidia.com # 디바이스 클래스 화면의 이름
allocationMode: ExactCount
count: 1
항목설명
deviceClassName디바이스 클래스 화면에 있는 이름을 그대로 씁니다. 없는 이름을 적으면 클레임이 Pending 에 머뭅니다
allocationModeExactCountcount 만큼, All 은 조건에 맞는 장치 전부
count몇 개를 요청할지

그 다음 파드가 이름으로 가리킵니다. 파드 스펙과 컨테이너 스펙 두 곳에 모두 적어야 합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-gpu-app
namespace: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-gpu-app
template:
metadata:
labels:
app: my-gpu-app
spec:
resourceClaims: # ① 파드가 어떤 클레임을 쓰는지
- name: gpu # 파드 안에서 부를 이름
resourceClaimName: shared-gpu # 실제 ResourceClaim 이름
containers:
- name: app
image: registry.example.com/my-gpu-app:1.0
resources:
claims: # ② 이 컨테이너가 그중 무엇을 쓰는지
- name: gpu # ①의 name 과 같아야 합니다
limits:
cpu: "2"
memory: 4Gi
위치하는 일
spec.resourceClaims파드가 쓸 클레임 목록. 여기 이름은 파드 안에서만 통합니다
containers[].resources.claims파드가 받은 것 중 이 컨테이너에 붙일 것

두 곳 중 하나만 적으면 장치가 연결되지 않습니다. 파드에만 적으면 컨테이너에서 GPU 가 보이지 않고, 컨테이너에만 적으면 파드 생성이 거부됩니다.

이 예에서는 복제본 3개가 모두 같은 GPU 한 장 을 씁니다. 리소스 클레임 상세의 사용 주체에 파드 3개가 함께 표시됩니다.

방법 2 — 복제본마다 GPU 를 따로 잡기

템플릿을 만들고 파드가 그것을 가리킵니다.

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
name: dedicated-gpu
namespace: my-app
spec:
spec:
devices:
requests:
- name: gpu
exactly:
deviceClassName: gpu.nvidia.com
allocationMode: ExactCount
count: 1

spec 이 두 번 나오는 것이 맞습니다. 바깥은 템플릿의 명세, 안쪽은 템플릿이 찍어 낼 클레임의 명세 입니다.

spec:
resourceClaims:
- name: gpu
resourceClaimTemplateName: dedicated-gpu # 템플릿 이름
containers:
- name: app
image: registry.example.com/my-gpu-app:1.0
resources:
claims:
- name: gpu

복제본 수만큼 장치가 필요합니다. 복제본 3개면 GPU 3장이 있어야 하고, 모자라면 남은 파드는 Pending 에 머뭅니다.

옛 방식과 무엇이 다른가

예전에는 컨테이너의 자원 상한에 GPU 개수를 적었습니다.

resources:
limits:
nvidia.com/gpu: "1" # 옛 방식

DRA 로 바꿀 때는 이 줄을 지웁니다. 두 방식을 함께 쓰면 장치를 두 번 요청하게 됩니다. CPU·메모리 상한은 그대로 둡니다(3.1 장).

옛 방식DRA
요청하는 곳컨테이너의 자원 상한ResourceClaim
요청할 수 있는 것개수만개수 + 조건(모델·메모리·분할 여부)
공유노드 단위 설정이라 그 노드 전체에 적용클레임 단위라 필요한 워크로드끼리만
확인 화면노드 상세의 할당 가능 자원디바이스 메뉴

적용한 뒤 확인할 것

순서어디에서정상이면
1디바이스 > 리소스 클레임상태가 Allocated
2같은 화면 상세할당 결과에 노드와 장치 이름이 있음
3같은 화면 상세사용 주체에 내 파드가 있음
4워크로드 > PodRunning(3.1 장)

1번에서 Pending 이면 파드는 뜨지 않습니다. 아래 "배정되지 않을 때" 를 보십시오.

자주 틀리는 것

증상원인
두 번째 파드부터 Pending공유하려 했는데 resourceClaimTemplateName 을 썼습니다
컨테이너에서 GPU 가 안 보임containers[].resources.claims 를 빠뜨렸습니다
파드 생성이 거부됨spec.resourceClaims 를 빠뜨렸거나 두 곳의 name 이 다릅니다
클레임이 계속 PendingdeviceClassName 이 실제 디바이스 클래스 이름과 다릅니다
장치를 두 배로 잡음옛 방식(limits.nvidia.com/gpu)을 함께 남겨 두었습니다
다른 네임스페이스 파드와 공유가 안 됨클레임은 네임스페이스 단위입니다. 드라이버 버전에 따라 가능 여부가 다르니 운영 담당자에게 확인하십시오

노드를 직접 지정할 수 없습니다. DRA 는 스케줄러가 장치를 배정해야 하므로 파드에 노드 이름을 박아 두면 배정이 되지 않습니다. 특정 노드로 보내야 하면 노드 선택 조건 (nodeSelector)을 쓰십시오.

장치 목록이 비어 있을 때

디바이스 클래스와 리소스 슬라이스가 모두 비어 있으면 드라이버가 없거나 동작하지 않는 것입니다.

확인설명
GPU 노드가 있는가노드 목록에서 GPU 노드를 확인합니다 (2.1 장)
드라이버 파드가 떠 있는가드라이버는 GPU 노드마다 파드로 돕니다
클러스터가 DRA 를 지원하는가운영 담당자에게 확인

이 화면은 조회 전용입니다. 드라이버 설치와 설정은 운영 담당자가 수행합니다.

배정되지 않을 때

증상원인확인할 것
클레임이 Pending남은 장치가 없음리소스 슬라이스에서 사용 중인 장치 확인
클레임이 Pending조건에 맞는 장치가 없음요청한 클래스·속성이 실제 장치와 맞는지
클레임이 Pending공유가 꺼져 있고 먼저 잡은 파드가 있음그 장치의 공유 가능 여부
파드가 Pending클레임은 배정됐으나 노드 자원 부족그 노드의 CPU·메모리 여유
여러 팀이 동시에 못 씀드라이버가 공유를 지원하지 않음드라이버 버전

GPU 는 대개 노드 수보다 적어 경쟁이 심합니다. 쓰지 않는 파드가 장치를 잡고 있는지 리소스 클레임 목록에서 확인하십시오. 개발·시험용 파드를 정리하면 자리가 납니다.

MIG 와 DRA 의 관계

두 가지를 혼동하기 쉬운데 층이 다릅니다.

MIGDRA
무엇인가GPU 하드웨어를 여러 조각으로 나누는 기능Kubernetes 의 장치 할당 방식
어디에 있나GPU 안Kubernetes 안
제공하는 것조각마다 전용 연산 자원과 메모리, 장애 격리조건에 맞는 장치를 찾아 배정
쓸 수 있는 GPU데이터센터용 일부 모델만드라이버가 지원하는 모든 GPU

"DRA 를 쓰면 MIG 가 필요 없다" 는 것은 아닙니다. MIG 가 GPU 를 조각으로 나누고, DRA 가 그 조각을 파드에 배정합니다. 두 가지를 함께 쓸 수 있습니다.

하드웨어 수준의 격리(한 작업이 다른 작업의 성능이나 안정성에 영향을 주지 않는 것)는 MIG 만 제공합니다. DRA 의 공유는 소프트웨어 수준이라 서로 영향을 줄 수 있습니다.

어떤 방식을 쓰는지는 클러스터 구성에 달려 있습니다. 리소스 슬라이스의 장치 목록에 조각으로 나뉜 장치가 보이면 MIG 가 적용된 것입니다.