资讯详情

资讯详情

离线环境安装docker-ce与nvidia-docker2的完整实践指南

简介在无外网环境中为 CentOS 7.6 部署容器运行时常因依赖缺失与 GPG 校验受阻。该离线安装包专为此场景设计面向运维工程师及需搭建 GPU 加速容器的开发者涵盖 Docker CE 19.03 与 NVIDIA Docker 2.4 的完整 RPM 依赖链无需联网即可完成安装。压缩包共 30 个文件体积约 91.98MB以 20 个 RPM 安装包为核心辅以 GZ/BZ2 压缩库、repo 元数据、XML 仓库描述、JSON 配置及 GPG 密钥文件结构清晰可直接用于内网批量部署。文中附带的 daemon.json 预设了 GPU 运行时配置路径安装后仅需替换配置并重启 Docker 即可生效。已有 3312 人学习使用尤其适合服务器离线初始化、AI 推理环境快速交付等场景可帮助避开 Yum 源不可达、依赖循环等典型坑点显著缩短部署排错时间。1. 离线机房里那台装了GPU的服务器等的不只是docker-ce一台centos7.6服务器两张T4卡要在一个彻底上不了公网的机房里部署推理服务。我到现场一看系统是7.6驱动已经用run文件装好宿主机nvidia-smi输出正常偏偏容器环境完全是空的——docker没装nvidia-docker2更是没人碰过。没有外网yum直接失效照着在线教程一步步走根本走不通。这篇笔记要解决的问题很具体在联网备机上把docker-ce 19.03和nvidia-docker2连同全部依赖收集成rpm包拷进离线机搭本地yum源完成安装并让容器里能跑通nvidia-smi。整套流程不需要目标机器碰公网一次适合刚接手内网GPU服务器的人也适合给产线批量交付同样镜像环境的运维。下面每一步都是我实际落过地的命令和参数坑也一并写出来。2. 离线安装前先想清楚为什么锁死19.03和nvidia-docker2这对组合2.1 版本选择的三个理由内核、驱动与容器运行时的三角关系centos7.6的默认内核是3.10.0-957cgroup还是v1体系。docker-ce官方仓库里19.03是兼容这套内核的最后一批稳定版本线也是第一个原生支持--gpus参数的版本线后续的20.10虽然也能用但依赖的containerd.io版本更激进在7.6的cgroup v1上偶发资源统计异常。离线环境里排查一个运行时异常的成本极高所以选19.03不是情怀是求稳。nvidia-docker2这个包名对应的是NVIDIA官方的GPU容器运行时方案。它做的事情是给docker注册一个名为nvidia的runtime在容器启动时把宿主机的显卡驱动、CUDA driver库透传进去。docker本身不认显卡只有加上这层运行时--gpus all才有意义。19.03提供命令行入口nvidia-docker2提供底层能力两者是组合关系不是二选一。还有一个隐含前提必须提前确认宿主机上必须已经装好NVIDIA显卡驱动且nvidia-smi在宿主机能正常输出。nvidia-docker2只是透传驱动不是替代驱动。驱动没装好后面容器里报的错会非常难排查这个坑我在第5章会专门细说。2.2 离线环境的资源清单要有哪些文件、不能缺哪一类动手收集之前先列清楚一份完整的离线资源项缺一项后面都会卡壳。资源内容说明rpm包目录docker-ce、docker-ce-cli、containerd.io及全部依赖这是docker本体rpm包目录nvidia-docker2、nvidia-container-toolkit、libnvidia-container1、libnvidia-container-tools这是GPU运行时链本地repo配置指向rpm目录的.repo文件让yum在离线机认识这些包CUDA基础镜像tar包nvidia/cuda镜像的save产物容器里跑nvidia-smi用必须离线导入很多人漏掉的是最后一项离线机上docker pull一定失败必须在备机上docker save成tar包再拷过去docker load。镜像tar和rpm包属于两条线前者负责容器内容后者负责容器运行能力我在第4章里会完整演示这条链路。另外还要注意架构问题。备机和离线机都应该是x86_64用uname -m先确认。arm架构机器的rpm包和镜像要单独收集不能拿x86的包硬装这和离线安装mysql时下载arm版rpm是同一个道理。2.3 在联网备机上用repotrack收集依赖包命令与筛选备机需要能访问公网并且在备机上先把docker官方和nvidia官方两套centos7仓库加进来。收集依赖包我推荐用repotrack而不是yumdownloaderyumdownloader加--resolve参数只会解析一层依赖repotrack会把整棵依赖树递归拉下来。离线安装最怕的就是半路冒出一个缺失的-el7.x86_64.rpm所以收集阶段宁可多收不可少收。# 在联网备机上执行 yum install -y yum-utils createrepo # 添加docker官方centos7仓库 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 添加nvidia官方centos7仓库 yum-config-manager --add-repo https://nvidia.github.io/nvidia-docker/centos7/nvidia-docker.repo mkdir -p /opt/gpu-docker-offline/rpms cd /opt/gpu-docker-offline/rpms # 收集docker-ce 19.03及依赖指定小版本或版本线均可 repotrack --destdir/opt/gpu-docker-offline/rpms docker-ce-19.03 docker-ce-cli containerd.io # 收集nvidia-docker2整条依赖链 repotrack --destdir/opt/gpu-docker-offline/rpms nvidia-docker2 libnvidia-container1 libnvidia-container-tools nvidia-container-toolkit逻辑说明repotrack执行完不会安装任何包只是把匹配到的rpm文件下载到指定目录。docker-ce-19.03这种写法会匹配yum源里所有19.03开头的小版本装的时候yum自动选一个合适版本避免自己死记19.03.15这种具体版本号。后面四条nvidia包是把完整运行时链点名拉下来缺一条都会在离线机安装时报依赖错误。参数说明--destdir必须放在命令前面指定输出目录否则文件落在当前目录管理起来很乱。备机上收集到的rpm包数量一般有几十个除了docker自身还包括container-selinux、policycoreutils-python这类系统依赖。收集完成后这套操作和离线安装node时把所有二进制包和依赖目录一次性拷过去是一个思路只是yum的依赖关系比node_modules更绕少一个包都装不上。3. 把离线rpm包变成本地yum源再装docker-ce 19.033.1 用createrepo生成repodata最小命令备机上收集好的rpm包只是一个文件堆yum要靠repodata索引才能解析依赖。createrepo的作用就是在rpm目录里生成这个索引。cd /opt/gpu-docker-offline createrepo rpms/执行后rpms/目录下会多出repodata/子目录里面有repomd.xml等索引文件。这一步完成后把整个/opt/gpu-docker-offline目录打成压缩包拷到离线机任意路径解压。我在打包时习惯把rpm目录单独放不要和后续的镜像tar混在一个目录里repodata是按目录生成的目录路径变了索引路径也要跟着变。3.2 本地repo文件怎么写gpgcheck和baseurl细节离线机上要把本地目录变成yum认识的源在/etc/yum.repos.d/下新建一个repo文件内容指向解压出来的rpm目录。[gpu-docker-local] nameGPU Docker Offline Repo baseurlfile:///opt/gpu-docker-offline/rpms enabled1 gpgcheck0baseurl必须是file://开头路径指向包含repodata/的那个目录不是tar包解压的根目录。第一次搭这个源时我把路径多写了一层结果yum install docker-ce一直报找不到包后来用yum repolist一查这个源显示的包数量是0问题马上暴露。gpgcheck设为0是离线环境下的省事做法。如果保留gpgcheck1就必须把docker官方和nvidia官方的GPG key也拷进离线机并执行rpm --import否则本地源里的包全部因签名未知被拒绝。内网环境没有外部攻击面我一般直接关掉。配置完成后让yum重建缓存yum clean all yum makecache3.3 用yum localinstall安装docker-ce为什么不用rpm -ivh离线机的repo源就绪后安装docker本体。cd /opt/gpu-docker-offline/rpms # 推荐用localinstall让yum自动处理依赖顺序 yum localinstall -y docker-ce-*.rpm --nogpgcheck # 安装完成后启动并验证 systemctl start docker systemctl enable docker docker version这里有一个明显的细节差异rpm -ivh *.rpm会把所有rpm按文件名字母序安装docker-ce主包会在containerd.io前面先装结果就是报依赖缺失或冲突。yum localinstall会读取rpm目录里的依赖关系把containerd.io、container-selinux这些都按正确顺序装好。离线环境里请忘掉rpm -ivh *.rpm这是很多人翻车的起点。--nogpgcheck和repo文件里的gpgcheck0作用相同双保险。docker version输出里如果Client和Server两段都能看到19.03.xdocker本体就已经通了。Server段起不来时报的是Cannot connect to the Docker daemon这时先看journalctl -u docker不要反复systemctl start原因基本在日志里已经写明。4. nvidia-docker2的离线安装链runtime注册与GPU容器验证4.1 先看清nvidia-docker2的依赖关系别只装一个包nvidia-docker2不是独立软件它是一整条依赖链的最上层。完整的链条是nvidia-docker2依赖nvidia-container-runtime这个运行时由nvidia-container-toolkit提供toolkit又依赖libnvidia-container1和libnvidia-container-tools做底层库调用。任何一层缺失效果都是docker启动容器时找不到nvidia runtime。在备机收集阶段repotrack已经把这条链上的包都拉下来了。到了离线机安装目录里先确认这些包都在ls -l | grep -E nvidia-(docker|container|libnvidia)看到nvidia-docker2、nvidia-container-toolkit、libnvidia-container1、libnvidia-container-tools四类包齐全再往下走。这套依赖关系在NVIDIA官方仓库的rpm包里是固定的版本不同链条不变。我见过有人图省事只装nvidia-docker2一个rpm结果docker info里永远看不到nvidia这个runtime。4.2 安装nvidia-docker2并确认daemon.json被正确写入cd /opt/gpu-docker-offline/rpms # 一次装齐整条链 yum localinstall -y nvidia-docker2-*.rpm libnvidia-container*.rpm --nogpgcheck # 安装完成后检查daemon.json cat /etc/docker/daemon.json # 重启docker让配置生效 systemctl restart docker # 确认docker已经认识nvidia runtime docker info | grep -i runtime逻辑说明nvidia-docker2的安装脚本会自动把nvidia runtime的配置合并进/etc/docker/daemon.json。但这里有个隐患如果离线机上原本就存在daemon.json比如配置过registry-mirror或私有仓库地址安装脚本的合并逻辑偶尔会失败且不报错。所以安装后必须cat实际内容确认。如果daemon.json里没有nvidia runtime配置需要手动补全。这是唯一的配置正解{ runtimes: { nvidia: { path: /usr/bin/nvidia-container-runtime, runtimeArgs: [] } } }手动写入后执行systemctl restart docker。这里的path指向的二进制由nvidia-container-toolkit包提供如果这个文件不存在docker启动容器时会报unknown runtime nvidia。所以写配置前先ls /usr/bin/nvidia-container-runtime确认文件在不在。4.3 离线导入GPU镜像并跑通容器里的nvidia-smidocker和nvidia runtime都就绪后还差一个能在容器里运行的基础镜像。这一步必须在备机完成pull和save离线机只负责load。整个逻辑和wsl离线导入ubuntu镜像包一样先在一个地方准备好完整镜像再传输导入。# 在联网备机执行 docker pull nvidia/cuda:11.0-base docker save nvidia/cuda:11.0-base -o nvidia-cuda-11.0-base.tar # 把tar包拷到离线机然后在离线机执行 docker load -i nvidia-cuda-11.0-base.tar # 用GPU运行时启动容器并验证 docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi参数说明--gpus all表示把宿主机全部GPU设备传入容器nvidia runtime会拦截容器启动过程自动执行nvidia-container-cli的挂载逻辑把显卡设备和驱动库映射进去。容器内nvidia-smi的输出应该和宿主机一致能看到显卡型号、驱动版本以及CUDA版本。这里有个匹配问题需要留意镜像tag里的CUDA版本要能被宿主机驱动支持。比如CUDA 11.0的基础镜像要求宿主机驱动版本不低于450.x。如果容器里报CUDA版本不支持要么换更老的基础镜像要么升级宿主机驱动不要以为这是nvidia-docker2装错了。5. 离线安装避坑让GPU容器翻车的5个典型问题5.1 依赖报错包明明在目录里yum却说不认识现象yum localinstall时提示缺少某个-el7.x86_64.rpm打开rpms目录确认文件就在那里。原因yum没有成功索引本地源。最常见是baseurl路径写错比如指向了tar包解压根目录而不是包含repodata的子目录或者往rpms目录追加了新rpm后忘了重新执行createrepoyum的索引还是旧的。解决检查repo文件的baseurl指向repodata/所在目录如果目录内容有变动重新执行createrepo rpms/然后yum clean all yum makecache再装。5.2 docker服务起不来报iptables failed现象systemctl start docker报Error creating default bridge network: iptables failed。原因离线最小化安装的centos7.6通常没有装iptables服务或者firewalld处于disabled状态导致NAT链缺失docker创建默认bridge网络时调用iptables失败。解决先装iptables组件yum install -y iptables iptables-services再systemctl enable iptables最后重新启动docker。如果确认这是纯内网环境且容器对外网络需求极低可以在daemon.json里加iptables: false绕开但GPU容器一般要联网拉推理数据我不建议关。5.3 docker run --gpus all报unknown runtime nvidia现象启动容器时docker daemon返回Error response from daemon: unknown runtime nvidia。原因daemon.json里没有nvidia runtime配置或者配置里的path指向的二进制不存在。nvidia-docker2安装脚本合并配置失败是高频原因特别是在原daemon.json里已经手动写过runtimes字段的情况下。解决先ls /usr/bin/nvidia-container-runtime确认二进制在再手动写入完整runtime配置到daemon.jsonsystemctl restart docker后docker info查看Runtimes段应该包含nvidia。这个坑在自动化和手动混合配置时出现最多我每次都先检查这步才继续跑容器。5.4 容器里nvidia-smi报couldnt find libcuda现象容器启动成功但执行nvidia-smi时报找不到libcuda或者显示NVIDIA driver not loaded。原因宿主机显卡驱动是用.run脚本安装的装完后没有把动态库路径暴露给系统。nvidia-container-cli在容器启动时找不到libcuda.so.xxx透传失败。解决到宿主机上执行ldconfig确认/usr/lib64/nvidia/下的libcuda库被系统识别。如果没识别写入/etc/ld.so.conf.d/nvidia.conf并再执行一次ldconfig。排查时可以用nvidia-container-cli info看完整报错这条命令会直接告诉你哪一层找不到库。5.5 在离线机上习惯性执行docker pull超时后才想起来没网现象离线机上docker pull nvidia/cuda:11.0-base一直转圈超时到最后才反应过来这台机器根本没有外网。原因这是最不值得踩的坑纯粹是操作习惯问题。离线机的镜像来源只能是tar包没有别的路径。解决回到备机执行pull和savetar包拷进离线机后load。顺带再提醒一次备机和离线机的架构必须一致。x86_64备机拉下来的镜像到arm64离线机上load是能成功的但运行时直接exec format error。这和离线安装mysql时下载arm版rpm是同类问题先uname -m对一下再拷贝。6. 离线安装后的收尾技巧一键脚本与三步验证6.1 把整套安装流程固化成一个可复用的脚本同一套离线环境和机型我给每个机房交付时都会带一个小脚本把第3章和第4章的安装步骤串起来。脚本设计成可重复执行跑烂了也不怕重跑一遍就能把环境拉回到可用状态。#!/bin/bash # offline-docker-install.sh 适用场景rpms目录已拷入离线机 RPMS_DIR/opt/gpu-docker-offline/rpms cd $RPMS_DIR || exit 1 # 第一步安装docker本体 yum localinstall -y docker-ce-*.rpm --nogpgcheck systemctl enable docker systemctl start docker # 第二步安装nvidia docker运行时链 yum localinstall -y nvidia-docker2-*.rpm libnvidia-container*.rpm --nogpgcheck # 第三步确保daemon.json里已经有nvidia runtime没有则写入 if ! grep -q nvidia /etc/docker/daemon.json 2/dev/null; then echo {runtimes:{nvidia:{path:/usr/bin/nvidia-container-runtime,runtimeArgs:[]}}} /etc/docker/daemon.json fi systemctl restart docker docker info | grep -i runtime nvidia-container-cli info这段脚本有一点要注意第三步里如果用echo直接覆盖daemon.json原来是registry-mirror这类自定义配置会被清掉。如果离线机原本有daemon.json内容先把原文件备份一份再用python或jq做字段合并不要直接覆盖。脚本末尾的nvidia-container-cli info是快速体检项它能给出驱动库、设备节点、运行时权限三方面的状态比直接跑容器定位问题快得多。6.2 用三步验证法确认整个链路可用我习惯的最终验证不是装完跑一次容器就结束而是分三步走第一步宿主机nvidia-smi确认驱动正常第二步docker info | grep -i runtime确认docker认识nvidia runtime第三步docker run --rm --gpus all执行一次容器内nvidia-smi输出与宿主机一致才算闭环。三步中任何一步异常都按第5章对应条目去查不要跳步。这套离线安装方案我已经在不同机房的GPU服务器上重复用过多轮最大的教训始终是同一个配置daemon.json之前先看一眼原文件内容改完先docker info再跑容器。机器越是没有网越要在每一步留痕日志和输出就是你唯一的判断依据。希望这个流程能帮你在没网的GPU服务器上少走弯路一步到位把docker-ce 19.03和nvidia-docker2跑起来。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →