Docker 启动顺序优化(CentOS / Ubuntu)

一、问题背景

在 CentOS、Ubuntu 等 Linux 服务器上,Docker 可能在系统网络尚未完全就绪时启动,导致容器网络初始化或端口映射出现异常。

通过 systemd 配置,可以让 Docker 在网络达到 network-online.target 之后启动,降低开机阶段出现网络竞态的概率。

适用范围 :本方案主要优化服务器开机时的 Docker 启动顺序;并不能保证网络服务在运行期间重启后,Docker 会自动恢复失效的端口映射。

二、配置 Docker 启动顺序

1. 创建 systemd 覆盖配置

CentOS / Ubuntu 通用:

复制代码
sudo systemctl edit docker.service

在打开的编辑器中加入:

ini 复制代码
[Unit]
Wants=network-online.target
After=network-online.target
After=firewalld.service

配置说明:

配置项 作用
Wants=network-online.target Docker 启动时,尝试拉起网络就绪目标。
After=network-online.target 规定 Docker 必须排在网络就绪目标之后启动。
After=firewalld.service 如果 firewalld.service 也在启动事务中,则让 Docker 排在它后面启动。

注意:

  • After= 只定义启动先后顺序,不会主动启动所指定的服务。因此,After=firewalld.service 不等于启用或启动 firewalld。
  • Ubuntu 常见防火墙管理工具为 UFW,通常没有运行 firewalld.service;这一行在没有该服务时可以省略。
  • network-online.target 是否确实等待网络就绪,取决于对应的等待服务是否正确配置,如 NetworkManager-wait-online.service 或 systemd-networkd-wait-online.service。
  • 建议使用 systemctl edit 添加 drop-in 配置,不要直接修改系统自带的 /usr/lib/systemd/system/docker.service 或 /lib/systemd/system/docker.service。

2. 重新加载 systemd 配置

复制代码
sudo systemctl daemon-reload

新配置将在 Docker 下一次启动时生效。可以在合适的维护窗口重启 Docker 以验证配置:

复制代码
sudo systemctl restart docker

注意:重启 Docker 可能中断正在运行的容器或其网络连接,生产环境应安排维护窗口。

三、验证配置是否生效

1. 查看完整 unit 配置

bash 复制代码
systemctl cat docker.service

检查输出中是否包含新增的 drop-in 内容。

2. 查看依赖及启动顺序

css 复制代码
systemctl show docker.service -p After -p Wants

确认 After 中包含 network-online.target,Wants 中包含 network-online.target。

3. 检查网络等待服务(按实际网络管理方式)

如果系统使用 NetworkManager:

lua 复制代码
systemctl status NetworkManager-wait-online.service

如果系统使用 systemd-networkd:

lua 复制代码
systemctl status systemd-networkd-wait-online.service

应根据系统实际采用的网络管理器配置等待服务,不要同时盲目启用多个网络管理器。

四、配置能解决什么,不能解决什么?

场景 本配置的效果
服务器开机时 Docker 早于网络就绪启动 可降低启动竞态导致的异常概率。
Docker 初始化网桥时依赖的网络条件未满足 可以改善部分因开机时序造成的问题。
运行期间执行 systemctl restart NetworkManager 不能保证自动恢复 Docker 网络。
运行期间重启 firewalld / UFW 后端口映射不可访问 不能保证自动修复丢失或变更的防火墙/NAT 规则。
Docker 网桥被 NetworkManager 或其他网络服务接管 不能解决,需要调整网络管理规则。

五、运行期间网络重启造成端口映射失效的排查方向

如果 Docker 已正常启动,但重启网络服务后容器端口无法访问,建议按以下方向定位根因:

  1. 检查 Docker 服务与容器状态 :使用 systemctl status docker、docker ps 确认服务与容器是否仍正常运行。
  2. 检查端口发布配置 :使用 docker ps 和 docker port <容器名或ID>,确认端口仍然按预期发布。
  3. 检查防火墙及 NAT 规则:核查 firewalld、UFW、iptables 或 nftables,确认网络重启时是否刷新、覆盖了 Docker 创建的规则。
  4. 检查 Docker 网桥管理归属 :确认 docker0、br-* 等接口没有被 NetworkManager 或其他网络管理器错误接管。
  5. 检查 Docker daemon 配置 :确认 /etc/docker/daemon.json 中没有意外关闭 Docker 的防火墙规则管理(如 "iptables": false);注意不同 Docker 网络后端及版本的配置差异。
  6. 检查服务日志 :通过 journalctl -u docker -b 和对应网络、防火墙服务日志定位规则被清理或接口被重建的时间点。

建议:优先修复造成 Docker 网桥或防火墙规则异常的服务配置,避免将每次网络重启后执行 systemctl restart docker 作为长期解决方案。

六、总结

通过下面的 systemd drop-in 配置,可以优化 Docker 的开机启动顺序:

ini 复制代码
[Unit]
Wants=network-online.target
After=network-online.target
After=firewalld.service

其中 After=firewalld.service 应根据服务器实际是否使用 firewalld 决定是否保留。

核心结论:

  • 开机启动问题 :通过 network-online.target 优化依赖与顺序。
  • 运行期间网络重启问题:应检查防火墙/NAT 规则及 Docker 网桥的管理冲突,针对根因修复。
  • 不要混淆"网络就绪后启动 Docker"与"网络重启后自动恢复 Docker 端口映射"这两类问题。
相关推荐
学长毕设2 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
梦里寻码2 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
鶴哥只手遮天2 小时前
《Redis 8.10.3 深度剖析》系列 ·第 10 章 Hash 一:`listpack`、`hashtable` 与 `LISTPACK_EX`
redis·后端·开源
johnjincaaaa2 小时前
WebAssembly 逆向实战:从 0 搞懂猿人学第 15 题
后端
Gopher_HBo2 小时前
Go CPU 剖析:四角色白话机制 + 实测实验
后端
猿人谷2 小时前
Surrogate Model:让进化算法学会“预测”,为什么它正在成为智能优化的重要技术?
后端·算法·架构
the局外人3 小时前
LangChain ToolRuntime 入门:context、state 与 store 的实际用法
后端·langchain·agent
回家路上绕了弯3 小时前
当 AI 越来越能干,我们如何理解自己的价值?
后端
陈随易3 小时前
Node.js 2026上半年都有哪些性能提升?
前端·后端·程序员
hhcgchpspk3 小时前
flask服务端页面预防被爬措施
后端·python·flask·网络爬虫·防爬