LabHub
学习 学习路径 课程

闭网环境的 GPU 驱动搬入与安装

用引入的那份材料立起仓库并安装

在 LabHub 中继续学习

一句话总结

将带入隔离环境的 .deb 软件包集合制作成软件源,就能交给 apt 处理,而不必逐个调整顺序再用 dpkg 安装。这是导入软件包的标准方式。

概念图: 制作成软件源 · 下次再做时还必须记住这个顺序。 · 不要跳过第 4 步。 · 这份输出就是导入是否成功的答案。

为什么需要这样做

如果用 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 的状态(如 iUiF),就说明安装尚未彻底完成。

驱动程序、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 与导入记录一并保存。以后需要回滚时,便能知道应该撤销哪一笔事务。

下一项实验要做什么

使用第一批导入的软件包建立软件源并成功安装驱动程序,随后确认工具包安装会失败,再补充缺失项(第二批导入内容)并重新安装成功。这就是隔离网络中的真实操作流程。