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 端口映射"这两类问题。
相关推荐
高频因子挖掘机3 小时前
同一交易日出现重复 K 线:去重前先确认时间、来源和粒度
后端·github·api
feely02084 小时前
《我写了 31 个静态扫描插件,踩了 7 个「假绿」》
后端
橙子家5 小时前
参数校验类异常(Argument Exception)【C# Exception 详解系列一】
后端
掘金挖土5 小时前
前端手摸手跑路之 AI 应用开发(九)
前端·后端
全栈弄潮儿5 小时前
Python实战第8期:函数
后端·python·编程语言
码事漫谈6 小时前
你让 AI “尽力做”,它反而可能做不好
后端
孟健6 小时前
LLM API 安全防线:从 OpenCode 盗刷事件到 LiteLLM 多模型容灾实操
人工智能·后端·架构
程序员cxuan6 小时前
我用 WorkBuddy + ima 把公众号文章做成了知识库。
人工智能·后端·程序员