---
title: "GPU 환경 구축을 위한 Docker와 NVIDIA Container Toolkit 완벽 가이드: 효율적인 리소스 관리와 딥러닝 최적화"
description: "Docker는 경량 컨테이너 기술로, NVIDIA Container Toolkit을 통해 GPU 자원을 관리할 수 있다. GPU 가상화 방식에는 VM 환경에서의 Passthrough와 vGPU가 있으며, Docker 환경에서는 CUDA 드라이버를 매핑하여 GPU에 접근한다. 운영 환경에서는 CPU, 메모리, GPU, 디스크 제한을 설정하여 시스템 안정성을 보장해야 한다."
date: "2024-10-15"
last_modified: "2026-05-15T08:36:00.000Z"
type: "Post"
tags:
  - "docker"
  - "gpu"
  - "install"
categories:
  - "🤖 Computer Science"
canonical_url: "https://blog.pieroot.xyz/docker-nvidia-gpu"
markdown_url: "https://blog.pieroot.xyz/docker-nvidia-gpu.md"
---

# GPU 환경 구축을 위한 Docker와 NVIDIA Container Toolkit 완벽 가이드: 효율적인 리소스 관리와 딥러닝 최적화

Docker는 경량 컨테이너 기술로, NVIDIA Container Toolkit을 통해 GPU 자원을 관리할 수 있다. GPU 가상화 방식에는 VM 환경에서의 Passthrough와 vGPU가 있으며, Docker 환경에서는 CUDA 드라이버를 매핑하여 GPU에 접근한다. 운영 환경에서는 CPU, 메모리, GPU, 디스크 제한을 설정하여 시스템 안정성을 보장해야 한다.

## Docker란?

---

Docker는 **Linux 컨테이너**를 만들고 사용할 수 있도록 하는 컨테이너화 기술입니다.

가상화 기술과 비교하면 이해하기 쉬운데, 간단히 정리해볼게요.

![image](https://blog.pieroot.xyz/api/image-proxy?id=6ab57fe7-c255-4976-bcae-75b726672b28&kind=s3&pageId=21e067c0-15d0-804b-838c-ee19f6df17a2&source=block&blockId=21f067c0-15d0-80a4-8245-e472ce40e72b)

### 가상화 vs 컨테이너

#### 1. 가상화 (Virtualization)

하이퍼바이저(Hypervisor)를 사용하여 Host OS 위에 Guest OS를 올려 각 시스템을 완전히 격리하는 방식입니다.

- **장점**: 하드웨어 수준의 완벽한 분리로 보안성이 높습니다. 기존 인프라를 그대로 가상화하여 옮기기 좋습니다.

- **단점**: 각 VM마다 OS가 포함되므로 무겁고(Resource Overhead), 부팅 시간이 깁니다.

#### 2. 컨테이너 (Container)

Host OS의 커널(Kernel)을 공유하면서, 애플리케이션과 필요한 라이브러리/종속성만 격리하여 실행하는 방식입니다.

- **장점**: 가볍고 빠릅니다. CI/CD 파이프라인에서 신속한 배포가 가능합니다.

- **단점**: 커널을 공유하므로 커널 취약점에 노출될 수 있고, Host OS와 다른 종류의 OS(예: Linux 위에 Windows)를 실행하는 데 제약이 있습니다.

> **핵심 정리**
> 
> - **가상화(VM)**: 완벽한 격리 (보안 중시), 무겁고 느림
> 
> - **컨테이너(Docker)**: 가벼운 격리 (효율성 중시), 빠르고 가벼움
> 
> - 둘 다 Host OS의 CPU, RAM, Disk를 공유하지만, 격리 수준이 다릅니다.

### GPU 가상화

---

GPU를 활용한 딥러닝/ML 환경을 구축할 때, **GPU 자원을 어떻게 할당하느냐**가 핵심입니다.

#### 1. 가상화(VM) 환경에서의 GPU

VMware, VirtualBox, Xen 같은 가상화 환경에서는 NVIDIA GRID vGPU 패키지를 사용하여 GPU 자원을 관리할 수 있습니다.

[https://us.download.nvidia.com/Windows/Quadro\_Certified/GRID/370.28/ESXi-6.5/367.128-370.28-grid-vgpu-user-guide.pdf](https://us.download.nvidia.com/Windows/Quadro_Certified/GRID/370.28/ESXi-6.5/367.128-370.28-grid-vgpu-user-guide.pdf)

[Using GPUs with Virtual Machines on vSphere – Part 3: Installing the NVIDIA Virtual GPU Technology](https://blogs.vmware.com/apps/2018/09/using-gpus-with-virtual-machines-on-vsphere-part-3-installing-the-nvidia-grid-technology.html)

This is part 3 of a series of blog articles on the subject of using GPUs with VMware vSphere. Part 1 of this series presents an overview of the various options for using GPUs on vSphere Part 2 describes the DirectPath I/O (Passthrough) mechanism for GPUs Part 3 gives details on setting up the NVIDIA &hellip; Continued

적용 방식은 두 가지로 나뉘니다:

- **Passthrough**: 하나의 VM이 하나의 GPU를 직접 할당받는 방식 (1:1 매핑)

- **vGPU**: 하나의 물리 GPU를 여러 VM에 나눠 할당하는 방식 (1:N 매핑)

> **GPU 지원 제한**
> 
> - **서버급 GPU (Tesla, A100 등)**: NVIDIA GRID vGPU 설치 시 VM에서 접근 가능
> 
> - **소비자급 GPU (GeForce)**: VM에서 공식 지원 안 됨

![image](https://blog.pieroot.xyz/api/image-proxy?id=733b3944-0fb8-4637-a226-ae1e83f3b438&kind=s3&pageId=21e067c0-15d0-804b-838c-ee19f6df17a2&source=block&blockId=21e067c0-15d0-8045-9078-d18e54e57ef1)

![vGPU 사용 시 동일한 arch 로만 나눌 수 있음](https://blog.pieroot.xyz/api/image-proxy?id=4d32c901-5486-44cc-8342-538c1f65d8a9&kind=s3&pageId=21e067c0-15d0-804b-838c-ee19f6df17a2&source=block&blockId=21e067c0-15d0-8037-891e-c75d38e83416)

#### 2. 컨테이너(Docker) 환경에서의 GPU

Docker는 **NVIDIA Container Toolkit**을 사용하여 GPU 자원에 접근할 수 있습니다.

[GitHub - NVIDIA/nvidia-container-toolkit: Build and run containers leveraging NVIDIA GPUs](https://github.com/NVIDIA/nvidia-container-toolkit)

Build and run containers leveraging NVIDIA GPUs. Contribute to NVIDIA/nvidia-container-toolkit development by creating an account on GitHub.

![image](https://blog.pieroot.xyz/api/image-proxy?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fcloud.githubusercontent.com%252Fassets%252F3028125%252F12213714%252F5b208976-b632-11e5-8406-38d379ec46aa.png%3Ftable%3Dblock%26id%3D21e067c0-15d0-807f-9c0f-cfd54d284111%26cache%3Dv2&pageId=21e067c0-15d0-804b-838c-ee19f6df17a2&source=block&blockId=21e067c0-15d0-807f-9c0f-cfd54d284111)

Host OS의 CUDA Driver를 컨테이너 내부의 CUDA Toolkit과 매핑하여, 애플리케이션이 GPU에 접근할 수 있게 합니다.

### NVIDIA Container Toolkit 설치

---

이제 Docker에서 GPU를 사용하기 위해 **NVIDIA Container Toolkit**을 설치해보겠습니다.

아래 과정은 **Ubuntu 22.04 LTS** 환경을 기준으로 작성되었습니다.

```yaml
ubuntu 22.04
RTX 3060 vram 12GB
nvidia driver 550.54.15-server
cuda 12.4
```
*환경*

![image](https://blog.pieroot.xyz/api/image-proxy?id=a456d2d0-8c30-45f9-9568-a296acc353ed&kind=s3&pageId=21e067c0-15d0-804b-838c-ee19f6df17a2&source=block&blockId=21e067c0-15d0-8021-ab90-c211e8f39bb1)

#### 1. 사전 준비 (Prerequisites)

Docker가 설치된 서버에 NVIDIA Driver가 먼저 설치되어 있어야 합니다.

```shell
$ nvidia-smi
```

![image](https://blog.pieroot.xyz/api/image-proxy?id=2e500b37-f632-4901-a607-9145b6d1d55d&kind=s3&pageId=21e067c0-15d0-804b-838c-ee19f6df17a2&source=block&blockId=21e067c0-15d0-800a-86f7-dbe2fea308e3)

CUDA 10.0 이후 버전부터는 **NVIDIA Container Toolkit**을 사용하며, 그 이전 버전은 nvidia-docker2를 사용해야 합니다.

[Installing the NVIDIA Container Toolkit &#8212; NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)

#### 2. 저장소 추가

Ubuntu 기준 GPG Key와 APT 저장소 리스트를 추가합니다.

```shell
$ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
    
    
$ sed -i -e '/experimental/ s/^#//g' /etc/apt/sources.list.d/nvidia-container-toolkit.list
```

#### 3. 패키지 설치

저장소 갱신 후 패키지를 설치합니다.

```shell
$ sudo apt update && sudo apt install -y nvidia-container-toolkit
```

#### 4. Docker 재시작

패키지 설치 후 Docker Engine을 재시작해야 합니다.

```shell
$ systemctl restart docker.service
```

#### 5. 설치 확인

Docker 컨테이너에서 드라이버가 정상적으로 연결되는지 확인합니다.

```shell
$ docker run -it --rm --gpus all ubuntu:22.04 nvidia-smi
```

`nvidia-smi` 출력이 정상적으로 나오면 연결이 성공한 것입니다.

### Docker 리소스 제한 (Resource Limits)

---

Docker는 VM과 달리 커널을 공유하므로, 하나의 컨테이너가 시스템 자원(CPU, Memory)을 과도하게 점유하면 호스트 전체가 불안정해질 수 있습니다.

따라서 **운영 환경(Production)**에서는 반드시 리소스 제한을 설정해야 합니다.

> **왜 제한해야 할까요?**
> 
> - 특정 컨테이너의 메모리 누수(Memory Leak)가 호스트 OOM(Out Of Memory)을 유발하는 것을 방지
> 
> - CPU 점유율 독점을 막아 다른 서비스의 성능 보장

아래는 자주 사용되는 주요 옵션들입니다.

#### 1. CPU 제한

---

가장 직관적인 방법은 `--cpus` 옵션을 사용하는 것입니다.

```shell
# 1.5개의 CPU 코어만 사용 가능 (예: 코어 1개 100% + 코어 1개 50%)
docker run --cpus="1.5" ubuntu

# 특정 코어(0번, 1번)만 사용하도록 지정
docker run --cpuset-cpus="0,1" ubuntu
```

- `--cpus`: 사용할 CPU 코어의 **개수**를 제한합니다. (가장 권장되는 방식)

- `--cpuset-cpus`: 특정 **CPU 코어 번호**를 지정합니다. (고성능 컴퓨팅 등 격리가 중요할 때 사용)

#### 2. Memory 제한

---

메모리 제한은 OOM Killer에 의해 프로세스가 종료되는 것을 방지하기 위해 중요합니다.

```shell
# 메모리 512MB 제한 (스왑은 기본값 사용)
docker run --memory="512m" ubuntu

# 메모리 512MB, 스왑 1GB (메모리+스왑 총합) 제한
# 즉, 실제 RAM 512MB + SWAP 512MB 사용 가능
docker run --memory="512m" --memory-swap="1g" ubuntu

# 스왑 끄기 (메모리와 스왑을 동일하게 설정)
docker run --memory="512m" --memory-swap="512m" ubuntu
```

> **주의**: `--memory-swap`은 `--memory` 값과 Swap 영역을 **합친 총량**입니다.

> 예를 들어 `--memory="300m" --memory-swap="1g"`라면, RAM 300MB + Swap 700MB를 사용하게 됩니다.

#### 3. GPU 할당

---

`--gpus` 플래그를 사용하여 컨테이너에 할당할 GPU를 지정할 수 있습니다.

```shell
# 모든 GPU 할당
docker run --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi

# 특정 GPU 2개 할당
docker run --gpus 2 nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi

# 특정 GPU 지정 (Device ID 또는 UUID)
docker run --gpus '"device=0,2"' ...
docker run --gpus device=GPU-3a23c669-... ...
```

**UUID 확인 방법:**

```shell
nvidia-smi -L
```

container 내부에 드라이버 연결이 되었는지 테스트하는 방법

```shell
docker run -it --rm --gpus all ubuntu nvidia-smi
```

```shell
+-------------------------------------------------------------------------------+
| NVIDIA-SMI 384.130            	Driver Version: 384.130                      	|
|-------------------------------+----------------------+------------------------+
| GPU  Name 	     Persistence-M| Bus-Id      	Disp.A | Volatile Uncorr. ECC   |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M.   |
|===============================+======================+========================|
|   0  GRID K520       	Off  |   00000000:00:03.0 Off  |                    N/A |
| N/A   36C	P0    39W / 125W |      	0MiB /  4036MiB  |          0%  	Default |
+-------------------------------+----------------------+------------------------+
+-------------------------------------------------------------------------------+
| Processes:                                                         GPU Memory |
|  GPU   	PID   Type   Process name                                  Usage  	  |
|===============================================================================|
|  No running processes found                                                   |
+-------------------------------------------------------------------------------+
```

#### 4. Disk (Volume) 제한

---

Docker의 기본 Storage Driver는 오버레이 파일시스템을 사용하므로, 컨테이너 생성 시 디스크 용량을 직접 제한하는 옵션은 `--storage-opt`를 사용합니다.

하지만, 일반적으로는 **Volume** 생성 시 크기를 제한하는 방법이 더 자주 쓰입니다.

```shell
# 1GB 크기의 볼륨 생성
docker volume create --driver local \
    --opt type=tmpfs \
    --opt device=tmpfs \
    --opt o=size=1024m \
    my_vol
```

> **참고**: XFS 파일시스템을 사용하는 경우, `--storage-opt size=10G` 와 같은 옵션으로 컨테이너 루트 파일시스템 크기를 제한할 수 있습니다.

### 마무리

---

이 글에서는 Docker와 가상화의 차이점부터, NVIDIA Container Toolkit을 통한 GPU 활용, 그리고 운영 환경에서 필수적인 리소스 제한 방법까지 살펴보았습니다.

> **핵심 요약**
> 
> - **Docker**: 커널을 공유하는 경량 컨테이너 기술로, VM보다 빠르고 효율적입니다.
> 
> - **NVIDIA Container Toolkit**: Docker에서 GPU를 사용하기 위한 필수 도구입니다.
> 
> - **리소스 제한**: `--cpus`, `--memory`, `--gpus` 등의 옵션으로 컨테이너별 자원을 제한할 수 있습니다.

GPU를 활용한 딥러닝/ML 환경을 구축할 때, 적절한 리소스 제한은 시스템 안정성과 여러 서비스 간의 공정한 자원 분배를 보장합니다. 이 글이 Docker GPU 환경 구축에 도움이 되었으면 좋겠습니다. 🐳
