【Docker/環境】NVIDIA Container ToolkitインストールとGPUパススルー設定の完全ガイドとトラブルシューティング

問題の概要:Dockerコンテナ内でGPUが認識されない

AI開発や機械学習の環境構築において、Dockerコンテナ内でGPUを利用しようとすると、以下のような問題に直面することがあります。

  • PyTorchやTensorFlowをコンテナ内で実行しても、GPUが認識されずCPUで動作してしまう
  • nvidia-smiコマンドをコンテナ内で実行すると「コマンドが見つかりません」と表示される
  • Docker run時に--gpus allオプションを指定してもエラーが発生する

具体的なエラーメッセージ例:

docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
RuntimeError: No CUDA GPUs are available

これらの問題は、ホストマシンにNVIDIA GPUドライバがインストールされていても、DockerコンテナとGPUを連携させるための「NVIDIA Container Toolkit」が正しく設定されていない場合に発生します。

原因の解説:DockerとGPUの連携メカニズム

従来のDockerは、コンテナ内からホストのハードウェアを直接利用する仕組みを持っていません。GPUのような特殊なデバイスをコンテナ内で使用するためには、以下のコンポーネントが必要です。

1. NVIDIA Container Toolkitの役割

NVIDIA Container Toolkitは、Dockerや他のコンテナランタイムがNVIDIA GPUにアクセスできるようにするためのソフトウェアスイートです。これにより、コンテナ内からホストのGPUドライバやCUDAライブラリを安全に利用できるようになります。

2. 必要なコンポーネント

  • NVIDIA GPUドライバ: ホストOSにインストール済みであることが前提
  • NVIDIA Container Toolkit: DockerとGPUを仲介するソフトウェア層
  • nvidia-container-runtime: Dockerのランタイムとして機能

3. よくある設定ミス

  • NVIDIA Container Toolkitのインストールが不完全
  • Dockerデーモンの設定ファイル(daemon.json)の記述ミス
  • ユーザーがdockerグループに属していない
  • ホストのNVIDIAドライバとコンテナ内のCUDAバージョンの不一致

解決方法:ステップバイステップ設定ガイド

ステップ1: 前提条件の確認

まず、ホストマシンにNVIDIA GPUドライバが正しくインストールされていることを確認します。

# GPUとドライバの状態を確認
nvidia-smi

# 期待される出力例
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.105.17   Driver Version: 525.105.17   CUDA Version: 12.0    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  Off  | 00000000:01:00.0 Off |                  N/A |
| 30%   34C    P8    10W / 250W |      0MiB / 12288MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

ステップ2: NVIDIA Container Toolkitのインストール

Ubuntu/Debian系ディストリビューションの場合のインストール手順です。

# リポジトリのGPGキーと設定を追加
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
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/$distribution/libnvidia-container.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

# パッケージリストの更新とインストール
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

ステップ3: Dockerデーモンの設定

DockerがNVIDIA Container Runtimeを使用するように設定します。

# nvidia-container-runtimeをDockerのランタイムとして設定
sudo nvidia-ctk runtime configure --runtime=docker

# 設定の適用
sudo systemctl restart docker

# 設定が正しく反映されたか確認
sudo cat /etc/docker/daemon.json

正しく設定されていれば、daemon.jsonに以下のような記述が追加されています。

{
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

ステップ4: 動作確認

簡単なテストコンテナを実行して、GPUが認識されることを確認します。

# テストコンテナの実行
sudo docker run --rm --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi

# コンテナ内でPythonからGPUを確認
sudo docker run --rm --gpus all -it nvidia/cuda:12.0.1-base-ubuntu22.04 python3 -c "import torch; print(torch.cuda.is_available())"

コード例・コマンド例

1. 基本的なGPU付きコンテナの実行

# すべてのGPUを利用
docker run --gpus all -it pytorch/pytorch:latest

# 特定のGPUのみを利用(GPU ID 0のみ)
docker run --gpus '"device=0"' -it tensorflow/tensorflow:latest-gpu

# 複数の特定GPUを利用(GPU ID 0と1)
docker run --gpus '"device=0,1"' -it nvcr.io/nvidia/pytorch:23.05-py3

2. Docker ComposeでのGPU設定例

version: '3.8'
services:
  ai-training:
    image: pytorch/pytorch:latest
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    volumes:
      - ./data:/data
      - ./models:/models
    command: python train.py

3. トラブルシューティング用コマンド

# Dockerデーモンのログを確認
sudo journalctl -u docker.service -f

# NVIDIA Container Toolkitのバージョン確認
nvidia-ctk --version

# 利用可能なランタイムの確認
docker info | grep -i runtime

# コンテナ内のGPU情報を詳細に確認
docker run --rm --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv

よくあるエラーと解決策

エラー1: “could not select device driver”

原因: NVIDIA Container Toolkitが正しくインストールされていないか、Dockerデーモンの再起動が行われていない。

解決策:

# インストールの再確認とDockerの再起動
sudo apt-get install --reinstall nvidia-container-toolkit
sudo systemctl restart docker

エラー2: “Unknown runtime specified nvidia”

原因: daemon.jsonにnvidiaランタイムが正しく設定されていない。

解決策:

# daemon.jsonの手動修正
sudo tee /etc/docker/daemon.json <<EOF
{
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    },
    "default-runtime": "nvidia"
}
EOF
sudo systemctl restart docker

エラー3: コンテナ内でCUDAバージョンエラー

原因: ホストのCUDAドライババージョンとコンテナイメージのCUDAバージョンが互換性がない。

解決策: コンテナイメージのCUDAバージョンをホストのドライババージョンに対応するものに変更。

# ホストのCUDAドライババージョンを確認
nvidia-smi | grep "CUDA Version"

# 互換性のあるCUDAバージョンのコンテナイメージを使用
# 例: CUDA 11.8に対応するイメージ
docker run --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04

まとめ・補足情報

NVIDIA Container Toolkitを正しく設定することで、Dockerコンテナ内でGPUをシームレスに利用できるようになります。この設定は、AI開発環境の再現性確保、異なるCUDAバージョンの並行利用、チーム間での環境統一に非常に有効です。

パフォーマンス最適化のヒント

  • 永続モードの有効化: sudo nvidia-smi -pm 1でGPUの永続モードを有効にすると、起動時間が短縮されます。
  • メモリ制限: --gpus all --memory="8g"のようにメモリ制限を設定することで、ホストシステムの安定性を保ちます。
  • ボリュームマウントの最適化: 学習データセットなど大きなファイルはボリュームマウントで共有し、コンテナイメージのサイズを小さく保ちます。

セキュリティに関する注意点

GPUパススルーを有効にすると、コンテナ内からホストのGPUリソースに直接アクセス可能になります。本番環境では以下の点に注意してください。

  • 信頼できるコンテナイメージのみを使用する
  • 必要最小限のGPU権限のみを付与する(--gpus '"device=0"'のように特定GPUのみ)
  • 定期的にセキュリティアップデートを適用する

本ガイドで紹介した手順に従うことで、ほとんどの環境でDockerコンテナ内でのGPU利用が可能になります。問題が解決しない場合は、NVIDIAの公式ドキュメントやDockerのコミュニティフォーラムも参照してください。

この記事は役に立ちましたか?