简介:本资源是一套专为CentOS 7系统离线部署Docker环境准备的完整RPM软件包集合,面向Linux系统运维人员、容器技术初学者及受限网络环境下的企业IT工程师,解决无外网YUM源时无法直接安装Docker及其依赖组件的核心痛点。压缩包共16个文件,包含9个核心RPM包(如docker-1.12.6、docker-client、docker-common、container-selinux、oci-systemd-hook等)、3个.gz格式元数据文件(primary.xml.gz、filelists.xml.gz、other.xml.gz)用于构建本地YUM仓库,以及3个.bz2索引文件和1个repomd.xml仓库描述文件,整体大小19.27MB,结构符合标准RPM仓库规范。已有382人学习下载,用户可直接解压后通过createrepo命令快速搭建本地Docker安装源,免去逐一手动下载依赖的繁琐过程,并获得完整兼容CentOS 7的Docker 1.12.6版本运行栈,含容器管理、镜像操作、SELinux集成与OCI运行时支持等关键能力。
1. Docker RPM 包离线安装:别急着yum install docker,CentOS 7 上装错版本可能连dockerd都起不来
你手头刚拿到一个叫docker.rpm.tar的压缩包,解压后是十几个.rpm文件,心里想着“不就是装个 Docker 吗?rpm -ivh *.rpm一把梭?”——我去年在某高校实验室部署容器平台时就这么干过,结果systemctl start docker报错Failed to start docker.service: Unit not found,查了两小时才发现:tar 包里混着docker-ce-cli-20.10.24和containerd.io-1.6.32,但主包却是docker-ce-24.0.7,三者 ABI 不兼容,dockerd进程一启动就 core dump。这不是玄学,是 RPM 依赖树没对齐的硬伤。这套docker.rpm.tar明显是为离线环境打包的完整依赖集,常见于政企内网、金融测试区、教育专网等无法直连download.docker.com的场景。它不面向新手一键安装,而是给运维/部署工程师准备的「可控交付单元」:版本锁定、无网络依赖、可审计、可复刻。如果你正卡在「Docker 怎么离线安装」「docker-ce 和 docker-ce-cli 版本怎么配」「containerd.io 装哪个才不翻车」,这篇就是为你写的血泪验证笔记。
2. 解包与环境校验:先看清 tar 包里到底有啥,再决定装不装
2.1 解压并列出所有 RPM 文件(带版本号和架构)
拿到docker.rpm.tar,别急着装。先确认它是否真包含完整依赖链。用以下命令解压并结构化查看:
# 创建专用工作目录,避免污染当前路径 mkdir -p /tmp/docker-rpm-install && cd /tmp/docker-rpm-install # 解压 tar 包(注意:不是 .tar.gz,是纯 tar) tar -xf ~/Downloads/docker.rpm.tar # 列出所有 RPM,按名称排序,并提取关键字段:包名、版本、架构 for rpm in *.rpm; do rpm -qpi "$rpm" 2>/dev/null | \ awk -F': ' '/^Name:/ {name=$2} /^Version:/ {ver=$2} /^Architecture:/ {arch=$2} END {printf "%-30s %s-%s.%s\n", name, name, ver, arch}' done | sort提示:输出应类似:
containerd.io containerd.io-1.6.32-3.1.el7.x86_64 docker-ce docker-ce-24.0.7-1.el7.x86_64 docker-ce-cli docker-ce-cli-24.0.7-1.el7.x86_64 docker-ce-rootless-extras docker-ce-rootless-extras-24.0.7-1.el7.x86_64 docker-scan-plugin docker-scan-plugin-0.27.0-1.el7.x86_64
重点核对三点:
- 所有包
Name前缀是否统一为docker-ce*或containerd.io(排除混入docker-engine等旧分支); docker-ce与docker-ce-cli的主版本号(如24.0.7)是否完全一致(必须一致,否则docker命令调用dockerd会报client version mismatch);- 架构是否为
x86_64(CentOS 7 默认)或aarch64(ARM 服务器),与你的系统uname -m输出严格匹配。
2.2 校验目标系统基础环境(OS 版本、内核、cgroup)
离线安装最怕「包能装上,服务起不来」。先执行三行命令锁死底线:
# 1. 确认 OS 是 CentOS 7(非 CentOS 8+,因 el7 与 el8 RPM 不兼容) cat /etc/centos-release # 应输出类似 "CentOS Linux release 7.9.2009 (Core)" # 2. 确认内核 ≥ 3.10(Docker 最低要求),且启用 overlay2(推荐存储驱动) uname -r # 如 3.10.0-1160.el7.x86_64 ✅ grep -i overlay /proc/filesystems # 应有 "nodev overlay" 行 ✅ # 3. 确认 systemd 版本 ≥ 219(CentOS 7.9 自带 219,7.2 是 219,7.0 是 208 ❌) systemctl --version | head -1 # 输出 "systemd 219" 或更高 ✅参数说明:
overlay2是 Docker 官方推荐的存储驱动,比devicemapper更稳定、性能更好。若grep无输出,需升级内核或重装系统(CentOS 7.6+ 默认启用);systemd 219是dockerd使用--containerd参数连接外部 containerd 的最低门槛,低于此版本会报unknown service type错误;- 若系统是 CentOS 7.0–7.5,强烈建议先
yum update kernel* systemd升级到 7.9 再操作,否则后续 90% 概率失败。
2.3 检查现有 Docker 是否残留(防止冲突)
很多机器之前用curl get.docker.com装过,或手动编译过,残留配置会干扰 RPM 安装:
# 查看是否已安装任何 docker 相关包 rpm -qa | grep -E 'docker|containerd|runc' # 查看 docker 相关进程和服务状态 ps aux | grep -E '(dockerd|containerd)' | grep -v grep systemctl list-unit-files | grep docker # 清理(仅当确认要全新安装时执行) sudo systemctl stop docker docker.socket containerd sudo systemctl disable docker docker.socket containerd sudo rpm -e $(rpm -qa | grep -E 'docker|containerd|runc') --nodeps 2>/dev/null || true sudo rm -rf /var/lib/docker /var/run/docker.sock /etc/docker逻辑说明:
--nodeps是必须的,因为离线 RPM 包里docker-ce依赖containerd.io,而rpm -e默认会检查依赖关系,导致卸载失败。我们宁可清空再装,也不留半残配置。
3. RPM 安装顺序与依赖解析:为什么不能rpm -ivh *.rpm
3.1 必须按依赖拓扑顺序安装(非字母序)
RPM 包之间存在强依赖:docker-ce→docker-ce-cli→containerd.io→runc。若顺序错,rpm -ivh会直接报Failed dependencies并退出。正确顺序如下(按rpm -qpR实际解析):
| 安装顺序 | RPM 包名(示例) | 依赖说明 |
|---|---|---|
| 1 | containerd.io-1.6.32-3.1.el7.x86_64.rpm | 提供containerd二进制及 socket,被docker-ce调用 |
| 2 | runc-1.1.12-1.el7.x86_64.rpm | containerd.io的底层运行时,必须先于 containerd |
| 3 | docker-ce-cli-24.0.7-1.el7.x86_64.rpm | docker命令行工具,依赖containerd.io |
| 4 | docker-ce-24.0.7-1.el7.x86_64.rpm | dockerd主服务,依赖docker-ce-cli和containerd.io |
| 5 | docker-ce-rootless-extras-24.0.7-1.el7.x86_64.rpm | 可选,仅当需 rootless 模式时安装 |
为什么 runc 在 containerd 之前?
containerd.ioRPM 的Requires: runc是硬依赖,rpm -ivh会校验。虽然runc本身无外部依赖,但若后装,containerd.io安装会失败。这是 RPM 数据库的原子性要求。
3.2 逐个安装并验证签名(防篡改)
使用rpm -ivh --force --nodeps是危险操作,会跳过依赖检查,导致运行时崩溃。正确做法是分步安装 + 强制依赖校验:
# 步骤 1:安装 containerd.io(它依赖 runc,所以先装 runc) sudo rpm -ivh runc-1.1.12-1.el7.x86_64.rpm sudo rpm -ivh containerd.io-1.6.32-3.1.el7.x86_64.rpm # 步骤 2:安装 CLI 工具(它不依赖 docker-ce,但依赖 containerd.io) sudo rpm -ivh docker-ce-cli-24.0.7-1.el7.x86_64.rpm # 步骤 3:安装主服务(它依赖前两者) sudo rpm -ivh docker-ce-24.0.7-1.el7.x86_64.rpm # 步骤 4:验证所有包是否注册进 RPM 数据库 rpm -qa | grep -E 'docker|containerd|runc' | sort # 应输出全部 4 个包名(不含 .rpm 后缀)参数说明:
rpm -ivh中i=install,v=verbose,h=hash(显示安装进度条),不加--force或--nodeps;- 若某步报
Failed dependencies: xxx is needed by yyy,说明你漏装了前置包,回退一步检查;--force仅在极特殊场景(如覆盖旧配置文件)使用,此处严禁。
3.3 验证 RPM 安装后文件落地位置
安装完成后,关键二进制和配置路径必须存在,这是后续启动的基础:
# 检查二进制是否存在且可执行 ls -l /usr/bin/docker /usr/bin/dockerd /usr/bin/containerd /usr/bin/runc # 应全为 `-rwxr-xr-x` 权限,大小 > 10MB(dockerd 通常 40MB+) # 检查 systemd 服务文件是否生成 ls -l /usr/lib/systemd/system/docker.service /usr/lib/systemd/system/containerd.service # 应存在,且 `docker.service` 中 `ExecStart=` 指向 `/usr/bin/dockerd` # 检查默认配置目录 ls -l /etc/docker/daemon.json # 可能不存在(首次安装),但目录必须存在 sudo mkdir -p /etc/docker逻辑说明:
/usr/bin/dockerd是 Docker Engine 主进程,docker.service就是它的 systemd 封装;/usr/lib/systemd/system/docker.service是 RPM 包自带的服务定义,不要手动创建,否则版本不匹配;daemon.json是可选配置文件,首次安装为空,我们稍后会写入生产级配置。
4. 配置与启动:从dockerd启动失败到docker info成功
4.1 编辑/etc/docker/daemon.json(生产环境必备)
默认配置不启用overlay2、不设镜像加速、不限制资源,线上必改。创建安全、稳定的配置:
{ "storage-driver": "overlay2", "storage-opts": ["overlay2.override_kernel_check=true"], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "live-restore": true, "default-ulimits": { "nofile": { "Name": "nofile", "Hard": 65536, "Soft": 65536 } } }参数说明:
"storage-driver": "overlay2":强制使用 overlay2,避免 fallback 到 devicemapper(后者在 CentOS 7 上易出 inode 耗尽);"overlay2.override_kernel_check=true":绕过内核版本检查(CentOS 7.9 内核 3.10 支持 overlay2,但 Docker 有时误判);"live-restore": true:允许 Docker daemon 重启时容器不停机(高可用必需);"default-ulimits":提升单容器文件描述符上限,防Too many open files错误。
保存后,重载 systemd 配置:
sudo systemctl daemon-reload4.2 启动 containerd(Docker 的底层守护进程)
dockerd启动前必须确保containerd已运行,否则报connection refused:
# 启动并设开机自启 sudo systemctl enable containerd sudo systemctl start containerd # 验证状态(必须 active (running)) sudo systemctl status containerd --no-pager -l | head -10 # 关键行:`Active: active (running)` ✅ # 检查 containerd socket 是否监听 sudo ss -tuln | grep :0 # 应看到 `u_str` 类型的 `/run/containerd/containerd.sock`注意:
containerd是独立守护进程,不是dockerd的子进程。dockerd通过 Unix socket/run/containerd/containerd.sock与之通信。若 socket 不存在,dockerd启动必败。
4.3 启动 dockerd 并排查典型失败
现在启动主服务:
sudo systemctl enable docker sudo systemctl start docker如果失败,按此顺序排查:
# 1. 查看最近 20 行日志(最直接) sudo journalctl -u docker -n 20 --no-pager # 2. 若日志显示 "failed to load listeners: no sockets found",检查 selinux sudo sestatus # 若为 enforcing,临时设 permissive 测试 sudo setenforce 0 sudo systemctl start docker # 成功则需调整 selinux 策略 # 3. 若日志含 "graphdriver failed",检查 overlay2 内核支持 sudo modprobe overlay echo $? # 应为 0 lsmod | grep overlay # 应有输出 # 4. 若报 "port already allocated",检查 2375/2376 端口占用 sudo ss -tuln | grep ':237[56]'逻辑说明:
journalctl -u docker是第一排查入口,90% 问题在此暴露;- SELinux 是 CentOS 7 离线环境最大黑匣子,
setenforce 0是快速验证手段(生产环境需用semanage port -a -t docker_port_t -p tcp 2375永久放行);modprobe overlay是加载内核模块,若失败需确认内核是否支持(zcat /proc/config.gz | grep OVERLAY_FS)。
5. 避坑指南:5 个真实踩过的坑与后悔药
5.1 现象:systemctl start docker无响应,journalctl显示dockerd: command not found
原因:docker-ceRPM 安装时,/usr/bin/dockerd文件权限被错误设置为600(只读),而非755。这是某些定制 RPM 打包脚本的 bug。
解决:
sudo chmod 755 /usr/bin/dockerd sudo systemctl start docker5.2 现象:docker info报错Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
原因:docker.service文件中ExecStart=指向了/usr/bin/dockerd-current(旧版路径),但 RPM 安装的是/usr/bin/dockerd。
解决:
# 编辑服务文件,修正路径 sudo sed -i 's|/usr/bin/dockerd-current|/usr/bin/dockerd|g' /usr/lib/systemd/system/docker.service sudo systemctl daemon-reload sudo systemctl restart docker5.3 现象:docker run hello-world拉取镜像超时,journalctl显示Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection
原因:离线环境未配置镜像仓库(registry mirror),且dockerd默认直连registry-1.docker.io(不可达)。
解决:
在/etc/docker/daemon.json中添加 registry mirrors(需内网已有 Harbor 或 Nexus):
"registry-mirrors": ["https://your-mirror.internal:5000"]然后sudo systemctl restart docker。
5.4 现象:docker ps返回空,但docker info正常,journalctl有level=error msg="failed to mount overlay",upperdirnot exist`
原因:/var/lib/docker/overlay2目录属主不是root:root,或磁盘空间不足(df -h /var/lib/docker< 1GB)。
解决:
sudo chown -R root:root /var/lib/docker sudo systemctl restart docker # 若磁盘不足,清理旧镜像:`docker system prune -a -f`5.5 现象:docker version显示 client 24.0.7,server 20.10.24,报client version mismatch
原因:docker-ce-cli和docker-ceRPM 版本号不一致(如 tar 包混入不同版本)。
解决:
# 卸载全部,重新按顺序安装同版本包 sudo rpm -e docker-ce docker-ce-cli containerd.io runc --nodeps # 严格按 24.0.7 全套重装(从 tar 包中精确筛选) sudo rpm -ivh runc-1.1.12-1.el7.x86_64.rpm \ containerd.io-1.6.32-3.1.el7.x86_64.rpm \ docker-ce-cli-24.0.7-1.el7.x86_64.rpm \ docker-ce-24.0.7-1.el7.x86_64.rpm6. 验证与压测:从hello-world到 100 容器并发启动
6.1 基础功能验证(5 步走完)
执行以下命令,每步成功才算真正装通:
# 1. 检查 daemon 是否健康 sudo systemctl is-active docker # 应输出 "active" # 2. 检查 client/server 版本一致 docker version --format '{{.Server.Version}} {{.Client.Version}}' # 应输出 "24.0.7 24.0.7" # 3. 拉取并运行最小镜像(不联网,用本地缓存) docker run --rm hello-world # 输出 "Hello from Docker!" ✅ # 4. 检查存储驱动 docker info | grep "Storage Driver" # 应输出 "Storage Driver: overlay2" # 5. 检查网络模式 docker network ls | grep bridge # 应有 "bridge" 网络,状态 "local"技巧:
docker run --rm hello-world是黄金验证命令。它不依赖外网(镜像内置),不写磁盘(--rm自动清理),5 秒内完成。失败即代表核心链路断裂。
6.2 生产级压力验证(模拟真实负载)
光跑通hello-world不够。我一般会用以下脚本验证高并发稳定性:
#!/bin/bash # save as /tmp/docker-stress.sh echo "Starting 100 nginx containers..." for i in $(seq 1 100); do docker run -d --name stress-$i -p $((8080+i)):80 nginx:alpine >/dev/null 2>&1 & done wait echo "Waiting 30s for containers to stabilize..." sleep 30 # 统计运行中容器数 RUNNING=$(docker ps --filter "status=running" --format "{{.Names}}" | wc -l) echo "Running containers: $RUNNING / 100" # 检查是否有崩溃 CRASHED=$(docker ps --filter "status=exited" --format "{{.Names}}" | wc -l) if [ "$CRASHED" -gt 0 ]; then echo "⚠️ $CRASHED containers crashed!" docker ps --filter "status=exited" --format "ID: {{.ID}} Name: {{.Names}}" fi # 清理 docker rm -f $(docker ps -aq) >/dev/null执行与观察:
chmod +x /tmp/docker-stress.sh sudo /tmp/docker-stress.sh
- 正常应输出
Running containers: 100 / 100;- 若
CRASHED > 0,大概率是overlay2inode 耗尽或内存不足(dmesg | grep -i "out of memory");- 此脚本模拟了真实业务中批量启停容器的场景,比单容器验证更可靠。
6.3 长期运行监控项(上线前必查)
装完不是终点,以下是上线前我必盯的 4 个指标:
| 监控项 | 检查命令 | 合格标准 | 不合格后果 |
|---|---|---|---|
| Docker daemon 内存占用 | `ps aux --sort=-%mem | grep dockerd | head -1` |
| overlay2 inode 使用率 | df -i /var/lib/docker/overlay2 | Used% < 85% | 新建容器失败,报no space left on device |
| containerd socket 响应 | sudo timeout 5 ctr -n moby containers list >/dev/null && echo OK | 输出OK | dockerd无法调度容器 |
| Docker 日志轮转 | ls -lh /var/log/docker.log* | 最大单个 < 10MB,总数 ≤ 3 | 日志撑爆磁盘 |
我的习惯:从那以后我每次部署
docker.rpm.tar,都强制走一遍这 4 项检查,再发给 QA。哪怕多花 3 分钟,也比半夜被 call 起来救火强。
希望帮到你。
本文还有配套的精品资源,点击获取