Docker 进阶篇(一) CentOS 7 离线升级 Docker 完整实战

CentOS 7 离线升级 Docker 19.x → 26.1.4 完整实战

------ 从源失效、依赖缺失到 daemon 起不来的排坑全过程

环境:本地 CentOS 7 服务器 · 目标版本 Docker Engine 26.1.4

一、背景与目标

本文记录在本地 CentOS 7 服务器上将 Docker 从 19.x 升级到 26.1.4 的全过程。原以为是一条简单的 yum update,实际却接连踩到三个大坑:

CentOS 7 已于 2024-06-30 停止维护(EOL),官方 mirrorlist 下线,yum 源全面 404;

Docker 26 的 rootless 依赖(slirp4netns、fuse-overlayfs)在失效源里装不到;

daemon.json 里用了废弃字段 graph,导致 dockerd 启动直接报错。

最终采用「绕过 yum、离线 RPM 直装 + 修复配置」的组合方案,干净落地。目标读者是遇到类似升级困境的运维同学。

1.1 环境说明

项目 说明
操作系统 CentOS 7.7(旧),最终对齐 7.9.2009 归档
升级前版本 Docker CE 19.03.x
升级后版本 Docker Engine 26.1.4(build 5650f9b)
网络环境 本地服务器,可访问阿里云镜像站
部署场景 自建 CentOS 服务器(非阿里云 ECS)

二、升级前准备

2.1 确认当前环境

升级前务必先摸清家底,避免盲目操作:

bash 复制代码
cat /etc/centos-release    # 确认 CentOS 版本
docker --version             # 确认当前 Docker 版本
rpm -qa | grep docker        # 查看已安装的 docker 相关包

2.2 备份数据(重要)

跨大版本升级有风险,先备份镜像与数据目录:

bash 复制代码
docker stop $(docker ps -q)   # 停掉所有运行中的容器
docker images | awk 'NR>1{print $1":"$2}' | while read img; do
  docker save "$img" -o "/backup/${img//\//_}.tar"
done
tar -czf /backup/docker-data-$(date +%Y%m%d).tar.gz /var/lib/docker
bash 复制代码
注意:若确定不再保留旧数据,可执行 rm -rf /var/lib/docker 清空,本文后续会重新初始化。

三、卸载旧版 Docker

停止并卸载旧版 Docker CE。部分旧包名可能不存在,属正常现象:

bash 复制代码
sudo systemctl stop docker
sudo yum remove -y docker-ce docker-ce-cli containerd.io \
    docker docker-client docker-common docker-engine

此时可能遇到 yum 源 404 报错------这正是 CentOS 7 EOL 导致,不影响卸载本身,yum 会跳过网络源直接处理本地包。

bash 复制代码
提示:yum remove 不会删除 /var/lib/docker 里的镜像与容器数据;如需彻底重装再清空,务必先备份。

四、修复 CentOS 7 yum 源(踩坑重点)

4.1 问题现象

执行 yum 安装时大量报错:

bash 复制代码
http://mirrors.*/centos/7.7.1908/.../repomd.xml: [Errno 14] HTTP Error 404
Could not retrieve mirrorlist http://mirrorlist.centos.org/...

根本原因:CentOS 7 EOL 后官方镜像列表服务下线,且旧配置里 $releasever 仍指向已删除的 7.7.1908 路径。

4.2 清空旧源,配置 Vault 归档源

关键点:必须把 /etc/yum.repos.d/ 下所有旧 .repo 文件彻底移走,只保留一个干净的 Vault 源,否则新旧源冲突会出现 "Repository listed more than once"。

bash 复制代码
mkdir -p /etc/yum.repos.d/bak
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/ 2>/dev/null
mkdir -p /etc/yum.repos.d

写入阿里云 Vault 7.9.2009 归档源(国内访问快,路径永久保留):

bash 复制代码
cat > /etc/yum.repos.d/CentOS-Vault.repo << 'EOF'
[base]
name=CentOS-7.9.2009 - Base
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/os/$basearch/
gpgcheck=0
enabled=1
 
[updates]
name=CentOS-7.9.2009 - Updates
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/updates/$basearch/
gpgcheck=0
enabled=1
 
[extras]
name=CentOS-7.9.2009 - Extras
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/extras/$basearch/
gpgcheck=0
enabled=1
EOF

4.3 禁用 fastestmirror + 强制 IPv4

日志里大量 IPv6「网络不可达」,需禁用 fastestmirror 插件并强制走 IPv4:

bash 复制代码
sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf 2>/dev/null
grep -q 'ip_resolve=4' /etc/yum.conf || echo 'ip_resolve=4' >> /etc/yum.conf

4.4 重建缓存并验证

bash 复制代码
yum clean all
rm -rf /var/cache/yum
yum makecache
yum repolist

成功的标志是 yum repolist 各仓库状态不再为 0。若仍报错,确认 /etc/yum.repos.d/ 下只有 CentOS-Vault.repo 与后续添加的 docker-ce.repo。

五、通过 yum 安装 Docker 26.1.4

yum 源修复后(第四章已验证 yum repolist 状态非 0),即可直接通过 yum 安装指定版本的 Docker。这也是本文最终采用的主方案。

5.1 添加 Docker CE 源

Docker 官方源在国内访问不稳定,这里继续使用阿里云镜像站的 Docker CE 源:

bash 复制代码
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

添加后会在 /etc/yum.repos.d/ 下生成 docker-ce.repo,其中包含 docker-ce-stable 等仓库。可用以下命令确认目标版本存在:

bash 复制代码
yum list docker-ce --showduplicates | grep 26.1.4
# 应能看到:docker-ce.x86_64  3:26.1.4-1.el7  docker-ce-stable

5.2 先安装 rootless 依赖

Docker 26.1.4 的 docker-ce-rootless-extras 子包要求 slirp4netns >= 0.4fuse-overlayfs >= 0.7,这两个包来自 extras 仓库,需先安装(这正是第四章必须把 extras 源修好的原因):

bash 复制代码
yum install -y slirp4netns fuse-overlayfs container-selinux

5.3 安装指定版本 Docker 26.1.4

bash 复制代码
yum install -y docker-ce-26.1.4 docker-ce-cli-26.1.4 containerd.io

安装过程中 yum 会自动把配套包一起装上,例如:

复制代码
作为依赖被安装:
  container-selinux.noarch 2:2.119.2-1.911c772.el7_8
  containerd.io.x86_64 0:1.6.33-3.1.el7
  docker-buildx-plugin.x86_64 0:0.14.1-1.el7
  docker-ce-rootless-extras.x86_64 0:26.1.4-1.el7
  docker-compose-plugin.x86_64 0:2.27.1-1.el7
  fuse-overlayfs.x86_64 0:0.7.2-6.el7_8
  slirp4netns.x86_64 0:0.4.3-4.el7_8

注意:必须锁定版本号 26.1.4,否则 yum install docker-ce 会装成仓库里的最新版(如 28.x),可能与 CentOS 7 内核不兼容。

5.4 启动并验证

bash 复制代码
systemctl daemon-reload
systemctl enable --now docker
docker --version   # 应输出:Docker version 26.1.4, build 5650f9b
docker run hello-world

备选说明:若某些极端环境下 yum 源确实无法修复,也可采用「下载 RPM 包 + rpm -ivh --nodeps --force」的离线方式作为兜底,步骤见文末附录。但正常情况下推荐本节的 yum 方式,便于后续跟随仓库自动更新。

六、修复 daemon.json(踩坑重点)

6.1 问题现象

执行 /usr/bin/dockerd --debug 直接报错:

bash 复制代码
unable to configure the Docker daemon with file /etc/docker/daemon.json:
the following directives don't match any configuration option: graph

6.2 根因与修复

graph 字段在 Docker 17.05 之后已被废弃并移除,新版 dockerd 读到未识别字段直接拒绝启动,必须改用 data-root。原始配置(含加速器、日志、私有仓库)如下:

bash 复制代码
{
  "registry-mirrors": ["https://7e2zsv7s.mirror.aliyuncs.com"],
  "graph": "/home/docker",
  "log-driver": "json-file",
  "log-opts": { "max-size": "500m", "max-file": "3" },
  "insecure-registries": ["42.123.65.126:5000"]
}

只需把 graph 改为 data-root,其余配置全部保留(均为 26.x 合法字段):

bash 复制代码
cat > /etc/docker/daemon.json << 'EOF'
{
  "registry-mirrors": ["https://7e2zsv7s.mirror.aliyuncs.com"],
  "data-root": "/home/docker",
  "log-driver": "json-file",
  "log-opts": { "max-size": "500m", "max-file": "3" },
  "insecure-registries": ["42.123.65.126:5000"]
}
EOF
旧配置 (≤ 17.04) 新配置 (≥ 17.05,含 26.1.4)
"graph": "/path" "data-root": "/path"

6.3 确保数据目录存在

bash 复制代码
mkdir -p /home/docker
chown -R root:root /home/docker
chmod 711 /home/docker

6.4 启动验证

bash 复制代码
systemctl restart docker
systemctl status docker        # 应显示 active (running)
docker info | grep "Docker Root Dir"  # 应输出 /home/docker

七、配置镜像加速器

升级后拉取 nginx 仍可能超时(registry-1.docker.io 在国内不稳定),配置国内加速源即可。在 daemon.json 中追加 registry-mirrors:

bash 复制代码
{
  "registry-mirrors": [
    "https://docker.xuanyuan.me",
    "https://docker.1ms.run",
    "https://docker.m.daocloud.io"
  ],
  "data-root": "/home/docker"
}

重启后验证拉取:

bash 复制代码
systemctl restart docker
docker pull nginx:latest
docker run --rm --entrypoint nginx nginx:latest -v
# 输出:nginx version: nginx/1.31.4

八、设置开机自启

bash 复制代码
systemctl enable docker          # 设置开机自启
systemctl enable --now docker   # 启用并立即启动
systemctl is-enabled docker     # 输出 enabled 即成功
systemctl enable containerd     # Docker 依赖 containerd,一并设置

九、完整操作流程速查

备份旧镜像与数据目录;

卸载旧版 Docker(yum remove);

清空 /etc/yum.repos.d/ 旧源,写入阿里云 Vault 7.9.2009 归档源;

禁用 fastestmirror、强制 IPv4,重建 yum 缓存;

下载 Docker 26.1.4 及依赖 RPM 包,rpm -ivh --nodeps --force 安装;

修正 daemon.json:graph → data-root,确保 /home/docker 存在;

systemctl enable --now docker,docker --version 验证;

配置 registry-mirrors 加速器,docker pull nginx 测试;

systemctl enable docker 设置开机自启。

十、常见问题排查

问题现象 解决方案
yum 报 404 / mirrorlist 不可达 CentOS 7 EOL,改用 Vault 归档源,清空旧 .repo
Repository listed more than once /etc/yum.repos.d/ 存在多个冲突源,只保留一个
IPv6 网络不可达 yum.conf 加 ip_resolve=4,禁用 fastestmirror
需要 slirp4netns >= 0.4 等依赖 从 vault extras 装满足版本的依赖包
dockerd 报 graph 未知字段 daemon.json 中 graph 改为 data-root
Docker daemon 起不来 journalctl -u docker 看日志,检查 containerd 与 daemon.json
生产环境版本选择 CentOS 7 建议锁定 24/26 LTS,规划迁移至 Rocky/Alma

10.1 查看 dockerd 详细报错

bash 复制代码
journalctl -u docker.service -n 100 --no-pager
/usr/bin/dockerd --debug   # 前台启动看实时错误

十一、小结

CentOS 7 升级 Docker 的核心难点并不在 Docker 本身,而在于系统已 EOL 带来的连锁反应:yum 源失效 → 依赖装不上 → 再加上历史配置里的废弃字段,才构成了这次升级的主要障碍。掌握「Vault 归档源 + 离线 RPM + 配置迁移」这套组合拳后,同类问题都能从容应对。

相关推荐
雾隐隐o2 小时前
Docker Compose 多容器编排实战
运维·docker·容器
IT大白鼠2 小时前
Kubernetes 核心资源ReplicaSet 控制器详解
云原生·容器·kubernetes
梦之美丽生活3 小时前
【本地部署及docker部署】yolov8_detect
yolo·docker·容器
^酸酸4 小时前
Kubernetes 运维实战:临时容器、端口转发与资源管理详解
运维·容器·kubernetes
奇特認4 小时前
kubernetes 微服务
微服务·容器·kubernetes
UseLessQQ5 小时前
云原生 kubernetes 中的service
云原生·容器·kubernetes
毕竟是shy哥5 小时前
windows电脑WSL下本地构建docker镜像
windows·docker·容器
小灰灰搞电子7 小时前
Rust 相关容器(集合)详解
开发语言·容器·rust
上学的小垃圾13 小时前
基于docker安装MySQL(openEuler系统)
linux·mysql·docker·容器