본문 바로가기
일반IT/AI

컨테이너에서 GPU는 어떻게 동작할까? NVIDIA Container Toolkit 아키텍처 이해하기

by gasbugs 2026. 7. 4.
반응형

AI 실습 환경이나 GPU 서버를 구성하다 보면 이런 명령어를 자주 보게 됩니다.

docker run --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi

 

또는 Kubernetes 환경에서는 GPU 노드에 NVIDIA 드라이버를 설치하고, NVIDIA Container Toolkit을 구성한 뒤, GPU가 필요한 컨테이너를 실행합니다.

 

여기서 자연스럽게 이런 질문이 생깁니다.

“컨테이너는 원래 격리된 환경인데, 어떻게 호스트 서버의 GPU를 사용할 수 있을까?”

 

 

이 질문에 대한 답이 바로 NVIDIA Container Toolkit의 아키텍처입니다.

 

NVIDIA Container Toolkit은 Docker, containerd, CRI-O, LXC 같은 다양한 컨테이너 런타임에서 NVIDIA GPU를 사용할 수 있도록 도와주는 구성 요소들의 묶음입니다. NVIDIA 공식 문서에서도 NVIDIA 컨테이너 스택은 특정 런타임 하나에만 묶이지 않고, 생태계의 여러 컨테이너 런타임을 지원할 수 있도록 설계되어 있다고 설명합니다.

 


1. 왜 NVIDIA Container Toolkit이 필요할까?

컨테이너는 기본적으로 호스트와 격리된 실행 환경입니다. 그래서 컨테이너 안에서 GPU를 사용하려면 단순히 CUDA 이미지 하나만 실행한다고 끝나지 않습니다.

 

GPU를 사용하려면 대략 다음 요소들이 필요합니다.

첫째, 호스트 OS에 NVIDIA GPU 드라이버가 설치되어 있어야 합니다.

둘째, 컨테이너 안에서 /dev/nvidia* 같은 GPU 장치 파일에 접근할 수 있어야 합니다.

셋째, 컨테이너 안에서 NVIDIA 드라이버 관련 라이브러리와 실행 파일을 사용할 수 있어야 합니다.

넷째, Docker, containerd, CRI-O 같은 컨테이너 런타임이 “이 컨테이너에는 GPU를 연결해야 한다”는 정보를 이해해야 합니다.

 

즉, GPU 컨테이너 실행은 단순히 컨테이너 이미지만의 문제가 아닙니다. 호스트의 GPU 장치, 드라이버, 라이브러리, 컨테이너 런타임 설정이 함께 맞물려야 합니다.

 

NVIDIA Container Toolkit은 이 과정을 자동화하고 표준화해주는 도구입니다.

 

쉽게 말하면 다음과 같습니다.

NVIDIA Container Toolkit은 컨테이너가 호스트의 NVIDIA GPU를 안전하고 일관된 방식으로 사용할 수 있도록 장치 파일, 드라이버 라이브러리, 런타임 설정을 연결해주는 계층이다.


2. NVIDIA Container Stack의 큰 구조

NVIDIA 공식 문서에서 설명하는 NVIDIA 컨테이너 스택의 주요 구성 요소는 크게 세 가지입니다.

구성 요소 대표 명령/패키지 역할
NVIDIA Container Runtime nvidia-container-runtime Docker/containerd 같은 런타임과 runC 사이에서 NVIDIA 설정을 주입
NVIDIA Container Runtime Hook nvidia-container-toolkit, nvidia-container-runtime-hook 컨테이너 시작 직전에 GPU 장치와 라이브러리 주입 작업을 수행
NVIDIA Container Library and CLI libnvidia-container1, nvidia-container-cli 실제 GPU 장치, 드라이버 라이브러리, 마운트 구성을 처리

 

이 구성 요소들은 개별적으로 존재하지만, 일반 사용자는 보통 nvidia-container-toolkit 패키지를 설치해서 사용합니다. NVIDIA 문서에서도 모든 사용 사례에서는 nvidia-container-toolkit 패키지 설치만으로 충분하다고 설명합니다.


3. 전체 흐름을 먼저 이해하기

Docker 기준으로 컨테이너가 GPU를 사용하는 흐름을 단순화하면 다음과 같습니다.

사용자
  ↓
docker run --gpus all ...
  ↓
Docker daemon
  ↓
nvidia-container-runtime
  ↓
runC spec 수정
  ↓
NVIDIA prestart hook 추가
  ↓
runC 실행
  ↓
nvidia-container-cli 호출
  ↓
GPU 장치와 라이브러리 컨테이너에 주입
  ↓
컨테이너 내부에서 nvidia-smi 실행 가능

 

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/arch-overview.html

 

여기서 핵심은 nvidia-container-runtime이 직접 컨테이너를 완전히 실행하는 독립 런타임이라기보다는, 기존 runC 앞단에서 NVIDIA 관련 설정을 끼워 넣는 역할을 한다는 점입니다.

 

NVIDIA 문서에 따르면 nvidia-container-runtime은 과거에는 runC를 포크한 구조였지만, 2019년 이후에는 호스트에 설치된 native runC를 감싸는 얇은 wrapper 형태로 동작합니다. 이 runtime은 runC spec을 입력으로 받아 NVIDIA Container Runtime Hook을 prestart hook으로 추가한 뒤, 수정된 spec을 native runC에 넘깁니다.


4. 가장 아래 계층: libnvidia-container와 nvidia-container-cli

NVIDIA 컨테이너 스택에서 가장 아래쪽에 있는 핵심 구성 요소가 libnvidia-container와 nvidia-container-cli입니다.

 

공식 문서에서는 이 구성 요소들이 GNU/Linux 컨테이너가 NVIDIA GPU를 사용할 수 있도록 자동 구성하는 라이브러리와 CLI이며, 구현은 Linux kernel primitive를 기반으로 하고 특정 컨테이너 런타임에 종속되지 않도록 설계되어 있다고 설명합니다.

 

쉽게 말하면 이 계층은 실제 작업 담당자입니다.

 

예를 들어 컨테이너 안에 다음과 같은 것들을 연결해야 합니다.

/dev/nvidia0
/dev/nvidiactl
/dev/nvidia-uvm
NVIDIA driver library
CUDA 관련 runtime library
GPU capabilities 정보

 

이때 “어떤 GPU를 넣을지”, “어떤 라이브러리를 마운트할지”, “컨테이너 안에서 어떤 경로로 보이게 할지” 같은 작업을 처리하는 핵심 도구가 nvidia-container-cli입니다.

 

즉, 컨테이너 런타임이 직접 NVIDIA GPU 세부 구성을 모두 아는 것이 아니라, NVIDIA가 제공하는 nvidia-container-cli를 호출해서 GPU 지원을 주입하는 구조입니다.


5. 중간 계층: NVIDIA Container Runtime Hook

그다음 중요한 구성 요소가 NVIDIA Container Runtime Hook입니다.

 

공식 문서에 따르면 이 hook은 runC의 prestart hook 인터페이스를 구현한 실행 파일입니다. runC가 컨테이너를 생성한 뒤, 아직 컨테이너 프로세스를 시작하기 전에 이 hook이 호출됩니다. 이때 hook은 컨테이너의 config.json 정보를 읽고, 적절한 플래그와 함께 nvidia-container-cli를 호출합니다. 특히 어떤 GPU 장치를 컨테이너에 주입할지가 중요한 플래그 중 하나입니다.

 

이 설명을 조금 더 쉽게 풀면 다음과 같습니다.

 

컨테이너 실행 과정에는 “컨테이너를 만들었지만 아직 시작하지 않은 순간”이 있습니다.

 

바로 이 시점이 중요합니다.

 

컨테이너가 이미 시작된 뒤에 GPU 장치와 라이브러리를 억지로 넣는 것이 아니라, 컨테이너 시작 직전에 필요한 GPU 설정을 미리 주입합니다.

 

그래서 prestart hook이라는 이름이 붙습니다.

컨테이너 생성
  ↓
아직 애플리케이션 실행 전
  ↓
NVIDIA prestart hook 실행
  ↓
GPU 장치와 라이브러리 주입
  ↓
컨테이너 애플리케이션 시작

 

이 구조 덕분에 컨테이너 내부 애플리케이션은 마치 GPU가 원래 컨테이너 안에 있는 것처럼 사용할 수 있습니다.


6. 상위 계층: NVIDIA Container Runtime

Docker나 containerd 환경에서는 nvidia-container-runtime이 OCI-compliant runtime으로 설정됩니다. NVIDIA 문서에서도 Docker 또는 containerd를 사용할 때는 NVIDIA Container Runtime이 OCI-compliant runtime으로 구성된다고 설명합니다.

 

여기서 OCI는 Open Container Initiative를 의미합니다. 컨테이너 이미지와 런타임 동작 방식에 대한 표준을 정의하는 생태계입니다.

 

Docker를 실행한다고 해서 Docker 혼자 모든 일을 처리하는 것은 아닙니다. Docker는 내부적으로 containerd, runC 같은 계층과 함께 동작합니다.

 

단순화하면 다음과 같습니다.

Docker CLI
  ↓
Docker daemon
  ↓
containerd
  ↓
OCI runtime
  ↓
runC
  ↓
Linux namespace / cgroup 기반 컨테이너 실행

 

NVIDIA Container Runtime은 이 흐름 중 OCI runtime 단계에 끼어듭니다.

 

사용자가 GPU 컨테이너를 실행하면 NVIDIA Container Runtime이 runC spec을 수정하고, NVIDIA hook을 추가한 뒤, 실제 컨테이너 실행은 native runC에 맡깁니다.

 

이 구조를 이해하면 nvidia-container-runtime이라는 이름 때문에 생길 수 있는 오해를 줄일 수 있습니다.

 

nvidia-container-runtime은 Docker 자체를 대체하는 것이 아닙니다. 또한 runC 전체를 대체하는 것도 아닙니다. 현재 구조에서는 기존 runC 앞에서 NVIDIA GPU 설정을 주입하는 wrapper에 가깝습니다.


7. Docker/containerd와 CRI-O/LXC의 차이

NVIDIA Container Toolkit은 컨테이너 런타임 종류에 따라 사용되는 흐름이 달라집니다.

 

공식 문서에서는 Docker 또는 containerd의 경우 nvidia-container-runtime이 OCI-compliant runtime으로 구성된다고 설명합니다. 반면 CRI-O와 LXC의 흐름에서는 NVIDIA Container Runtime 컴포넌트가 필요하지 않다고 설명합니다.

 

이 차이를 쉽게 정리하면 다음과 같습니다.

 

 

런타임 주요 흐름 특징
Docker Docker → NVIDIA Container Runtime → runC → NVIDIA Hook Docker에 NVIDIA runtime을 등록해서 사용
containerd containerd → NVIDIA Container Runtime → runC → NVIDIA Hook Kubernetes 노드에서 자주 사용
CRI-O CRI-O → NVIDIA Hook/CLI 계층 별도 NVIDIA Container Runtime이 필요하지 않을 수 있음
LXC LXC → NVIDIA Hook/CLI 계층 Docker 계열과 흐름이 다름
Podman CDI 사용 권장 최근에는 CDI 방식이 중요

 

즉, NVIDIA Container Toolkit은 하나의 방식만 강제하지 않습니다. 컨테이너 런타임의 구조에 따라 GPU를 주입하는 경로가 달라집니다.


8. 패키지 구조 이해하기

NVIDIA Container Toolkit의 주요 패키지는 다음과 같습니다.

nvidia-container-toolkit
nvidia-container-toolkit-base
libnvidia-container-tools
libnvidia-container1

 

패키지 의존성은 대략 다음과 같습니다.

nvidia-container-toolkit
 ├─ libnvidia-container-tools
 │   └─ libnvidia-container1
 └─ nvidia-container-toolkit-base

libnvidia-container-tools
 └─ libnvidia-container1

libnvidia-container1

 

각 패키지를 역할 중심으로 보면 다음과 같습니다.

패키지 역할
libnvidia-container1 NVIDIA GPU 컨테이너 지원을 위한 핵심 라이브러리
libnvidia-container-tools nvidia-container-cli 등 CLI 도구 제공
nvidia-container-toolkit-base nvidia-container-runtime, nvidia-ctk 등 기본 도구 포함
nvidia-container-toolkit 일반적으로 설치하는 통합 패키지

 

실무에서는 패키지를 하나하나 나눠서 설치하기보다는 대부분 nvidia-container-toolkit을 설치하면 됩니다.

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/arch-overview.html

 

공식 문서도 모든 사용 사례에서 nvidia-container-toolkit 설치가 충분하다고 설명합니다.


9. nvidia-docker2는 이제 뭘까?

예전 자료를 보면 nvidia-docker2라는 패키지를 자주 볼 수 있습니다.

 

과거에는 NVIDIA GPU를 Docker에서 사용하려면 nvidia-docker2를 설치하라는 문서가 많았습니다. 그래서 아직도 오래된 블로그나 설치 가이드에는 nvidia-docker2가 등장합니다.

 

하지만 현재 NVIDIA 공식 문서에서는 nvidia-docker2와 nvidia-container-runtime 패키지를 deprecated로 봐야 한다고 설명합니다. 그 기능이 nvidia-container-toolkit 패키지로 병합되었기 때문입니다. 다만 오래된 워크플로우와의 호환성을 위해 패키지가 여전히 제공될 수는 있습니다.

 

정리하면 다음과 같습니다.

과거 방식:
nvidia-docker2 중심

현재 권장 방식:
nvidia-container-toolkit 중심

 

따라서 새 환경을 구성한다면 nvidia-docker2를 기준으로 보기보다는 nvidia-container-toolkit과 nvidia-ctk를 기준으로 보는 것이 좋습니다.


10. nvidia-ctk는 어떤 도구인가?

nvidia-ctk는 NVIDIA Container Toolkit CLI입니다.

 

공식 문서에서는 이 CLI가 Docker 같은 런타임을 NVIDIA Container Toolkit과 함께 사용할 수 있도록 설정하거나, CDI 사양을 생성하는 등의 기능을 포함한다고 설명합니다.

 

예를 들어 Docker에서 NVIDIA runtime을 사용하도록 설정하려면 다음 명령을 사용할 수 있습니다.

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

 

NVIDIA 설치 문서에 따르면 이 명령은 호스트의 /etc/docker/daemon.json 파일을 수정해서 Docker가 NVIDIA Container Runtime을 사용할 수 있도록 업데이트합니다.

 

containerd를 Kubernetes용으로 구성할 때는 다음과 같은 명령을 사용할 수 있습니다.

sudo nvidia-ctk runtime configure --runtime=containerd
sudo systemctl restart containerd

 

공식 문서에 따르면 containerd의 경우 nvidia-ctk가 기본적으로 /etc/containerd/conf.d/99-nvidia.toml drop-in 설정 파일을 만들고, /etc/containerd/config.toml의 imports 설정을 업데이트합니다.

 

즉, nvidia-ctk는 사람이 직접 설정 파일을 열어서 복잡하게 수정해야 하는 작업을 대신해주는 관리 도구라고 보면 됩니다.


11. Kubernetes에서는 어떻게 이해해야 할까?

Kubernetes에서 GPU를 사용하는 경우 일반적으로 노드 레벨에서 다음 구성이 필요합니다.

GPU가 장착된 노드
  ↓
NVIDIA GPU Driver 설치
  ↓
NVIDIA Container Toolkit 설치
  ↓
containerd 또는 Docker 런타임 구성
  ↓
NVIDIA Device Plugin 배포
  ↓
Pod에서 nvidia.com/gpu 리소스 요청

 

여기서 NVIDIA Container Toolkit은 “컨테이너 런타임이 실제로 GPU를 컨테이너에 연결할 수 있도록 하는 기반 계층”입니다.

 

Kubernetes 스케줄러 입장에서는 GPU 리소스가 있는 노드에 Pod를 배치해야 합니다. 하지만 Pod가 실제로 GPU 장치를 컨테이너 안에서 사용할 수 있으려면 컨테이너 런타임이 GPU 장치와 라이브러리를 주입할 수 있어야 합니다.

 

이때 NVIDIA Container Toolkit이 필요합니다.

 

예를 들어 Pod 스펙에서는 다음처럼 GPU 리소스를 요청할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: gpu-test
spec:
  restartPolicy: Never
  containers:
    - name: cuda
      image: nvidia/cuda:12.4.1-base-ubuntu22.04
      command: ["nvidia-smi"]
      resources:
        limits:
          nvidia.com/gpu: 1

 

이 YAML만 있다고 GPU가 자동으로 되는 것은 아닙니다.

 

노드에 NVIDIA 드라이버가 있어야 하고, 컨테이너 런타임이 NVIDIA Container Toolkit을 통해 GPU를 주입할 수 있어야 하며, Kubernetes가 GPU 리소스를 인식할 수 있도록 Device Plugin도 구성되어야 합니다.


12. CDI(Container Device Interface)는 왜 중요해졌을까?

최근에는 CDI(Container Device Interface)도 중요해지고 있습니다.

 

NVIDIA 문서에 따르면 NVIDIA Container Toolkit은 v1.12.0부터 CDI specification 생성을 지원합니다. CDI는 NVIDIA GPU 같은 장치에 접근한다는 것이 무엇을 의미하는지 추상화하고, 여러 컨테이너 런타임에서 장치 접근 방식을 표준화하기 위한 open specification입니다.

 

쉽게 말하면 CDI는 “컨테이너에서 GPU 같은 장치를 표현하는 표준 명세”입니다.

 

기존 방식에서는 특정 런타임 hook이나 환경 변수에 의존하는 부분이 컸습니다. CDI를 사용하면 GPU 장치를 더 표준화된 방식으로 컨테이너 런타임에 전달할 수 있습니다.

 

특히 Podman 같은 환경에서는 NVIDIA가 CDI 사용을 권장합니다. NVIDIA 설치 문서에서도 Podman의 경우 NVIDIA 장치 접근에 CDI 사용을 권장한다고 설명합니다.

 

예를 들어 Podman에서는 다음과 같이 CDI 장치를 지정할 수 있습니다.

podman run --rm \
  --device nvidia.com/gpu=all \
  --security-opt=label=disable \
  ubuntu nvidia-smi -L

 

NVIDIA 문서에서는 이 명령이 호스트에서 nvidia-smi -L을 실행했을 때와 동일한 GPU 목록을 보여줘야 한다고 설명합니다.

 

또한 NVIDIA Container Toolkit v1.18.0부터는 nvidia-cdi-refresh라는 systemd 서비스가 CDI specification을 자동으로 생성하고 갱신합니다. 이 서비스는 Toolkit 설치/업그레이드, GPU 드라이버 설치/업그레이드, 시스템 재부팅 시 /var/run/cdi/nvidia.yaml을 생성 또는 갱신합니다.


13. Docker에서 GPU 컨테이너 실행 흐름 예시

Docker 기준으로 사용자가 다음 명령을 실행한다고 가정해 보겠습니다.

docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi

 

이 명령이 실행될 때 내부적으로는 대략 이런 일이 일어납니다.

1. 사용자가 Docker CLI로 GPU 사용을 요청한다.
2. Docker daemon이 컨테이너 생성을 준비한다.
3. NVIDIA Container Runtime이 OCI runtime spec을 수정한다.
4. prestart hook에 NVIDIA Container Runtime Hook이 추가된다.
5. runC가 컨테이너 생성 후 시작 직전에 hook을 실행한다.
6. hook이 nvidia-container-cli를 호출한다.
7. nvidia-container-cli가 GPU 장치와 필요한 라이브러리를 컨테이너에 주입한다.
8. 컨테이너 내부에서 nvidia-smi가 GPU를 인식한다.

 

이 구조에서 중요한 점은 컨테이너 이미지 안에 GPU 드라이버 전체를 설치하는 방식이 아니라는 것입니다.

 

호스트에 설치된 NVIDIA 드라이버와 GPU 장치를 컨테이너가 사용할 수 있도록 연결해주는 방식입니다.

 

그래서 GPU 컨테이너 환경에서는 다음 순서가 중요합니다.

호스트 NVIDIA 드라이버 정상 동작 확인
  ↓
nvidia-smi 확인
  ↓
NVIDIA Container Toolkit 설치
  ↓
Docker/containerd 런타임 설정
  ↓
GPU 컨테이너 실행 테스트

14. 설치와 구성 흐름

NVIDIA Container Toolkit 설치 문서 기준으로 가장 먼저 필요한 것은 Linux 배포판에 맞는 NVIDIA GPU Driver 설치입니다. NVIDIA는 배포판의 패키지 매니저를 사용한 드라이버 설치를 권장한다고 설명합니다.

 

Ubuntu/Debian 계열에서는 NVIDIA 저장소를 등록한 뒤 Toolkit 패키지를 설치합니다. 공식 문서에는 apt 기반 설치 예시와 함께 nvidia-container-toolkit, nvidia-container-toolkit-base, libnvidia-container-tools, libnvidia-container1 패키지 설치 예시가 제공되어 있습니다.

 

설치 후 Docker를 구성하는 대표 흐름은 다음과 같습니다.

# Docker가 NVIDIA Container Runtime을 사용할 수 있도록 설정
sudo nvidia-ctk runtime configure --runtime=docker

# Docker 재시작
sudo systemctl restart docker

# GPU 컨테이너 테스트
docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi

 

Kubernetes에서 containerd를 사용하는 경우에는 다음 흐름을 생각하면 됩니다.

# containerd가 NVIDIA Container Runtime을 사용할 수 있도록 설정
sudo nvidia-ctk runtime configure --runtime=containerd

# containerd 재시작
sudo systemctl restart containerd

 

이후 Kubernetes에서는 NVIDIA Device Plugin을 배포하고, Pod에서 nvidia.com/gpu 리소스를 요청하는 방식으로 GPU 워크로드를 실행합니다.


15. 실무에서 자주 헷갈리는 부분

15.1 컨테이너 안에 NVIDIA 드라이버를 설치해야 하나?

일반적으로 컨테이너 이미지 안에 호스트용 NVIDIA 드라이버를 설치하는 방식으로 접근하지 않습니다.

 

GPU 드라이버는 호스트 커널과 맞물려 동작합니다. 컨테이너는 호스트의 GPU 장치와 드라이버 라이브러리를 사용할 수 있도록 구성됩니다.

 

컨테이너 이미지는 CUDA runtime, cuDNN, 애플리케이션 코드 등을 포함할 수 있지만, 실제 GPU 장치와 커널 드라이버는 호스트 쪽이 중요합니다.

 

15.2 nvidia-smi가 호스트에서는 되는데 컨테이너에서는 안 된다면?

이 경우 다음을 확인해야 합니다.

# 호스트에서 GPU 인식 확인
nvidia-smi

# NVIDIA Container Toolkit 설치 여부 확인
dpkg -l | grep nvidia-container
# 또는
rpm -qa | grep nvidia-container

# Docker runtime 설정 확인
cat /etc/docker/daemon.json

# containerd 설정 확인
cat /etc/containerd/config.toml
ls -al /etc/containerd/conf.d/

 

Docker 환경이라면 다음 명령으로 런타임 구성을 다시 적용해볼 수 있습니다.

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

 

containerd 환경이라면 다음 명령을 사용할 수 있습니다.

sudo nvidia-ctk runtime configure --runtime=containerd
sudo systemctl restart containerd

15.3 nvidia-docker2를 설치해야 하나?

새로운 환경이라면 일반적으로 nvidia-docker2보다는 nvidia-container-toolkit 기준으로 접근하는 것이 좋습니다.

 

공식 문서에서 nvidia-docker2와 nvidia-container-runtime 패키지는 deprecated로 설명되며, 해당 기능은 nvidia-container-toolkit으로 병합되었습니다.

15.4 AWS GPU 인스턴스 이미지에 nvidia-ctk가 왜 설치되어 있을까?

AWS의 GPU 기반 이미지나 AI/ML용 이미지에는 NVIDIA 드라이버, CUDA, 컨테이너 실행 환경이 미리 구성되어 있는 경우가 많습니다.

 

이런 이미지에 nvidia-ctk가 설치되어 있다면, 컨테이너에서 GPU를 사용하도록 Docker나 containerd를 쉽게 구성하기 위한 목적이라고 보면 됩니다.

 

특히 Ollama, vLLM, PyTorch, TensorFlow 같은 워크로드를 컨테이너로 실행하려면 GPU 장치가 컨테이너에 정상적으로 전달되어야 합니다. 이때 NVIDIA Container Toolkit과 nvidia-ctk가 중요한 역할을 합니다.


16. 한 장으로 정리하는 아키텍처

전체 구조를 한 번에 정리하면 다음과 같습니다.

[사용자 명령]
docker run --gpus all ...
        │
        ▼
[Docker / containerd]
컨테이너 생성 요청 처리
        │
        ▼
[nvidia-container-runtime]
OCI runtime spec 수정
NVIDIA prestart hook 추가
        │
        ▼
[runC]
컨테이너 생성
prestart hook 실행
        │
        ▼
[nvidia-container-runtime-hook]
config.json 분석
nvidia-container-cli 호출
        │
        ▼
[nvidia-container-cli / libnvidia-container]
GPU 장치 파일 주입
드라이버 라이브러리 마운트
환경 구성
        │
        ▼
[컨테이너]
nvidia-smi
CUDA 애플리케이션
AI 모델 추론/학습

 

이 흐름을 이해하면 GPU 컨테이너 문제를 훨씬 쉽게 디버깅할 수 있습니다.

예를 들어 문제가 생겼을 때 다음처럼 계층을 나눠서 볼 수 있습니다.

1. 호스트 GPU 문제인가?
   - nvidia-smi가 호스트에서 동작하는가?

2. Toolkit 설치 문제인가?
   - nvidia-container-toolkit 패키지가 설치되어 있는가?

3. 런타임 설정 문제인가?
   - Docker/containerd가 NVIDIA runtime을 사용하도록 구성되어 있는가?

4. 컨테이너 실행 옵션 문제인가?
   - docker run --gpus all 옵션을 사용했는가?
   - Kubernetes Pod에서 nvidia.com/gpu 리소스를 요청했는가?

5. 애플리케이션 문제인가?
   - CUDA 버전, 프레임워크 버전, 드라이버 호환성이 맞는가?

17. 결론

NVIDIA Container Toolkit은 단순히 “GPU 컨테이너 실행 도구”가 아닙니다.

 

더 정확히 말하면 컨테이너 런타임과 NVIDIA GPU 사이를 연결해주는 표준화된 구성 계층입니다.

 

Docker나 containerd에서는 NVIDIA Container Runtime이 OCI runtime 흐름에 들어가고, runC prestart hook을 통해 nvidia-container-cli가 호출됩니다. CRI-O나 LXC에서는 흐름이 다를 수 있으며, 최근에는 CDI를 통한 장치 표준화도 중요해지고 있습니다.


실무적으로 기억해야 할 핵심은 다음 세 가지입니다.

  • 첫째, GPU 드라이버는 호스트에 설치되어야 합니다.
  • 둘째, 컨테이너 런타임은 NVIDIA Container Toolkit을 통해 GPU 장치와 라이브러리를 컨테이너에 주입해야 합니다.
  • 셋째, 새 환경에서는 nvidia-docker2보다 nvidia-container-toolkit과 nvidia-ctk 중심으로 이해하는 것이 좋습니다.

 

AI 인프라, GPU 서버, Kubernetes GPU 노드, Ollama/vLLM 같은 LLM 추론 환경을 구성한다면 NVIDIA Container Toolkit 아키텍처는 반드시 이해해야 하는 기반 지식입니다.

 

이 구조를 알고 나면 “왜 호스트에서는 GPU가 보이는데 컨테이너에서는 안 보이는지”, “왜 Docker daemon.json을 수정해야 하는지”, “왜 containerd 재시작이 필요한지”, “왜 Kubernetes GPU Pod가 Pending 또는 실행 실패 상태가 되는지”를 훨씬 체계적으로 분석할 수 있습니다.

 

참고자료: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/arch-overview.html

 

반응형