Docker 24.0.5 内网离线安装实战:RPM与二进制部署及避坑指南 简介这份资源面向需要在无外网或内网环境中部署 Docker 的运维与开发人员提供 Docker 24.0.5 的完整离线安装方案解决服务器无法联网拉取依赖、安装过程反复报错的痛点。压缩包共 18 个文件以 17 个 rpm 依赖包和 1 个 install_docker.sh 安装脚本为主整体约 108.02MBrpm 覆盖 docker-ce、docker-ce-cli、containerd.io、docker-buildx-plugin、docker-compose-plugin 以及 container-selinux、fuse-overlayfs、slirp4netns 等运行依赖脚本负责统一安装并自动启动服务。使用时执行脚本即可需注意脚本要运行两遍以确保依赖与主程序完整就位。目前已有 935 人学习下载适合希望快速完成离线环境搭建、减少依赖排查时间的读者参考使用。1. 内网环境下的 Docker 24.0.5 离线安装从依赖梳理到服务拉起很多做交付的同行都遇到过这种场景客户机房完全断外网安全策略只允许带进去一个 U 盘而部署清单上明明白白写着要跑容器化服务。这时候yum install docker-ce或者apt install docker-ce全部失效curl -fsSL https://get.docker.com | sh更是想都别想。Docker 24.0.5 这个版本在离线场景里被问得特别多因为它属于 24.x 早期稳定版containerd 和 runc 的版本搭配比较成熟很多存量项目的镜像和编排文件都是按这个基线做的。这篇笔记就把我在几台隔离机器上反复装 Docker 24.0.5 的流程拆开从 RPM 包依赖怎么凑齐、二进制包怎么选、systemd 单元怎么配一直讲到装完怎么验证、踩过的坑怎么绕。适合需要在内网批量部署容器的运维和交付工程师新手照着命令走也能复现熟手可以直接跳到参数和排错部分。2. 离线安装前的依赖梳理与包选择RPM 还是二进制离线安装 Docker 24.0.5第一件事不是急着拷文件而是先确定目标机器的发行版和包管理方式。这一步选错后面全是白费功夫。Docker 官方对 CentOS/RHEL 系提供 RPM 包对 Ubuntu/Debian 系提供 DEB 包另外还有一套静态二进制包static binary适用于任何 Linux 发行版。三条路各有适用边界得按现场情况挑。2.1 三种安装方式的适用边界RPM 方式最省心前提是目标机器是 CentOS 7/8、RHEL 7/8 或 Rocky/Alma 这类兼容发行版并且你能把依赖链上的包全部凑齐。Docker 24.0.5 的 RPM 依赖不算特别深但containerd.io、docker-ce-cli、docker-buildx-plugin、docker-compose-plugin这几个是必须一起带进去的缺一个rpm -ivh就会报依赖错误。DEB 方式对应 Ubuntu 20.04/22.04、Debian 11/12依赖关系用dpkg -i装的时候同样需要手动补齐apt-get install -f在离线环境里是没法自动下载的。静态二进制方式最灵活本质是把dockerd、docker、containerd、runc、docker-proxy这些可执行文件直接放到/usr/bin或/usr/local/bin再手写 systemd 单元。它不依赖包管理器适合发行版比较偏、或者客户不允许动系统包管理的场景。代价是升级和卸载都得手动管理没有rpm -e那么干净。我一般会先问清楚两件事目标机器cat /etc/os-release输出是什么以及客户允不允许用包管理器装东西。如果两个条件都友好优先 RPM如果发行版不标准或者权限受限直接上二进制。2.2 依赖清单怎么列以 CentOS 7 为例Docker 24.0.5 离线 RPM 安装需要准备的文件清单大致如下包名作用是否必须docker-ce-24.0.5Docker 引擎主包必须docker-ce-cli-24.0.5命令行客户端必须containerd.io容器运行时必须docker-buildx-plugin构建扩展按需docker-compose-pluginCompose V2按需container-selinuxSELinux 策略CentOS 7 必须libcgroupcgroup 支持部分系统需要container-selinux这个包在 CentOS 7 上特别容易漏漏了之后rpm -ivh docker-ce会直接报Requires: container-selinux 2.9。而container-selinux本身又依赖policycoreutils、selinux-policy等如果目标机器是最小化安装这条链要提前补。一个实用的做法是在一台能联网的同版本机器上用yumdownloader把包和依赖一次性拉下来。# 在联网的同版本 CentOS 7 机器上执行 # 创建存放目录 mkdir -p /tmp/docker-offline cd /tmp/docker-offline # 下载 docker-ce 24.0.5 及其依赖--resolve 会解析依赖树 yumdownloader --resolve --destdir/tmp/docker-offline \ docker-ce-24.0.5 \ docker-ce-cli-24.0.5 \ containerd.io \ docker-buildx-plugin \ docker-compose-plugin # 查看下载了哪些包确认依赖是否齐全 ls -1 /tmp/docker-offline/*.rpm | wc -l ls -1 /tmp/docker-offline/*.rpm这里--resolve是关键参数它会把依赖树里所有包都下载下来而不是只下指定的几个。--destdir指定输出目录。执行完之后ls出来的包数量通常在 10 到 20 个之间取决于基础系统的精简程度。如果数量明显偏少比如只有五六个那大概率是container-selinux这条链没被解析到需要手动补yumdownloader --resolve container-selinux。提示yumdownloader来自yum-utils包联网机器上如果没有先yum install -y yum-utils。2.3 二进制包方案的文件构成如果走静态二进制路线需要从 Docker 官方下载docker-24.0.5.tgz解压后docker/目录下包含这些可执行文件# 解压二进制包 tar -xzvf docker-24.0.5.tgz # 查看解压后的文件列表 ls -1 docker/ # containerd # containerd-shim # containerd-shim-runc-v2 # ctr # docker # docker-init # docker-proxy # dockerd # runc这些文件需要分别放到系统路径下dockerd、docker、containerd、runc、docker-proxy、docker-init放/usr/bin/containerd-shim和containerd-shim-runc-v2也放/usr/bin/ctr是 containerd 的 CLI 工具同样放/usr/bin/。放完之后还要手动创建docker.service和containerd.service两个 systemd 单元这部分在下一章展开。二进制方案的好处是不用管container-selinux这类包依赖坏处是 systemd 单元要自己写写错了服务起不来排查起来比 RPM 方式麻烦。3. 离线安装实操RPM 与二进制两条路径的完整命令依赖包凑齐之后真正的安装动作其实很快容易出问题的是安装前后的配置和验证。这一章把 RPM 和二进制两条路径的操作步骤都走一遍每条命令都说明它在干什么。3.1 RPM 方式安装与依赖补齐把/tmp/docker-offline整个目录拷到目标机器上比如放到/opt/docker-offline然后进目录执行安装。# 进入离线包目录 cd /opt/docker-offline # 一次性安装所有 RPM 包 # --nodeps 不要用让它正常检查依赖缺什么报什么 rpm -ivh *.rpm # 如果报 container-selinux 缺失先单独装它 rpm -ivh container-selinux-*.rpm # 再重新装 docker 相关包 rpm -ivh docker-ce-24.0.5*.rpm docker-ce-cli-24.0.5*.rpm containerd.io*.rpmrpm -ivh *.rpm会按文件名顺序安装如果依赖顺序不对可能先装 docker-ce 再装 containerd.io 导致报错。更稳妥的做法是先装containerd.io和container-selinux再装docker-ce-cli最后装docker-ce。--nodeps这个参数在离线安装里经常被人拿来绕过依赖检查但我不建议用因为绕过的依赖在运行时照样会出问题比如 containerd 没装好dockerd 根本起不来。安装完成后启动服务并设开机自启# 重载 systemd 配置让新装的单元文件生效 systemctl daemon-reload # 启动 Docker 服务 systemctl start docker # 设置开机自启 systemctl enable docker # 查看服务状态确认 active (running) systemctl status dockerdaemon-reload这一步在 RPM 安装后经常被忽略但新装的docker.service文件需要它才能被 systemd 识别。systemctl status docker输出里如果看到Active: active (running)说明服务已经起来了。如果看到failed用journalctl -u docker -n 50看最近 50 行日志大部分启动失败都能从日志里找到原因。3.2 二进制方式安装与 systemd 单元配置二进制方式的安装分四步放文件、写单元、起服务、验证。# 1. 把二进制文件复制到 /usr/bin cp docker/* /usr/bin/ # 2. 确认关键文件就位 which dockerd which containerd which runc # 3. 创建 containerd.service cat /etc/systemd/system/containerd.service EOF [Unit] Descriptioncontainerd container runtime Documentationhttps://containerd.io Afternetwork.target local-fs.target [Service] ExecStartPre-/sbin/modprobe overlay ExecStart/usr/bin/containerd Typenotify Delegateyes KillModeprocess Restartalways RestartSec5 LimitNPROCinfinity LimitCOREinfinity LimitNOFILEinfinity TasksMaxinfinity OOMScoreAdjust-999 [Install] WantedBymulti-user.target EOF # 4. 创建 docker.service cat /etc/systemd/system/docker.service EOF [Unit] DescriptionDocker Application Container Engine Documentationhttps://docs.docker.com Afternetwork-online.target docker.socket firewalld.service containerd.service Wantsnetwork-online.target Requiresdocker.socket containerd.service [Service] Typenotify ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock ExecReload/bin/kill -s HUP $MAINPID TimeoutSec0 RestartSec2 Restartalways StartLimitBurst3 StartLimitInterval60s LimitNOFILEinfinity LimitNPROCinfinity LimitCOREinfinity TasksMaxinfinity Delegateyes KillModeprocess OOMScoreAdjust-500 [Install] WantedBymulti-user.target EOF # 5. 重载并启动 systemctl daemon-reload systemctl start containerd systemctl start docker systemctl enable containerd dockercontainerd.service里的ExecStartPre-/sbin/modprobe overlay前面的减号表示即使这条命令失败也不影响后续启动因为有些内核已经内置了 overlay 模块。Delegateyes让 containerd 能管理自己的 cgroup 子树这个参数在跑 Kubernetes 或者需要资源限制的容器时很重要漏了会导致容器内 cgroup 操作报权限错误。docker.service里的ExecStart指定了-H fd://和--containerd两个参数。-H fd://表示通过 systemd 的 socket 激活方式监听配合docker.socket单元使用--containerd指定 containerd 的 socket 路径二进制安装时这个路径必须和 containerd 实际监听的一致否则 dockerd 连不上 containerd服务会卡在启动阶段。3.3 安装后验证版本、信息与容器运行不管走哪条路径装完都要做三层验证版本对不对、信息全不全、容器能不能跑。# 第一层版本验证 docker version # 输出里 Client 和 Server 的 Version 都应该是 24.0.5 # 如果 Server 部分报错说明 dockerd 没起来 # 第二层信息验证 docker info # 关注 Containerd 版本、Storage Driver、Cgroup Driver 三项 # Storage Driver 通常是 overlay2Cgroup Driver 通常是 systemd # 第三层运行一个测试容器 # 离线环境没有镜像先从别处导入一个 busybox 镜像 docker load -i busybox.tar docker run --rm busybox echo offline docker okdocker version如果 Client 有输出但 Server 报Cannot connect to the Docker daemon说明 dockerd 没在跑回去看systemctl status docker。docker info里的Cgroup Driver如果是cgroupfs而不是systemd在 CentOS 7 上可能和 systemd 的 cgroup 管理冲突需要在/etc/docker/daemon.json里显式指定exec-opts: [native.cgroupdriversystemd]然后重启 Docker。docker load -i busybox.tar这个测试很关键因为离线环境最容易出问题的就是镜像导入和容器启动。如果docker load报invalid tar header多半是 tar 文件传输过程中损坏了重新拷一遍。如果docker run报runc: command not found说明 runc 没放到/usr/bin或者没有执行权限。4. 避坑与排查离线安装 Docker 24.0.5 的五个高频翻车点离线安装的坑集中在依赖、权限、内核和配置四个方向。下面这五条是我在交付现场真实遇到过的每条按现象、原因、解决来写。4.1 现象rpm -ivh 报 container-selinux 缺失手动装了还是报原因container-selinux本身有版本要求Docker 24.0.5 要求container-selinux 2.9如果带进去的是旧版本比如 2.5装了等于没装。另外 CentOS 7 最小化安装可能连policycoreutils都没有container-selinux的依赖链没走完。解决在联网机器上用yumdownloader --resolve container-selinux把完整依赖链拉下来确认rpm -q container-selinux输出的版本号大于等于 2.9。如果目标机器 SELinux 是 disabled 状态也可以临时用rpm -ivh --nodeps container-selinux跳过但这不是推荐做法因为 SELinux 策略缺失可能在后续容器挂载卷时引发权限问题。4.2 现象systemctl start docker 卡住status 显示 activating原因dockerd 启动时在等 containerd 的 socket但 containerd 没起来或者 socket 路径不对。二进制安装时docker.service里写的--containerd/run/containerd/containerd.sock和 containerd 实际监听的路径不一致就会卡在这里。解决先systemctl status containerd确认 containerd 是 active 状态再ls -l /run/containerd/containerd.sock确认 socket 文件存在。如果 containerd 没起来用journalctl -u containerd -n 30看日志常见原因是/usr/bin/containerd没有执行权限或者containerd-shim-runc-v2没放到/usr/bin。4.3 现象docker run 报 permission denied但当前用户已经在 docker 组里原因RPM 安装会自动创建docker用户组但二进制安装不会。另外即使用户在docker组里如果/var/run/docker.sock的属主不对照样连不上。解决二进制安装后手动创建组和用户groupadd docker usermod -aG docker $USER # 重新登录或者 newgrp docker 让组生效 newgrp docker然后确认 socket 权限ls -l /var/run/docker.sock正常应该是srw-rw---- root docker。如果属主是root root说明 dockerd 启动时没读到组配置检查docker.service里有没有Groupdocker。4.4 现象容器能跑但网络不通ping 外部地址失败原因离线环境通常没有外网但容器默认的 bridge 网络需要 iptables 的 NAT 规则。如果目标机器 iptables 规则被清空过或者net.ipv4.ip_forward没开容器出不去。解决检查两个地方# 确认 IP 转发已开启 sysctl net.ipv4.ip_forward # 如果输出是 0临时开启 sysctl -w net.ipv4.ip_forward1 # 永久生效写入 /etc/sysctl.conf echo net.ipv4.ip_forward 1 /etc/sysctl.conf # 确认 iptables 的 nat 表有 Docker 链 iptables -t nat -L -n | grep DOCKER如果iptables -t nat -L里没有DOCKER链重启 Docker 服务会重新生成。注意有些安全加固脚本会定期清 iptables这种情况需要把 Docker 的规则持久化或者把加固脚本的清理逻辑排除掉 Docker 链。4.5 现象docker info 里 Storage Driver 是 vfs容器启动特别慢原因overlay2 驱动依赖内核的 overlay 模块如果内核版本太低或者模块没加载Docker 会回退到 vfs。vfs 不做分层每个容器都复制完整文件系统启动慢、占空间。解决先确认内核版本uname -rCentOS 7 需要 3.10.0-514 以上才支持 overlay2。然后加载模块modprobe overlay lsmod | grep overlay如果模块加载失败说明内核编译时没带 overlay只能升级内核或者接受 vfs。在/etc/docker/daemon.json里可以显式指定驱动{ storage-driver: overlay2, exec-opts: [native.cgroupdriversystemd] }改完systemctl restart docker再用docker info确认驱动生效。5. 离线环境下的镜像搬运与 daemon.json 调优技巧装好 Docker 只是第一步离线环境真正麻烦的是镜像怎么进去、参数怎么调。这一章说两个具体技巧镜像的离线搬运方法以及daemon.json里几个在隔离环境特别有用的配置。5.1 镜像离线搬运save 与 load 的配合联网机器上拉好镜像用docker save导出成 tar拷到离线机器用docker load导入。这一步看起来简单但有几个细节容易翻车。# 联网机器拉取镜像并导出 docker pull nginx:1.24 docker save -o nginx-1.24.tar nginx:1.24 # 如果多个镜像可以一起导出 docker save -o app-images.tar nginx:1.24 redis:7.0 mysql:8.0 # 离线机器导入镜像 docker load -i nginx-1.24.tar # 导入后确认 docker images | grep nginxdocker save导出的 tar 包含镜像的所有层文件可能很大。如果镜像层有重复多个镜像一起导出会比分开导出省空间因为共享层只存一份。导入时docker load会保留原有的镜像名和标签不需要重新 tag。注意docker save和docker export是两回事。save针对镜像保留分层和元数据export针对容器导出的是扁平文件系统导入后没有历史层。离线搬运镜像用save不要用export。如果镜像特别大传输过程中可能损坏导入前先校验# 联网机器生成校验值 sha256sum nginx-1.24.tar nginx-1.24.tar.sha256 # 离线机器校验 sha256sum -c nginx-1.24.tar.sha256校验通过再docker load能避免invalid tar header这类问题。5.2 daemon.json 在隔离环境的推荐配置/etc/docker/daemon.json是 Docker 的运行时配置文件离线环境里几个配置项值得提前写好。{ storage-driver: overlay2, exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 50m, max-file: 3 }, data-root: /var/lib/docker, live-restore: true, iptables: true, default-address-pools: [ { base: 172.30.0.0/16, size: 24 } ] }log-opts里的max-size和max-file控制日志轮转离线环境磁盘清理不方便不限制日志大小很容易把/var撑满。live-restore: true让 dockerd 重启时容器继续运行在需要升级 Docker 或者调整 daemon 配置时很有用能减少服务中断。default-address-pools自定义容器网段避免和客户内网已有网段冲突这个在交付现场经常需要改默认的172.17.0.0/16很容易撞上。改完daemon.json后必须重启 Dockersystemctl restart docker docker info | grep -E Storage Driver|Cgroup Driver|Logging Driver确认三项输出分别是overlay2、systemd、json-file。如果Cgroup Driver还是cgroupfs说明exec-opts没生效检查 JSON 格式有没有写错daemon.json对格式很敏感多一个逗号都会导致 Docker 启动失败。5.3 验证清单与我的固定习惯每次离线装完 Docker我会固定走一遍这个清单检查项命令预期结果版本一致docker versionClient/Server 均为 24.0.5服务自启systemctl is-enabled dockerenabled存储驱动docker info | grep Storageoverlay2Cgroup 驱动docker info | grep Cgroupsystemd容器运行docker run --rm busybox echo ok输出 ok日志轮转docker info | grep -A2 Logmax-size 50m这个清单走完基本能覆盖 90% 的离线安装问题。剩下的 10% 通常是内核参数或者 SELinux 策略引起的需要看journalctl -u docker的具体报错。从那以后我每次进隔离机房之前都会在联网机器上把 RPM 包、二进制包、测试镜像和daemon.json模板打成一个目录校验值一起带上。到了现场先cat /etc/os-release确认发行版再决定走哪条安装路径装完按清单过一遍。这套流程在十几台不同配置的机器上跑下来没再出现过装到一半卡住的情况。希望帮到你。本文还有配套的精品资源点击获取