☰
Docker 24.0.5 内网离线安装实战:RPM与二进制部署及避坑指南
2026/10/18 9:37:43 网站建设 项目流程

简介:这份资源面向需要在无外网或内网环境中部署 Docker 的运维与开发人员,提供 Docker 24.0.5 的完整离线安装方案,解决服务器无法联网拉取依赖、安装过程反复报错的痛点。压缩包共 18 个文件,以 17 个 rpm 依赖包和 1 个 install_docker.sh 安装脚本为主,整体约 108.02MB,rpm 覆盖 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*.rpm

rpm -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 docker

daemon-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] Description=containerd container runtime Documentation=https://containerd.io After=network.target local-fs.target [Service] ExecStartPre=-/sbin/modprobe overlay ExecStart=/usr/bin/containerd Type=notify Delegate=yes KillMode=process Restart=always RestartSec=5 LimitNPROC=infinity LimitCORE=infinity LimitNOFILE=infinity TasksMax=infinity OOMScoreAdjust=-999 [Install] WantedBy=multi-user.target EOF # 4. 创建 docker.service cat > /etc/systemd/system/docker.service <<'EOF' [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target docker.socket firewalld.service containerd.service Wants=network-online.target Requires=docker.socket containerd.service [Service] Type=notify ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always StartLimitBurst=3 StartLimitInterval=60s LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TasksMax=infinity Delegate=yes KillMode=process OOMScoreAdjust=-500 [Install] WantedBy=multi-user.target EOF # 5. 重载并启动 systemctl daemon-reload systemctl start containerd systemctl start docker systemctl enable containerd docker

containerd.service里的ExecStartPre=-/sbin/modprobe overlay前面的减号表示即使这条命令失败也不影响后续启动,因为有些内核已经内置了 overlay 模块。Delegate=yes让 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 通常是 overlay2,Cgroup Driver 通常是 systemd # 第三层:运行一个测试容器 # 离线环境没有镜像,先从别处导入一个 busybox 镜像 docker load -i busybox.tar docker run --rm busybox echo "offline docker ok"

docker 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.cgroupdriver=systemd"],然后重启 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里有没有Group=docker。

4.4 现象:容器能跑但网络不通,ping 外部地址失败

原因:离线环境通常没有外网,但容器默认的 bridge 网络需要 iptables 的 NAT 规则。如果目标机器 iptables 规则被清空过,或者net.ipv4.ip_forward没开,容器出不去。

解决:检查两个地方:

# 确认 IP 转发已开启 sysctl net.ipv4.ip_forward # 如果输出是 0,临时开启 sysctl -w net.ipv4.ip_forward=1 # 永久生效写入 /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 -r,CentOS 7 需要 3.10.0-514 以上才支持 overlay2。然后加载模块:

modprobe overlay lsmod | grep overlay

如果模块加载失败,说明内核编译时没带 overlay,只能升级内核或者接受 vfs。在/etc/docker/daemon.json里可以显式指定驱动:

{ "storage-driver": "overlay2", "exec-opts": ["native.cgroupdriver=systemd"] }

改完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 nginx

docker 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.cgroupdriver=systemd"], "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后必须重启 Docker:

systemctl 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 Storageoverlay2
Cgroup 驱动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确认发行版,再决定走哪条安装路径,装完按清单过一遍。这套流程在十几台不同配置的机器上跑下来,没再出现过装到一半卡住的情况。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询