用引入的那份材料立起仓库并安装
一句话总结
将带入隔离环境的 .deb 软件包集合制作成软件源,就能交给 apt 处理,而不必逐个调整顺序再用 dpkg 安装。这是导入软件包的标准方式。
为什么需要这样做
如果用 dpkg -i *.deb 一次安装所有带入的文件,安装往往会因顺序不对而失败。虽然可以排好顺序逐个安装,但如果有 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 表示软件包虽然存在,但版本不匹配。这个区别是编制第二批导入清单的依据。
明确标注软件源信息
deb [trusted=yes] file:/srv/airgap/pool ./
[trusted=yes] 声明信任未签名的软件源。除非是实验或临时软件源,否则必须进行签名。 在生产环境中,应使用自有 GPG 密钥为 Release 文件签名,并通过 [signed-by=/usr/share/keyrings/...] 指定密钥。
此外,在软件源名称或路径中加入快照日期,会对六个月后的调查大有帮助。
安装后检查
dpkg -l 'nvidia*' 'libnvidia*' | grep '^ii' | wc -l
dpkg -l | grep -c '^i[^i]' # ii 가 아닌 것 (문제 있는 상태)
apt-get -f install # 미해결이 있으면 정리
只要存在一个不是 ii 的状态(如 iU、iF),就说明安装尚未彻底完成。
驱动程序、CUDA 与容器工具包的关系
这三者各不相同,版本规则也不一样。如果分不清它们,很可能会因为“明明安装了 CUDA 却不能用”而浪费一整天。
[ 호스트 ]
NVIDIA 드라이버 (커널 모듈 + libcuda.so) ← 여기만 커널에 붙는다
nvidia-container-toolkit ← 컨테이너에 장치를 넣어 준다
↓
[ 컨테이너 ]
CUDA 런타임 (libcudart) ← 이미지 안에 들어 있다
cuDNN, PyTorch …
不要在容器内安装驱动程序。 内核模块只使用主机上的一份,工具包会将 /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'
可以从三种方案中选择一种:注册 MOK 密钥并为模块签名;使用发行版已签名的驱动程序包;或者关闭 Secure Boot。在隔离网络中,注册 MOK 时必须有人在重启过程中通过控制台输入,因此,如果环境只能远程访问,就必须提前规划。
实际现场中的情况
应把第二批导入视为必然,并据此设计流程。 无论计算得多么周密,第一批导入中仍可能出现遗漏。因此,成熟的组织会将“第一批导入后进行模拟 → 自动生成缺失项清单 → 第二批导入”固化为流程。如果由人工编制缺失项清单,还会再次漏项。
保留安装日志。 将 apt-get install 的输出和 /var/log/apt/history.log 与导入记录一并保存。以后需要回滚时,便能知道应该撤销哪一笔事务。
下一项实验要做什么
使用第一批导入的软件包建立软件源并成功安装驱动程序,随后确认工具包安装会失败,再补充缺失项(第二批导入内容)并重新安装成功。这就是隔离网络中的真实操作流程。