午前2時15分の呼び出し:なぜコンテナは「盲目」なのか
ある火曜日の午前2時15分、Slackが鳴り響きました。私たちはUbuntuのステージングクラスターに新しいコンピュータビジョンモデルをデプロイしていました。CI/CDは正常、Dockerイメージもビルドされ、Kubernetesも正常なデプロイを報告していました。しかし、ログは全く別の話を伝えていました:RuntimeError: システムにNVIDIAドライバが見つかりません。
ホストマシン上では、nvidia-smiにより8台のA100 GPUがバージョン535ドライバで完璧に動作していることが確認できました。しかし、コンテナ内はどうでしょう? 完全に「真っ暗」でした。アプリケーションは重いテンソル演算をCPUで処理しようとし、毎秒3イテレーションという遅さで動作した後、最終的にタイムアウトしました。この瞬間、ホスト側のドライバだけでは不十分であることに気づきます。架け橋が必要なのです。それが、NVIDIA Container Toolkitです。
現場において、これは不可欠なスキルです。AIやディープラーニングを構築しているなら、隔離されたコンテナにハードウェアアクセラレーションを公開する方法を知っているかどうかが、正常に動作する製品と、3万ドルのただのシリコンの塊を分ける境界線となります。
アーキテクチャ:なぜDockerはGPUを認識できないのか
設計上、Dockerコンテナはハードウェアに依存しません。ホストのカーネルを共有しますが、特定のハードウェアドライバからは隔離されたバブルの中で生きています。標準的なLinuxのデバイスマッピングを使用してGPUを渡そうとすると、ライブラリの不整合に遭遇する可能性が高くなります。これらのエラーを大規模な環境でデバッグするのは悪夢です。
NVIDIA Container Toolkit(以前のnvidia-docker2)は、カスタムランタイムとして機能することでこの問題を解決します。--gpusフラグを使用してコンテナを起動すると、ツールキットは以下の3つの重要なタスクを処理します:
- 必要なNVIDIAユーザーレベルライブラリをコンテナ環境にマウントします。
- コンテナが物理デバイスノード(
/dev/nvidia0など)にアクセスできるようにマッピングします。 - ホストのカーネルドライバとコンテナのCUDAバージョンの互換性を検証します。
これがなければ、窓のない閉め切られた部屋から車を運転しようとしているようなものです。このツールキットは、ステアリングカラムと道路の視界を提供します。
ステップ・バイ・ステップ:Ubuntuへのツールキットのインストール
前提条件はシンプルです。UbuntuホストにNVIDIAドライバとDockerが既にインストールされている必要があります。ホスト上でnvidia-smiが失敗する場合は、ここで一旦止まり、先にドライバを修正してください。土台がしっかりしたら、以下の手順に従って橋を架けましょう。
1. パッケージリポジトリの設定
NVIDIAは独自のリポジトリをホストしています。GPGキーとリストをaptに追加して、バイナリの場所を認識させる必要があります。
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
2. ツールキットのインストール
ローカルインデックスを更新し、パッケージをインストールします。これは軽量なインストール(約15MB)であり、既存のDocker設定を上書きすることはありません。単に必要なプラグインを追加するだけです。
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
3. Dockerランタイムの設定
バイナリはディスク上にありますが、Dockerはまだそれを使用していません。nvidia-ctkコマンドを使用して/etc/docker/daemon.jsonを自動的にパッチし、nvidiaを認識されたランタイムにします。
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
再起動をスキップしないでください。デーモンがまだ古い設定で動いているために「GPUが見つかりません」エラーのデバッグに何時間も費やした結果、単なるsystemctl restartが解決策だったということがよくあります。ここでは再起動が最大の味方です。
検証:パイプラインのテスト
修正を確認しましょう。軽量なCUDAイメージをプルし、コンテナの*内部*からnvidia-smiを実行します。
sudo docker run --rm --runtime=nvidia --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi
ターミナルにGPUステータステーブルが表示されれば、コンテナの壁を突き破ることに成功しています。--gpus allフラグはすべてのカードを公開します。マルチGPUサーバーを管理していてワークロードを分離したい場合は、--gpus "device=0,1"のように特定のIDを使用してください。
本番環境でよくある落とし穴を避ける
クリーンインストールを行っても、本番環境ではトリッキーな問題が発生することがあります。よくある原因は以下の通りです:
CUDA互換性の罠
バージョンの不一致は、最も頻繁に発生するトラブルの原因です。ホストドライバがバージョン470.xxであるのに、DockerイメージがCUDA 12.xを必要としている場合、即座に失敗します。新しいドライバは古いCUDAバージョンと後方互換性がありますが、その逆はほとんどありません。常にNVIDIA互換性マトリックスを確認してください。
パーミッションの問題
Dockerをルートレス(rootless)モードで実行していますか? その場合、インストール手順が少し異なり、ツールキットのconfig.tomlに追加の設定が必要です。ほとんどの本番サーバーでは、ユーザーをdockerグループに追加し、標準モードを使用するのが最も抵抗の少ない方法です。
Fabric Managerの要件
DGXや、NVLinkを備えたH100 GPUを使用するハイエンドシステムでは、nvidia-fabricmanagerサービスがアクティブであることを確認する必要があります。これがないと、nvidia-smiが正常に見えても、マルチGPU間通信が暗黙的に失敗します。
最後に
DockerでGPUサポートを有効にするのは、単にコマンドを実行するだけのことではありません。Linuxカーネル、NVIDIAドライバ、そしてランタイム間の「引き継ぎ」を理解することです。NVIDIA Container Toolkitを使いこなすことで、複雑な機械学習モデルをあらゆるUbuntuインフラに自信を持ってデプロイできるようになります。
次に深夜のデプロイ失敗に直面したときは、ホストドライバを確認し、ツールキットの設定を検証し、常にデーモンを再起動することを忘れないでください。これらの基礎的なステップが、世界が眠っている間もハイパフォーマンスなシステムの円滑な運用を支えるのです。

