TT Lab
はじめる
学ぶ 学習パス コース

閉域網へのGPUドライバ搬入と導入

containerdにランタイムを登録する

TT Labで続きを見る

一言でいうと

コンテナでGPUを使うには、ドライバー(カーネル)+ ツールキット(注入ツール)+ ランタイム登録(config.toml)の3つが、すべて必要です。1つだけ欠けても、症状は同じ「GPUが見えない」です。

なぜ必要なのか

ドライバーをインストールして、nvidia-smiもうまく動くのに、コンテナの中では、GPUが見えません。よくある状況で、原因は、たいていランタイム登録がされていないことです。

どう動くのか

3つの層

層 何か 確認方法
カーネル nvidia.koモジュール、/dev/nvidia*デバイスノード lsmod | grep nvidia、ls /dev/nvidia*
ユーザー空間 libcuda.so、libnvidia-ml.soなど nvidia-smi、ldconfig -p | grep nvidia
コンテナへの注入 nvidia-container-cli、CDIスペック、ランタイム登録 nvidia-ctk cdi list、config.toml

コンテナの中には、カーネルがありません(ホストと共有します)。そのため、必要なのは、ユーザー空間のライブラリとデバイスノードを、コンテナの中に入れてあげることで、それをするのが、ツールキットです。

containerd config.toml

containerd config defaultで、デフォルトのファイルを作成したあと、ランタイムを追加します。手でヘッダーを組み立てないでください。セクションヘッダーが、containerdのメジャーバージョンによって、丸ごと変わります。

config version 2(containerd 1.x):

version = 2

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia]
  runtime_type = "io.containerd.runc.v2"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options]
  BinaryName = "/usr/bin/nvidia-container-runtime"
  SystemdCgroup = true

config version 3(containerd 2.x)では、CRIの設定が、ランタイムとイメージの2つに分かれます。

version = 3

[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.nvidia.options]
  BinaryName = '/usr/bin/nvidia-container-runtime'
  SystemdCgroup = true

バージョン2のファイルは、2.xでもサポートされ、自動変換されます。バージョン1は、2.0からサポートされません。インターネットから拾ってきたスニペットを貼り付けたのに、何の効果もなければ、たいていは、このバージョンの不一致です。

nvidia-ctkが、この編集を代わりにしてくれます。

nvidia-ctk runtime configure --runtime=containerd --set-as-default=false

--set-as-default=falseが重要です。デフォルトのランタイムをnvidiaに変えると、GPUを使わないPodまで、そのランタイムを経由します。そのランタイムに問題が生じると、クラスター全体が影響を受けます。

SystemdCgroup

デフォルト値は、falseです。ところが、systemdベースのホストでは、trueが推奨されます。なぜなら、kubeletだけをsystemd cgroupドライバーに変えて、containerdをそのままにすると、2つのマネージャーが、別々のcgroupビューを持つことになるためです。この不一致は、リソース制限がおかしな動作をしたり、Podが予想と違う形でエビクトされたりする形で現れます。

RuntimeClass

登録したランタイムを、ワークロードが選択できるようにします。

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia
handler: nvidia          # config.toml 의 runtimes.<이름> 과 일치해야 한다
spec:
  runtimeClassName: nvidia
  containers:
    - name: cuda
      resources:
        limits:
          nvidia.com/gpu: 1

handlerの値とconfig.tomlのランタイム名が、正確に一致する必要があります。合わないと、PodがRunContainerErrorで起動し、メッセージに「no runtime for ... is configured」が出ます。

マネージドノードの落とし穴

マネージドノードグループでは、ノードのブートストラップのときに、config.tomlが、もう一度生成されることが多いです。手で直した設定は、ノードが入れ替わる瞬間に消え、さらに悪いことに、一部のノードにだけ残って、再現できない違いを作ります。設定を変える必要があるなら、ブートストラップスクリプトや、起動テンプレート、あるいはノードイメージ自体を、直す必要があります。ノードに入って直したものは、診断であって、デプロイではありません。

現場での姿

ドライバーの更新後に、GPUが認識されません。CDIスペックの再生成を、忘れています。スペックには、バージョンが埋め込まれたライブラリのパスが入っています。

GPUのPodだけ、起動が遅いです。コンテナの起動のたびに、ライブラリを注入して、ldcacheを更新するコストです。イメージが大きいと、より目立ちます。

次のラボですること

config.tomlに、nvidiaランタイムを登録して、TOMLパーサーで検証します。CDIスペックを配置して、RuntimeClassのYAMLを作成します。実際のGPUがなくても、設定の正確さは、すべて検証できます。