上一篇 下一篇 分享链接 返回 返回顶部

Docker 要不要升级?生产环境实测建议与配置文件参考

发布人:慈云数据-客服中心 发布时间:16小时前 阅读量:2

Docker 值得升级吗|附配置文件

在容器化已经成为后端开发、运维部署、微服务治理、CI/CD 流水线标配的今天,Docker 仍然是最常见、最容易上手的容器工具之一。很多团队在使用 Docker 时都会遇到一个问题:Docker 到底要不要升级?

有些人认为:“能跑就不要动,升级可能出问题。”
也有人认为:“新版本性能更好、安全性更高,应该及时升级。”

这两个观点都有道理。Docker 升级不是简单地执行一条命令,它涉及运行中的容器、镜像兼容性、网络配置、数据卷、日志驱动、Compose 文件版本、Linux 内核特性、CI/CD 环境等多个方面。如果升级前没有评估,确实可能导致服务异常;但如果长期不升级,也会积累安全风险、兼容性问题和维护成本。

本文将从实际生产环境角度,系统分析 Docker 是否值得升级、什么时候应该升级、什么时候不建议立即升级、升级前要检查什么、升级后如何验证,并附上一套常用 Docker 配置文件示例,方便直接参考。


一、Docker 为什么需要升级?

Docker 本质上是一个容器运行与管理平台,主要包括 Docker Engine、containerd、runc、Docker CLI、Docker Compose 等组件。每次版本更新通常会带来以下几类变化。


二、安全性:升级最重要的理由

如果你的 Docker 运行在生产服务器上,那么安全性应该是首要考虑因素。

Docker 依赖多个底层组件,例如:

  • containerd
  • runc
  • Linux namespace
  • cgroups
  • overlay2 文件系统
  • iptables / nftables
  • Docker daemon API

这些组件一旦出现高危漏洞,攻击者可能通过容器逃逸、权限提升、恶意镜像执行等方式影响宿主机安全。

例如历史上容器领域曾出现过一些比较严重的问题:

  • 容器逃逸漏洞
  • 镜像构建过程权限泄露
  • Docker API 未授权访问导致服务器被入侵
  • runc 漏洞导致攻击者可能突破容器边界
  • 旧版本 TLS、依赖库、网络模块存在安全风险

如果 Docker 版本长期停留在几年前,哪怕业务一直正常运行,也并不意味着环境安全。生产环境中,安全风险往往不是“会不会发生”,而是“发生时能不能承受”。

因此,如果当前版本存在已公开的高危漏洞,升级是非常值得的,甚至应当尽快安排。


三、稳定性:新版本不一定更不稳定

很多团队担心升级 Docker 后服务不可用,这种担心并非没有道理。但也不能因此认为旧版本一定更稳定。

旧版本 Docker 可能存在以下问题:

  • 某些情况下容器无法正常停止
  • 日志文件过大导致磁盘被打满
  • overlay2 存储异常
  • Docker daemon 偶发崩溃
  • Compose 与新语法不兼容
  • 新系统内核下运行旧 Docker 出现兼容问题
  • 镜像拉取、构建缓存、网络转发存在 bug

新版本通常会修复大量历史问题,尤其是与系统内核、文件系统、网络规则、BuildKit、Compose 插件相关的问题。

不过,稳定性并不是简单地由版本号决定,而是取决于:

  • 当前业务是否依赖某些旧行为
  • Docker 配置是否规范
  • 是否有灰度升级流程
  • 是否做好备份与回滚
  • 是否提前在测试环境验证

因此,正确的做法不是盲目升级,也不是永远不升级,而是:定期评估、测试验证、分批升级、保留回滚方案。


四、性能:升级可能带来明显收益

Docker 升级带来的性能提升并不是每次都很明显,但在某些场景下确实能改善体验。

常见收益包括:

  1. 镜像构建速度提升
    新版本 Docker 对 BuildKit 支持更完善,可以更好地利用缓存、并行构建、多阶段构建。

  2. 镜像拉取与推送更稳定
    对 registry 的兼容性更好,网络异常时的处理也更完善。

  3. 容器启动速度优化
    containerd、runc 等组件更新后,容器生命周期管理可能更高效。

  4. 日志处理能力增强
    如果配置了合适的日志驱动和日志轮转策略,可以减少磁盘压力。

  5. 资源限制更准确
    在 cgroups v2 的系统中,新版本 Docker 对 CPU、内存、IO 等资源限制支持更完整。

如果你的团队经常构建镜像、频繁发布、运行大量容器,或者正在使用较新的 Linux 发行版,那么升级 Docker 往往能带来更好的兼容性和性能表现。


五、功能特性:是否需要新能力?

Docker 的升级也可能是为了使用新功能。

例如:

  • 更完善的 BuildKit 支持
  • Docker Compose V2
  • 更好的多平台镜像构建支持
  • 更安全的默认配置
  • 对 cgroups v2 的增强支持
  • 对 rootless 模式的改进
  • 更好的镜像扫描与供应链安全能力
  • 更现代的插件机制
  • 对较新 Linux 发行版的兼容

如果你的项目仍然使用老旧的 docker-compose Python 版本工具,可能会发现很多新的 Compose 语法无法使用。现在 Docker 官方更推荐使用:

docker compose up -d

而不是:

docker-compose up -d

也就是说,Compose V2 已经成为主流选择。对于仍在旧版本生态里的团队,升级 Docker 往往可以顺便统一工具链,减少开发、测试、生产环境之间的差异。


六、什么时候 Docker 值得升级?

以下情况通常建议升级 Docker。

1. 当前版本存在安全漏洞

如果官方公告、Linux 发行版安全公告或安全扫描工具提示当前 Docker、containerd、runc 存在高危漏洞,应优先升级。

可以查看版本:

docker version
docker info
containerd --version
runc --version

2. 当前版本太旧

如果 Docker 已经多年未升级,例如还停留在 18.x、19.x、20.x 的早期版本,就应该认真考虑升级。

长期不升级的问题不只是缺功能,更重要的是:

  • 安全补丁缺失
  • 与新系统兼容性变差
  • 官方维护支持减少
  • 社区文档和实践逐渐不适配
  • 新工具链无法顺利接入

3. 操作系统准备升级

如果你准备从 CentOS 7 迁移到 Rocky Linux、AlmaLinux、Ubuntu 22.04 / 24.04、Debian 12 等较新的系统,那么 Docker 最好也同步升级到较新的稳定版本。

原因是新系统可能默认使用:

  • cgroups v2
  • nftables
  • 新版 systemd
  • 新版内核
  • 新版 iptables 兼容层

旧 Docker 在这些环境下可能出现兼容问题。


4. 使用 Docker Compose V2

如果项目需要使用较新的 Compose 语法,例如:

  • profiles
  • depends_on.condition
  • 更完整的 healthcheck
  • 多环境变量文件
  • 扩展字段
  • 更好的插件集成

那么升级 Docker 和 Compose 是合理选择。


5. 镜像构建效率成为瓶颈

如果你的 CI/CD 流水线经常花大量时间构建镜像,可以考虑升级 Docker 并启用 BuildKit。

例如:

DOCKER_BUILDKIT=1 docker build -t my-app:latest .

BuildKit 在缓存、并发、构建输出、secret 挂载、多阶段构建等方面都更优秀。


七、什么时候不建议立刻升级?

虽然 Docker 升级很重要,但下面这些情况不建议直接在生产环境执行升级。

1. 没有测试环境

如果生产环境是唯一环境,且没有任何备份、没有灰度机器、没有回滚方案,那么不要贸然升级。

正确做法是先准备至少一台测试服务器,模拟生产环境:

  • 相同操作系统
  • 相同 Docker 配置
  • 相同 Compose 文件
  • 相同镜像版本
  • 相同数据卷挂载方式
  • 相同网络结构

验证通过后再考虑生产升级。


2. 核心服务无法停机

Docker 升级通常会重启 Docker daemon。虽然容器进程在某些配置下可能不会立刻退出,但生产环境不能依赖这种不确定行为。

如果你的服务不能中断,需要:

  • 做多节点部署
  • 使用负载均衡摘流
  • 分批升级节点
  • 确认健康检查
  • 升级后再恢复流量

3. 依赖旧版 Docker 行为

部分旧项目可能依赖旧版本 Docker 或 Compose 的行为,例如:

  • 老版本 Compose 文件语法
  • 特定网络名称
  • 特定 volume 挂载行为
  • 旧版日志驱动参数
  • 自定义 iptables 规则
  • Swarm 或第三方插件

这类环境升级前一定要做兼容性测试。


4. 镜像和容器没有备份

虽然升级 Docker 通常不会删除镜像、容器和 volume,但任何生产变更都应该假设可能发生意外。

升级前至少需要备份:

  • 业务数据库
  • Docker volume 数据
  • Compose 配置
  • Docker daemon 配置
  • 自定义网络配置
  • 镜像版本清单

八、升级前检查清单

升级 Docker 前,建议按照下面清单逐项确认。

1. 查看当前版本

docker version
docker info
docker compose version
containerd --version
runc --version

2. 查看运行中的容器

docker ps

建议保存一份清单:

docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" > docker-containers.txt

3. 查看镜像列表

docker images

保存镜像版本:

docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}" > docker-images.txt

4. 查看数据卷

docker volume ls

查看某个 volume 详情:

docker volume inspect volume_name

5. 查看网络配置

docker network ls
docker network inspect bridge

6. 备份 Docker 配置

常见配置文件路径:

/etc/docker/daemon.json
/etc/systemd/system/docker.service.d/
/var/lib/docker/

其中 /var/lib/docker/ 是 Docker 默认数据目录,一般比较大,不一定适合整体备份,但至少需要确认重要数据是否在 volume 或宿主机目录中。


九、Docker 推荐配置文件:daemon.json

下面是一份比较常见、适合生产环境参考的 Docker daemon 配置文件。实际使用前请根据自己的服务器、网络和镜像仓库情况调整。

配置文件路径:

/etc/docker/daemon.json

示例配置:

{
  "data-root": "/data/docker",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
    "https://docker.m.daocloud.io"
  ],
  "insecure-registries": [],
  "live-restore": true,
  "default-address-pools": [
    {
      "base": "172.30.0.0/16",
      "size": 24
    }
  ],
  "features": {
    "buildkit": true
  }
}

十、配置项说明

1. data-root

"data-root": "/data/docker"

用于指定 Docker 数据目录。默认路径通常是:

/var/lib/docker

生产环境中,如果系统盘较小,建议将 Docker 数据目录放到独立磁盘,例如:

/data/docker

这样可以避免镜像、容器日志、volume 数据不断增长导致系统盘被打满。

注意:已有 Docker 环境修改 data-root 需要谨慎,不能简单改完就重启,否则 Docker 可能找不到原来的镜像和容器。需要提前迁移数据或在新环境初始化时配置。


2. log-driver 与 log-opts

"log-driver": "json-file",
"log-opts": {
  "max-size": "100m",
  "max-file": "3"
}

Docker 默认日志驱动通常是 json-file。如果不设置日志轮转,容器日志可能无限增长,最终占满磁盘。

这段配置表示:

  • 单个日志文件最大 100MB
  • 最多保留 3 个文件
  • 单个容器最多约 300MB 日志

对于生产环境非常重要。

如果你使用 ELK、Loki、Fluent Bit 等日志系统,也可以考虑使用其他日志方案,但无论哪种方式,都要避免日志无限增长。


3. storage-driver

"storage-driver": "overlay2"

overlay2 是当前 Linux 环境下最常用的 Docker 存储驱动,性能和稳定性都比较好。

一般不建议随意更改存储驱动,尤其是已有容器和镜像的服务器。存储驱动改变可能导致原有数据无法识别。


4. exec-opts

"exec-opts": ["native.cgroupdriver=systemd"]

在使用 systemd 的 Linux 发行版中,推荐让 Docker 使用 systemd 作为 cgroup 驱动,尤其是在 Kubernetes 环境中更常见。

这样可以减少 cgroup 管理方式不一致导致的问题。


5. registry-mirrors

"registry-mirrors": [
  "https://docker.m.daocloud.io"
]

镜像加速地址需要根据实际可用性选择。不同地区、不同时间可用性可能不同。

如果企业内部有私有镜像仓库,建议优先使用内部 registry,例如 Harbor。


6. live-restore

"live-restore": true

该配置允许 Docker daemon 重启时,尽量保持已有容器继续运行。

这对于升级 Docker、重启 Docker 服务时减少影响有帮助。但需要注意:

  • 它不是高可用方案
  • 不能保证所有场景都无中断
  • daemon 重启期间无法正常管理容器
  • 网络、日志、插件等仍可能受影响

所以生产环境仍然应该依赖负载均衡、集群和灰度升级,而不是只依赖 live-restore


7. default-address-pools

"default-address-pools": [
  {
    "base": "172.30.0.0/16",
    "size": 24
  }
]

这个配置用于指定 Docker 自动创建网络时使用的默认地址池。

如果公司内网已经大量使用 172.17.0.0/16172.18.0.0/16 等网段,Docker 默认 bridge 网络可能与现有网络冲突,导致容器访问内网服务异常。

提前规划 Docker 网络地址池,可以减少很多排查成本。


8. BuildKit

"features": {
  "buildkit": true
}

开启 BuildKit 可以改善镜像构建体验,尤其适合多阶段构建、缓存优化和 CI/CD 场景。


十一、修改配置后的操作步骤

修改 /etc/docker/daemon.json 后,需要检查 JSON 格式是否正确。

可以使用:

cat /etc/docker/daemon.json | jq .

如果没有安装 jq,也可以使用 Python 检查:

python3 -m json.tool /etc/docker/daemon.json

然后重新加载 systemd 配置并重启 Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

查看 Docker 状态:

sudo systemctl status docker

确认配置是否生效:

docker info

十二、Docker Compose 配置文件示例

下面提供一个比较通用的 docker-compose.yml 示例,包含 Nginx、应用服务和 Redis,适合中小型项目参考。

services:
  nginx:
    image: nginx:1.27-alpine
    container_name: demo-nginx
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./nginx/logs:/var/log/nginx
    depends_on:
      app:
        condition: service_healthy
    networks:
      - demo-net
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

  app:
    image: demo-app:latest
    container_name: demo-app
    restart: unless-stopped
    environment:
      TZ: Asia/Shanghai
      APP_ENV: production
      REDIS_HOST: redis
      REDIS_PORT: 6379
    expose:
      - "8080"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s
    networks:
      - demo-net
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

  redis:
    image: redis:7.4-alpine
    container_name: demo-redis
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis-data:/data
    networks:
      - demo-net
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

volumes:
  redis-data:

networks:
  demo-net:
    driver: bridge

十三、Compose 配置建议

1. 不建议使用 latest 作为生产镜像标签

示例中 demo-app:latest 只是演示。生产环境建议使用明确版本,例如:

image: demo-app:2025.01.15

这样可以保证回滚时有明确目标,避免不同时间拉取到不同镜像。


2. 配置 restart 策略

restart: unless-stopped

该配置可以在容器异常退出后自动重启,也可以在服务器重启后自动拉起服务。

常见策略:

  • no
  • always
  • unless-stopped
  • on-failure

生产环境中,unless-stopped 比较常用。


3. 配置 healthcheck

健康检查可以帮助判断容器内部服务是否真正可用,而不仅仅是进程是否存在。

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
  interval: 30s
  timeout: 5s
  retries: 3
  start_period: 20s

需要注意的是,镜像中必须包含 curl,否则健康检查会失败。如果镜像没有 curl,可以改用 wget 或自定义脚本。


4. 日志限制不要只依赖 daemon.json

虽然可以在 daemon.json 中配置全局日志策略,但在关键 Compose 服务中显式配置日志限制也很有必要,方便迁移和审计。


十四、升级 Docker 的推荐流程

下面是一套较稳妥的升级流程。

第一步:确认目标版本

不要盲目追最新版本,可以选择当前官方稳定版,或者发行版仓库中的稳定版本。

查看当前版本:

docker version

查看可安装版本:

apt-cache madison docker-ce

或在 RHEL 系系统中:

yum list docker-ce --showduplicates

第二步:备份配置和数据

备份配置:

sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak.$(date +%F)

备份 Compose 项目:

tar -czf compose-backup-$(date +%F).tar.gz /path/to/compose/project

导出镜像清单:

docker images --format "{{.Repository}}:{{.Tag}}" > images-list.txt

第三步:测试环境验证

在测试环境执行:

docker compose config
docker compose up -d
docker ps
docker logs container_name

检查:

  • 容器是否正常启动
  • 网络是否正常
  • 数据卷是否正常挂载
  • 日志是否正常输出
  • 健康检查是否通过
  • 应用功能是否正常

第四步:生产环境分批升级

如果是多台服务器,建议一台一台升级。

典型流程:

  1. 从负载均衡摘除一台节点
  2. 停止或迁移该节点流量
  3. 升级 Docker
  4. 重启服务
  5. 验证健康状态
  6. 加回负载均衡
  7. 继续下一台节点

第五步:升级后验证

升级完成后执行:

docker version
docker info
docker compose version
docker ps
docker network ls
docker volume ls

检查应用日志:

docker logs --tail=100 container_name

查看 Docker daemon 日志:

journalctl -u docker -n 200 --no-pager

十五、Ubuntu 上升级 Docker 示例

以下命令适用于通过 Docker 官方源安装的 Ubuntu 系统,仅供参考。

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

查看版本:

docker version
docker compose version

如果需要锁定版本,避免自动升级:

sudo apt-mark hold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

取消锁定:

sudo apt-mark unhold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

十六、CentOS / Rocky Linux / AlmaLinux 升级示例

sudo yum makecache
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

查看版本:

docker version
docker compose version

如果系统使用的是 dnf

sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

十七、如何回滚 Docker?

回滚取决于你的安装方式和系统包管理器。

如果是 Ubuntu,可以查看历史版本:

apt-cache madison docker-ce

安装指定版本:

sudo apt install docker-ce=版本号 docker-ce-cli=版本号 containerd.io

如果是 yum/dnf:

yum list docker-ce --showduplicates
sudo yum downgrade docker-ce docker-ce-cli containerd.io

但需要注意:Docker 降级不一定总是安全。因为新版本可能升级了元数据格式、网络状态或存储状态。回滚前必须确认数据兼容性。

更稳妥的回滚方式通常是:

  • 保留原服务器不动
  • 新服务器完成升级验证
  • 通过流量切换完成迁移
  • 出现问题切回旧服务器

这比在同一台机器上反复升级、降级更可靠。


十八、我的建议:Docker 值得升级,但不要裸奔升级

综合来看,Docker 是值得升级的,尤其是在以下前提下:

  • 当前版本较旧
  • 存在安全漏洞
  • 需要新功能
  • 操作系统已升级
  • CI/CD 构建效率低
  • 需要 Compose V2
  • 需要更好的 cgroups v2 支持

但升级的正确姿势不是“看到新版本就直接升级”,而是:

先评估,再测试;先备份,再升级;先灰度,再全量;先验证,再收尾。

对于个人开发环境,升级成本较低,可以相对积极一些。
对于生产环境,升级应该纳入变更流程,选择低峰期执行,并提前准备回滚方案。


十九、最终结论

Docker 值得升级,但是否“现在就升级”,取决于你的环境和风险承受能力。

如果你正在使用非常老的 Docker 版本,或者安全扫描已经提示漏洞,那么升级非常必要。
如果你的生产环境业务稳定,但没有测试环境、没有备份、没有回滚方案,那么不建议直接升级,而应该先补齐基础运维能力。
如果你希望获得更好的构建体验、Compose V2 支持、更好的系统兼容性和安全保障,那么升级 Docker 是一项长期收益明显的工作。

最后给出一句实用建议:

开发环境可以快速跟进,测试环境提前验证,生产环境稳定升级。Docker 不怕升级,怕的是没有准备地升级。

目录结构
全文