【Docker/環境】NVIDIA Container ToolkitインストールとGPUパススルー設定エラー完全解決ガイド

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

AI開発、特に深層学習のモデルトレーニングや推論をDocker環境で行う際、コンテナ内からホストマシンのNVIDIA GPUを利用できるようにする設定は必須です。しかし、NVIDIA Container Toolkit(旧称:nvidia-docker2)のインストールや設定を誤ると、以下のようなエラーに遭遇することが頻繁にあります。

代表的なエラーメッセージ

# Dockerコンテナ内で `nvidia-smi` を実行した場合
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
# または、PyTorch/TensorFlowを使用時
RuntimeError: No CUDA GPUs are available
# `nvidia-smi` コマンド自体が見つからない
bash: nvidia-smi: command not found

これらのエラーは、DockerデーモンがNVIDIA GPUを認識するためのランタイム設定が正しく行われていない、あるいはドライバやツールキットのインストールに問題があることを示しています。

原因の解説

従来のDockerは、CPUやメモリ、ストレージなどのリソースを仮想化しますが、GPUのような特殊なハードウェアデバイスをそのままコンテナに「パススルー」する機能は標準では備えていません。NVIDIA Container Toolkitは、このギャップを埋めるためのソフトウェアスタックです。主な原因は以下の3つに分類されます。

1. 必須コンポーネントの欠落

NVIDIA Container Toolkitが正常に機能するためには、以下の全てのレイヤーが正しくインストール・設定されている必要があります。

  • ホスト側NVIDIAドライバ: 物理GPUをOSが認識するための基盤。
  • NVIDIA Container Toolkit: DockerとGPUを仲介するミドルウェア。
  • Dockerデーモンの設定: `nvidia` をデフォルトまたは使用可能なランタイムとして登録。

このいずれかが欠けている、またはバージョンが互換性がない場合にエラーが発生します。

2. Dockerデーモンの設定不備

NVIDIA Container Toolkitをインストールしても、Dockerの設定ファイル(`/etc/docker/daemon.json`)に `nvidia` ランタイムが追加されていないと、DockerはGPUを使用する方法を知りません。

3. 権限の問題

Dockerデーモンやコンテナを実行するユーザーに適切な権限がない場合、デバイスへのアクセスが拒否されることがあります。

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

以下に、Ubuntu 20.04/22.04を例に、確実に設定を行う手順を説明します。他のディストリビューションでも概念は同じです。

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

まず、ホストマシンにNVIDIA GPUドライバが正しくインストールされ、`nvidia-smi` コマンドが動作することを確認します。

# NVIDIAドライバとCUDAドライバの確認
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. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0 Off |                  N/A |
| N/A   45C    P8    N/A /  N/A |      0MiB /  6144MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

`nvidia-smi` がコマンドが見つからない、またはエラーを出す場合は、先にNVIDIA公式サイトからドライバをインストールしてください。

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

パッケージリポジトリを設定し、ツールキットをインストールします。

# パッケージリポジトリと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ランタイムを使用するように設定します。

# nvidia-ctkコマンドでDocker設定を自動更新(推奨)
sudo nvidia-ctk runtime configure --runtime=docker

# または、手動で `/etc/docker/daemon.json` を編集
# 以下の内容が追加されていることを確認します。
sudo cat /etc/docker/daemon.json
# 期待する出力例:
{
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

重要: 既存の `daemon.json` ファイルがある場合、`nvidia-ctk` コマンドは既存の設定とマージしようとしますが、手動で編集する場合はバックアップを取り、JSONの構文エラー(カンマの抜けなど)に注意してください。

ステップ4: Dockerデーモンの再起動と設定確認

# Dockerデーモンの再起動
sudo systemctl restart docker

# 設定の確認(nvidiaランタイムが登録されているか)
docker info | grep -i runtime
# 出力例:
 Runtimes: nvidia runc io.containerd.runc.v2
 Default Runtime: runc

ステップ5: 動作テスト

公式のCUDAコンテナイメージを使用して、GPUがコンテナ内から見えるかテストします。

# 最もシンプルなテスト
sudo docker run --rm --runtime=nvidia --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi

# より実践的なテスト (すべてのGPUを利用)
sudo docker run --rm --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi

# 特定のGPUのみを指定(複数GPU環境の場合)
sudo docker run --rm --gpus '"device=0,1"' nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi

ここでホストと同じ `nvidia-smi` の出力が得られれば、設定は成功です。

トラブルシューティングとコード例

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

原因: Dockerランタイム設定が不完全。

解決策:

# 1. nvidia-container-runtime のパスを確認
ls -la /usr/bin/nvidia-container-runtime

# 2. daemon.json のパス設定が正しいか確認
# パスが異なる場合(例: /usr/bin/nvidia-container-runtime.bin)、daemon.jsonを修正
sudo vi /etc/docker/daemon.json
# "path": "/usr/bin/nvidia-container-runtime.bin" に変更

# 3. Docker再起動
sudo systemctl restart docker

エラー2: “docker: Error response from daemon: unknown or invalid runtime name: nvidia”

原因: `daemon.json` の変更が適用されていない。

解決策:

# Dockerデーモンの再読み込みと再起動
sudo systemctl daemon-reload
sudo systemctl restart docker

# もしくは、Dockerソケットを直接リスタート
sudo systemctl restart docker.socket
sudo systemctl restart docker

エラー3: コンテナ内でCUDAが利用できない(PyTorch/TensorFlow)

原因: ベースイメージにCUDAライブラリが含まれていない、またはバージョン不一致。

解決策: 適切なCUDAバージョンが含まれる公式イメージを使用します。

# Dockerfileの例 (PyTorch)
FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime

# ビルドと実行
# docker build -t my-gpu-app .
# docker run --rm --gpus all my-gpu-app python -c "import torch; print(torch.cuda.is_available())"

まとめ・補足情報

NVIDIA Container Toolkitの設定は、AI開発環境をDockerで構築する上での基盤技術です。本ガイドで紹介した手順に従うことで、ほとんどの「GPUがコンテナ内で認識されない」問題は解決できるはずです。設定後は、`–gpus all` オプションを付けるだけで、コンテナ内のアプリケーションがホストのGPUリソースをフルに活用できるようになります。

最後の確認ポイント:

  • ホストドライバ: `nvidia-smi` がホストで動作するか。
  • ツールキットインストール: `apt list –installed | grep nvidia-container-toolkit`。
  • Docker設定: `/etc/docker/daemon.json` に `nvidia` ランタイムが定義されているか。
  • ランタイム登録: `docker info` で `Runtimes` に `nvidia` が含まれるか。

Docker Composeを使用する場合は、`docker-compose.yml` のサービス定義に `deploy.resources.reservations.devices` セクションを追加するか、`runtime: nvidia` を指定する必要があります。Kubernetesを利用する場合は、さらにNVIDIA Device Pluginのデプロイが必要となるので、別途公式ドキュメントを参照してください。

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