폐쇄망 GPU 드라이버 반입 설치 · nvidia-container-toolkit 설치와 런타임 등록 · 이론
containerd 에 런타임 등록하기
한 줄 요약
컨테이너에서 GPU 를 쓰려면 드라이버(커널) + 툴킷(주입 도구) + 런타임 등록(config.toml) 세 가지가 모두 있어야 한다. 하나만 빠져도 증상은 똑같이 "GPU 가 안 보인다" 다.
왜 이게 필요했나
드라이버를 깔고 nvidia-smi 도 잘 되는데 컨테이너 안에서는 GPU 가 안 보인다. 흔한 상황이고, 원인은 대개 런타임 등록이 안 된 것이다.
어떻게 동작하나
세 층
| 층 | 무엇 | 확인 방법 |
| --- | --- | --- |
| 커널 | nvidia.ko 모듈, /dev/nvidia* 장치 노드 | lsmod \| grep nvidia, ls /dev/nvidia* |
| 유저 공간 | libcuda.so, libnvidia-ml.so 등 | nvidia-smi, ldconfig -p \| grep nvidia |
| 컨테이너 주입 | nvidia-container-cli, CDI 스펙, 런타임 등록 | nvidia-ctk cdi list, config.toml |
컨테이너 안에는 커널이 없다(호스트와 공유). 그래서 필요한 것은 유저 공간 라이브러리와 장치 노드를 컨테이너 안으로 넣어 주는 일이고, 그걸 하는 것이 툴킷이다.
containerd config.toml
containerd config default 로 기본 파일을 만든 뒤 런타임을 추가한다. 손으로 헤더를 조립하지 마라 — 섹션 헤더가 containerd 메이저 버전에 따라 통째로 바뀐다.
config version 2(containerd 1.x):
version = 2[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia] runtime_type = "io.containerd.runc.v2"[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options] BinaryName = "/usr/bin/nvidia-container-runtime" SystemdCgroup = trueconfig version 3(containerd 2.x)에서는 CRI 설정이 런타임과 이미지 둘로 쪼개진다.
version = 3[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.nvidia.options] BinaryName = '/usr/bin/nvidia-container-runtime' SystemdCgroup = true버전 2 파일은 2.x 에서도 지원되며 자동 변환된다. 버전 1 은 2.0 부터 지원되지 않는다. 인터넷에서 주워 온 스니펫을 붙였는데 아무 효과가 없다면 대부분 이 버전 불일치다.
nvidia-ctk 가 이 편집을 대신해 준다.
nvidia-ctk runtime configure --runtime=containerd --set-as-default=false--set-as-default=false 가 중요하다. 기본 런타임을 nvidia 로 바꾸면 GPU 를 안 쓰는 파드까지 그 런타임을 거친다. 그 런타임에 문제가 생기면 클러스터 전체가 영향을 받는다.
SystemdCgroup
기본값은 false 다. 그런데 systemd 기반 호스트에서는 true 가 권장된다. 왜냐하면 kubelet 만 systemd cgroup 드라이버로 바꾸고 containerd 를 그대로 두면 두 관리자가 서로 다른 cgroup 뷰를 갖게 되기 때문이다. 이 불일치는 리소스 제한이 이상하게 동작하거나 파드가 예상과 다르게 축출되는 형태로 나타난다.
RuntimeClass
등록한 런타임을 워크로드가 선택하게 한다.
apiVersion: node.k8s.io/v1kind: RuntimeClassmetadata: name: nvidiahandler: nvidia # config.toml 의 runtimes.<이름> 과 일치해야 한다spec: runtimeClassName: nvidia containers: - name: cuda resources: limits: nvidia.com/gpu: 1handler 값과 config.toml 의 런타임 이름이 정확히 일치해야 한다. 안 맞으면 파드가 RunContainerError 로 뜨고 메시지에 "no runtime for ... is configured" 가 나온다.
관리형 노드의 함정
관리형 노드 그룹에서는 노드 부트스트랩 때 config.toml 이 다시 생성되는 경우가 많다. 손으로 고친 설정은 노드가 교체되는 순간 사라지고, 더 나쁘게는 일부 노드에만 남아 재현되지 않는 차이를 만든다. 설정을 바꿔야 한다면 부트스트랩 스크립트나 런치 템플릿, 또는 노드 이미지 자체를 고쳐야 한다. 노드에 들어가서 고친 것은 진단이지 배포가 아니다.
현장에서 만나는 모습
드라이버 업데이트 후 GPU 가 안 잡힌다. CDI 스펙 재생성을 잊은 것이다. 스펙에는 버전이 박힌 라이브러리 경로가 들어 있다.
GPU 파드만 시작이 느리다. 컨테이너 시작 때마다 라이브러리를 주입하고 ldcache 를 갱신하는 비용이다. 이미지가 크면 더 두드러진다.
다음 실습에서 할 것
config.toml 에 nvidia 런타임을 등록하고 TOML 파서로 검증한다. CDI 스펙을 배치하고 RuntimeClass YAML 을 작성한다. 실제 GPU 없이도 설정의 정확성은 전부 검증할 수 있다.