搬入分でリポジトリを立てて導入する
一言でいうと
持ち込んだ.debのまとまりを、リポジトリにすれば、dpkgで1つずつ順序を合わせてインストールする代わりに、aptに任せられます。それが、持ち込み方式の標準です。
なぜ必要なのか
持ち込んだファイルをdpkg -i *.debで一度にインストールすると、順序のために失敗します。順序を合わせて1つずつやれば済みますが、パッケージが30個なら、それも大変です。そして何より、次にもう一度やるときに、その順序を覚えている必要があります。
リポジトリにすれば、この問題がなくなります。aptがグラフを解いて、順序を決めます。そして、そのリポジトリは、繰り返し再利用されます。
どう動くのか
手順
# 1. 반입분을 한곳에 모은다
mkdir -p /srv/airgap/pool && cp /media/usb/*.deb /srv/airgap/pool/
# 2. 색인을 만든다
cd /srv/airgap && dpkg-scanpackages pool /dev/null > pool/Packages
gzip -kf pool/Packages
# 3. 저장소로 등록한다
echo 'deb [trusted=yes] file:/srv/airgap/pool ./' > /etc/apt/sources.list.d/airgap.list
apt-get update
# 4. 먼저 시뮬레이션
apt-get install -s nvidia-driver-550
# 5. 실제 설치
apt-get install -y nvidia-driver-550
ステップ4を飛ばさないでください。-s(simulate)は、実際には何も変えず、計画だけを出力します。ここで、Instで始まる行が、インストールされるパッケージで、依存関係が解決できなければ、The following packages have unmet dependenciesが出ます。この出力が、そのまま、持ち込みが成功したかどうかへの答えです。
解決できなかったときの読み方
The following packages have unmet dependencies:
libnvidia-container-tools : Depends: libnvidia-container1 (>= 1.16.2-1) but it is not installable
読み方: 左が要求する側、右がないものです。not installableは、リポジトリにその名前自体がないという意味で、but 1.0 is to be installedは、あるにはあるけれど、バージョンが合わないという意味です。この区別が、2次持ち込みの一覧を作る根拠になります。
リポジトリ情報を明確に
deb [trusted=yes] file:/srv/airgap/pool ./
[trusted=yes]は、署名のないリポジトリを信頼するという宣言です。ラボや一時的なリポジトリでなければ、必ず署名する必要があります。運用環境では、独自のGPGキーでReleaseファイルに署名して、[signed-by=/usr/share/keyrings/...]でキーを指定します。
そして、リポジトリ名やパスに、スナップショットの日付を入れておくと、6か月後に調査するときに、大きな助けになります。
インストール後の確認
dpkg -l 'nvidia*' 'libnvidia*' | grep '^ii' | wc -l
dpkg -l | grep -c '^i[^i]' # ii 가 아닌 것 (문제 있는 상태)
apt-get -f install # 미해결이 있으면 정리
iiではない状態(iU、iFなど)が1つでもあれば、インストールが完全には終わっていません。
ドライバー・CUDA・コンテナツールキットの関係
3つは、それぞれ別のもので、バージョンのルールも違います。この区別ができないと、「CUDAをインストールしたのに動かない」で、1日が過ぎます。
[ 호스트 ]
NVIDIA 드라이버 (커널 모듈 + libcuda.so) ← 여기만 커널에 붙는다
nvidia-container-toolkit ← 컨테이너에 장치를 넣어 준다
↓
[ 컨테이너 ]
CUDA 런타임 (libcudart) ← 이미지 안에 들어 있다
cuDNN, PyTorch …
コンテナの中に、ドライバーを入れません。カーネルモジュールは、ホストのもの1つだけで、ツールキットが、/dev/nvidia*とホストのlibcuda.soを、コンテナに入れてくれます。
バージョンのルールは、ドライバーがCUDAと同じか、それより高い必要があるということです(前方互換)。ドライバー550なら、CUDA 12.4までできます。そのため、イメージのCUDAバージョンを上げるときは、ホストのドライバーから確認します。
nvidia-smi # 오른쪽 위에 드라이버와 CUDA 상한이 나온다
cat /proc/driver/nvidia/version
カーネルを上げると、モジュールが消える
最もよく経験する事故です。apt upgradeでカーネルが上がると、そのカーネル用のNVIDIAモジュールがなくて、再起動のあとにGPUが消えます。
# DKMS 가 새 커널에 맞춰 다시 빌드해 준다 — 이것이 설치돼 있어야 한다
dkms status
nvidia/550.90.07, 6.8.0-45-generic, x86_64: installed
# 커널을 고정하는 방법(폐쇄망에서는 이쪽이 안전하다)
apt-mark hold linux-image-generic linux-headers-generic
エアギャップ環境では、DKMSのビルドに必要なヘッダーとコンパイラーが、持ち込まれている必要があります。そのため、カーネルの固定のほうが、安全な選択であることが多いです。
Secure Bootがふさぐとき
Secure Bootが有効だと、署名されていないカーネルモジュールがロードされません。症状は、「インストールは成功したのに、nvidia-smiがデバイスを見つけられない」です。
mokutil --sb-state # SecureBoot enabled 이면 이 문제일 수 있다
dmesg | grep -i 'nvidia\|taint\|module verification'
3つのうち1つを選びます。MOKキーを登録してモジュールに署名するか、ディストリビューションが署名したドライバーパッケージを使うか、Secure Bootをオフにするか、です。エアギャップ環境でのMOK登録は、コンソールで人が再起動中に入力する必要があるので、リモートだけが可能な環境なら、事前に計画する必要があります。
現場での姿
2次持ち込みが必然だと考えて、手続きを組みます。どれだけうまく計算しても、最初の持ち込みで抜けるものが出ます。そのため、成熟した組織は、「1次持ち込みのあとシミュレーション → 不足分の一覧を自動生成 → 2次持ち込み」を、手続きとして定めています。不足分の一覧を人が手で作ると、また抜けます。
インストールログを残します。apt-get installの出力と、/var/log/apt/history.logを、持ち込み記録と一緒に保管します。あとでロールバックするときに、どのトランザクションを戻す必要があるかがわかります。
次のラボですること
1次持ち込み分でリポジトリを立てて、ドライバーのインストールを成功させ、ツールキットのインストールは失敗することを確認したあと、不足分(2次持ち込み分)を追加して、もう一度成功させます。実際のエアギャップ環境の手続きそのままです。