NVIDIA device plugin 설치 파일
GPU 를 클러스터 자원으로 알리는 device plugin 설치 파일 두 가지(기본, 시분할) 전문과 항목 설명
k3s 노드가 GPU 를 nvidia.com/gpu 자원으로 광고(클러스터에 GPU 수를 알림)하게 하는 DaemonSet 설치 파일. 서버 소스의 scripts/serving/ 에 두 가지가 있으며 둘 중 하나만 적용. 설치 절차는 k3s·GPU 준비 참고.
기본판은 공개 프로젝트 k8s-device-plugin v0.19.3 의 매니페스트에 runtimeClassName: nvidia 한 줄을 추가한 것. 아래 블록은 서버 저장소의 파일에서 자동 생성(scripts/gen-device-plugin.ts). 원본의 주석은 생략하고 각 항목의 의미는 아래 표에 정리.
두 파일 비교
| 구분 | 기본 | 시분할 |
|---|---|---|
| 파일 | scripts/serving/nvidia-device-plugin.yml | scripts/serving/nvidia-device-plugin-timeSlicing.yml |
| 광고하는 슬롯 | GPU 한 장당 1개 | GPU 한 장당 replicas 개(기본 8) |
| 포함 객체 | DaemonSet | ConfigMap, DaemonSet |
| 사용 시점 | GPU 가 여러 장이고 파드마다 한 장씩 할당하면 되는 경우 | GPU 가 한두 장인데 학습·서빙을 여러 개 동시에 실행해야 하는 경우 |
두 파일의 DaemonSet 은 이름이 같음. 시분할판은 기본판에 ConfigMap 과, 그 설정을 읽기 위한 환경 변수 CONFIG_FILE·볼륨·마운트만 추가한 것.
기본: nvidia-device-plugin.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nvidia-device-plugin-daemonset
namespace: kube-system
spec:
selector:
matchLabels:
name: nvidia-device-plugin-ds
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: nvidia-device-plugin-ds
spec:
runtimeClassName: nvidia
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
priorityClassName: "system-node-critical"
containers:
- image: nvcr.io/nvidia/k8s-device-plugin:v0.19.3
name: nvidia-device-plugin-ctr
env:
- name: FAIL_ON_INIT_ERROR
value: "false"
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
시분할: nvidia-device-plugin-timeSlicing.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: nvidia-device-plugin-config
namespace: kube-system
data:
config.yaml: |-
version: v1
flags:
migStrategy: none
sharing:
timeSlicing:
renameByDefault: false
failRequestsGreaterThanOne: true
resources:
- name: nvidia.com/gpu
replicas: 8
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nvidia-device-plugin-daemonset
namespace: kube-system
spec:
selector:
matchLabels:
name: nvidia-device-plugin-ds
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: nvidia-device-plugin-ds
spec:
runtimeClassName: nvidia
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
priorityClassName: "system-node-critical"
containers:
- image: nvcr.io/nvidia/k8s-device-plugin:v0.19.3
name: nvidia-device-plugin-ctr
env:
- name: FAIL_ON_INIT_ERROR
value: "false"
- name: CONFIG_FILE
value: /etc/nvidia-device-plugin/config.yaml
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
- name: plugin-config
mountPath: /etc/nvidia-device-plugin
readOnly: true
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
- name: plugin-config
configMap:
name: nvidia-device-plugin-config
DaemonSet 항목
| 항목 | 값 | 의미 |
|---|---|---|
| 이름 | nvidia-device-plugin-daemonset (네임스페이스 kube-system) | 앱의 GPU 슬롯 화면이 이 이름으로 플러그인 상태 조회. 다른 이름·네임스페이스로 설치했다면 GEO_MLOPS_KUBERNETES_DEVICE_PLUGIN_NAME, GEO_MLOPS_KUBERNETES_DEVICE_PLUGIN_NAMESPACE 지정 |
runtimeClassName | nvidia | 원본 매니페스트에 추가한 줄. k3s 의 기본 런타임은 nvidia 가 아니므로, 이 줄이 없으면 플러그인이 GPU 를 인식하지 못하고 0개로 보고 |
tolerations | nvidia.com/gpu, NoSchedule | GPU 노드에 같은 이름의 taint 가 있어도 플러그인 배치 |
priorityClassName | system-node-critical | 노드 필수 구성 요소로 취급. 노드 자원이 부족해도 다른 파드보다 먼저 배치 |
| 이미지 | nvcr.io/nvidia/k8s-device-plugin:v0.19.3 | v0.18.2 이상 필요. 통합 메모리 GPU 는 GPU 메모리 조회에 Not Supported 를 반환하는데, 그 이전 버전은 이를 치명 오류로 처리해 GPU 를 하나도 광고하지 않음 |
FAIL_ON_INIT_ERROR | false | 초기화 오류(GPU 를 찾지 못함 등)가 발생해도 컨테이너를 종료하지 않고 대기. 재시작을 반복하지 않음 |
securityContext | 권한 상승 금지, capability 전부 제거 | 컨테이너 권한 최소화 |
device-plugin 볼륨 | 호스트의 /var/lib/kubelet/device-plugins | kubelet 과 통신하는 소켓 디렉터리 |
CONFIG_FILE (시분할판만) | /etc/nvidia-device-plugin/config.yaml | 시분할 설정 파일 경로. 이 환경 변수가 없으면 ConfigMap 은 마운트만 되고 무시됨 |
plugin-config 볼륨 (시분할판만) | ConfigMap nvidia-device-plugin-config | /etc/nvidia-device-plugin 에 읽기 전용 마운트. 앱의 GPU 슬롯 화면도 DaemonSet 이 마운트한 ConfigMap 을 찾아 시분할 설정을 표시 |
시분할 설정
ConfigMap nvidia-device-plugin-config 의 config.yaml 에 들어 있는 키.
| 키 | 값 | 의미 |
|---|---|---|
version | v1 | 설정 파일 형식 버전 |
migStrategy | none | MIG(GPU 하드웨어 분할) 미사용. MIG 를 지원하지 않는 GPU 에서도 시분할만으로 동작 |
renameByDefault | false | 자원 이름을 nvidia.com/gpu 로 유지. true 면 nvidia.com/gpu.shared 로 바뀌므로 학습·서빙이 요청하는 자원 이름(GEO_MLOPS_SERVING_GPU_RESOURCE, 기본 nvidia.com/gpu)도 함께 변경 필요 |
failRequestsGreaterThanOne | true | 슬롯을 2개 이상 요청한 파드는 곧바로 거부. 슬롯 2개는 GPU 2장이 아니므로, 허용하면 실제로는 GPU 한 장으로 실행됨 |
resources 의 name | nvidia.com/gpu | 시분할할 자원 |
resources 의 replicas | 8 | GPU 한 장을 광고할 슬롯 수. 광고만 하는 숫자라 여유 슬롯에 비용 없음. 동시에 실행할 파드 수보다 넉넉하게 지정 |
설정 파일은 하나만 두고 CONFIG_FILE 로 직접 지정. 노드마다 다른 설정을 쓰려면 플러그인의 config-manager 사이드카가 필요하며 이 설치 파일에는 없음.
적용과 변경
하나를 적용한 뒤 노드마다 광고되는 슬롯 수 확인. 시분할판이면 GPU 수 × replicas.
sudo k3s kubectl apply -f /opt/geo-mlops/scripts/serving/nvidia-device-plugin-timeSlicing.yml
sudo k3s kubectl get nodes -o custom-columns='NAME:.metadata.name,ALLOC:.status.allocatable.nvidia\.com/gpu'
-
다른 판으로 교체: 그 파일을
apply. DaemonSet 이름이 같으므로 기존 DaemonSet 이 변경되고 플러그인 파드가 다시 기동. -
시분할판에서 기본판으로 교체: ConfigMap
nvidia-device-plugin-config는 삭제되지 않고 남음. 사용하지 않으므로sudo k3s kubectl -n kube-system delete configmap nvidia-device-plugin-config로 삭제 가능. -
replicas만 변경: ConfigMap 만 바뀌고 DaemonSet 은 그대로이므로 플러그인이 다시 기동하지 않음. 적용 후 롤아웃 필요.sudo k3s kubectl apply -f /opt/geo-mlops/scripts/serving/nvidia-device-plugin-timeSlicing.yml sudo k3s kubectl -n kube-system rollout restart ds/nvidia-device-plugin-daemonset -
폐쇄망: 이미지
nvcr.io/nvidia/k8s-device-plugin:v0.19.3를 k3s 에 미리 반입(폐쇄망 설치).