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

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

なぜ閉域網の導入は難しいのか

TT Labで続きを見る

一言でいうと

エアギャップ環境でのインストールが難しい本当の理由は、依存関係を計算する側とインストールする側が分離されているためです。計算に必要な情報が、両側に分かれています。

なぜ必要なのか

依頼は、いつもこうやって来ます。「ドライバーのファイルを1つだけ取得してきてください」。

取得して入れると、こんなエラーが出ます。

The following packages have unmet dependencies:
 nvidia-driver-550 : Depends: nvidia-kernel-dkms-550 but it is not installable

もう一度外に出て、それを取得してくると、また別のものがないと言われます。USBを3、4回往復させると、半日が過ぎていて、持ち込み審査は1日に1回だけです。

どう動くのか

計算とインストールの分離

依存関係リゾルバー(depsolver)の入力は、2つです。

  1. リポジトリメタデータの全体: どのパッケージが何を提供して、何を要求するか
  2. インストール対象システムの現在の状態: すでに何がインストールされているか

エアギャップ環境の内側には1番がなく、外側には2番がありません。この分離が、問題の本質です。

解決策は2つの方向です。

小さく始めると、1つ目に進みますが、ほとんどの組織は、結局2つ目に進みます。持ち込みが繰り返されると、1つ目の方式の管理コストが、急激に大きくなるからです。

黙って抜け落ちるもの

1つ目の方式で最も危険なのは、エラーなしで黙って抜け落ちるパッケージです。

第一に、すでにインストールされているものが、結果から消えます。依存関係の計算は、「計算するシステムの現在の状態」を前提にします。接続された環境の機器に、すでにインストールされているライブラリは、「不要」として処理されて、一覧から抜け、その事実は、エアギャップ環境の内側で初めて明らかになります。

第二に、バージョンが違うと、結果が変わります。接続された環境の機器が24.04で、インストール対象が22.04なら、解決の結果が違うことがあります。

第三に、アーキテクチャを忘れます。noarch/allパッケージを、arch指定から落とすと、Pythonモジュールや設定パッケージが、丸ごと抜けます。

第四に、弱い依存(Recommends)の扱いです。計算するときは除外したのに、インストールするときはデフォルトで含まれるために、要求される場合があります。逆の場合もあります。

そのため、定石は、空のルートを基準に計算することです。apt側では、--print-urisで取得する一覧を先に取り出して確認し、--download-onlyで取得したあと、そのまとまりが自分の中で閉じているか(closure)を確認します。

完全性: 2つの異なる問い

媒体を通ったファイルについて、尋ねるべき問いは2つです。

問い 答えるもの ツール
転送中に破損していないか チェックサム sha256sum -c
これは本当に、そちらから来たもので合っているか 署名 GPG検証、dpkg-sig、rpm --checksig

同じ媒体にだけ入ったチェックサムは、媒体が丸ごとすり替えられると、一緒に変わります。そのため、チェックサムだけでは、出所を保証できません。実質的な保証は、署名から得られます。

そして、マニフェストにないのに媒体に入っているファイルも、検査する必要があります。不足は、インストールの失敗としてすぐに明らかになりますが、追加されたファイルは、誰にも知られずに通り過ぎます。持ち込み審査の観点では、こちらのほうが、大きな問題です。

持ち込み記録

バンドルには、ファイルだけでなく、記録も一緒に入る必要があります。

項目 例 理由
バンドルID gpu-airgap-2026-08-20 サーバーとバンドルを結び付けるキー
スナップショットの日付 2026-08-20 どの時点のコンテンツか
対象バージョン ubuntu 24.04 / driver 550.90.07 再現の前提
生成コマンド apt-get install --download-only ... 再現の核心
媒体のハッシュ アーカイブ全体のSHA-256 媒体単位の完全性
持ち込み日時・担当者 — 監査の要求

6か月後に、「このサーバーは、どの時点のコンテンツでインストールされたのか」という問いに、答えられる必要があります。

持ち込み前に一覧を作る方法

エアギャップ環境への持ち込みで、最もよくある失敗は、完全性ではなく、抜け漏れです。一度入ったら、もう一度出てくるのは難しいので、一覧を作る方法そのものが、手続きの核心になります。

依存関係を人が数えません。パッケージマネージャーに、「これをインストールするには、何が必要か」を尋ねて、その答えを、そのまま入れます。

# 데비안 계열: 의존성까지 통째로 내려받는다
apt-get install --download-only --reinstall -o Dir::Cache::archives=./pkgs <패키지>
# RHEL 계열
dnf download --resolve --alldeps --destdir ./pkgs <패키지>
# 파이썬: 해시까지 고정해서
pip download -r requirements.txt -d ./wheels --require-hashes

コンテナイメージは、ダイジェストで入れます。タグで入れると、外部で取得したものと、内側で使うものが、違うことがあります。

skopeo copy --all docker://registry/app@sha256:... dir:./images/app

--allがなければ、今のこのコンピューターのアーキテクチャだけが入ります。持ち込み対象が別のアーキテクチャなら、内側で「manifest unknown」に出会います。

GPU側は、バージョンの組み合わせが、特に厳密です。ドライバー、コンテナツールキット、CUDA、フレームワークの組み合わせが、合っている必要があります。1つだけずれても、「GPUが見つからない」として現れ、エアギャップ環境の中では、別のバージョンを取得してみることができません。外部で、同じ組み合わせを一度立ててみて、その一覧を、そのまま持ち込みます。

インストールの順序も、一緒に入れます。オフラインリポジトリを作成して、そのリポジトリを指すように設定し、順番にインストールするスクリプトを、一緒に入れます。内側で、手で順序を探すのは、時間もかかり、再現もできません。

元に戻す方法も、一緒に入れます。ドライバーを上げて問題が生じたら、以前のバージョンに戻る必要がありますが、その以前のバージョンのパッケージが内側にないと、戻せません。現在インストールされているバージョンのパッケージも、一緒に持ち込みます。

現場での姿

epochの落とし穴: Debian/RPMとも、バージョンの前にepochを置けます(1:550.90.07-0ubuntu1)。ファイル名には、epochは入りません。ところが、バージョンの比較では、epochが最優先です。ファイル名だけを見て、「こちらのほうが新しい」と判断すると、間違うことがあります。マニフェストに、完全なバージョン文字列を書く必要がある理由です。

次の確認で見ること

続くクイズでは、依存関係の計算の2つの入力、チェックサムと署名の役割、マニフェストの双方向の検証を、まず区別します。その判断基準を確認したあと、次のモジュールから、パッケージのまとまりの依存関係グラフと、インストール順序を、実際に導き出します。