なぜ閉域網の導入は難しいのか
一言でいうと
エアギャップ環境でのインストールが難しい本当の理由は、依存関係を計算する側とインストールする側が分離されているためです。計算に必要な情報が、両側に分かれています。
なぜ必要なのか
依頼は、いつもこうやって来ます。「ドライバーのファイルを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番がありません。この分離が、問題の本質です。
解決策は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つの入力、チェックサムと署名の役割、マニフェストの双方向の検証を、まず区別します。その判断基準を確認したあと、次のモジュールから、パッケージのまとまりの依存関係グラフと、インストール順序を、実際に導き出します。