Docker Swarm 29.8.0 升级后同节点宿主机 IP 端口不通:怎样取证与回退

用四点连通性矩阵确认版本回归,再选择 overlay 服务名绕行或受控回退 Engine

Docker Swarm 升级 29.8.0 后容器无法经同节点宿主机 IP 访问已发布端口时,用四点矩阵确认回归,并安全绕行或回退。

Docker Swarm 升级到 29.8.0 后,如果服务容器只能在“任务与目标不在同一节点”时经宿主机 IP 访问已发布端口,而同节点访问超时,先按已确认的 29.8.0 网络回归处理,不要先清空防火墙。先保存版本、服务端口模式、任务所在节点和四组连通性结果。短期优先让 Swarm 内部调用改走同一 overlay 网络中的服务名;必须保留宿主机 IP 路径时,在维护窗口回退到升级前已验证版本,并冻结自动升级,等待上游修复版本。

本文适用于 Linux Docker Engine 的 Swarm 服务,并且问题出现在升级 29.8.0 之后。只读检查不会收费,也不会修改数据。回退 Docker Engine 会重启守护进程,可能中断容器网络和业务连接;执行前必须保留云控制台入口、配置、镜像摘要和数据卷备份,并先在一个可排空节点验证。

先确认是否命中这次回归

不要只凭一条 curl 失败下结论。上游现场的关键特征是:Swarm 服务启用了已发布端口,容器从同一节点访问该节点宿主机 IP 失败,但访问另一节点的宿主机 IP 或升级前版本正常。先在管理节点执行以下只读命令;把 YOUR_SERVICE 换成真实服务名。

docker version
docker info --format '{{json .Swarm}}'
docker service inspect YOUR_SERVICE --pretty
docker service ps YOUR_SERVICE --no-trunc
docker service inspect YOUR_SERVICE --format '{{json .Endpoint.Spec.Ports}}'
docker network ls
docker network inspect ingress

docker version 应显示服务端 Engine 版本;不能只看客户端版本。端口输出中的 PublishMode 若为 ingress,请求会经过 routing mesh;若为 host,则是直接发布到任务所在节点,两种路径不能混为一谈。任务列表用于确认发起请求的容器与目标任务是否恰好在同一节点。

做四点连通性矩阵

选择一个不会改变数据的健康检查地址,分别从外部客户端、宿主机、同节点容器和异节点容器访问同一个 宿主机IP:已发布端口。不要对有写入副作用的接口重复测试。以下命令中的地址、端口、容器名必须按实际环境替换。

curl -v --connect-timeout 5 http://HOST_IP:PUBLISHED_PORT/health
docker exec SOURCE_CONTAINER curl -v --connect-timeout 5 http://HOST_IP:PUBLISHED_PORT/health
docker exec SOURCE_CONTAINER getent hosts TARGET_SERVICE
docker exec SOURCE_CONTAINER curl -v --connect-timeout 5 http://TARGET_SERVICE:TARGET_PORT/health

如果只有“同节点容器 → 本节点宿主机 IP → 已发布端口”失败,而服务名访问、外部访问和跨节点宿主机 IP 访问正常,特征与 Moby #53713 高度一致。若所有方向都失败,应先检查服务是否有运行中的任务、应用是否监听目标端口,以及节点间 7946/TCP+UDP、4789/UDP 和已发布端口是否放行。

检查结果更可能的原因下一步
只有同节点宿主机 IP 路径失败,版本为 29.8.0命中已确认的 Swarm 回归改走 overlay 服务名,或受控回退 Engine
服务名也失败overlay、服务发现或应用监听异常查共同网络、任务日志与目标端口
跨节点也失败节点间端口、防火墙或 ingress 异常核对 7946/TCP+UDP、4789/UDP 与规则
仅外部失败安全组、负载均衡或已发布端口未开放从公网入口向内逐层取证
PublishMode 为 host不经过 routing mesh,且节点必须实际运行任务按 host 模式拓扑检查,不套用本回归结论

不要用清空 iptables 作为第一步

Docker 官方说明,Swarm overlay 与已发布端口依赖 Docker 创建的 iptables/nftables 链和 IP 转发。直接停止 firewalld、关闭 Docker 的 iptables 选项或清空规则,既可能让容器断网,也可能把原本受控的端口暴露出去。先保存只读证据:

sudo iptables-save
sudo nft list ruleset
sudo sysctl net.ipv4.ip_forward
sudo journalctl -u docker --since '30 minutes ago' --no-pager

这些命令只读取当前状态。若机器使用 nftables 后端,iptables 输出可能是兼容视图,因此要同时记录后端和规则;不要根据链名存在就认定流量已经通。

恢复业务的两个安全分支

分支一:Swarm 内部调用改用服务名

调用方和目标服务连接到同一个用户自定义 overlay 网络时,Swarm 内置 DNS 可以按服务名发现目标。把内部 URL 从宿主机 IP 改成 http://TARGET_SERVICE:TARGET_PORT,绕开“容器回到本节点宿主机已发布端口”的路径。先在单个调用方副本验证 DNS、TLS 主机名、鉴权和健康检查,再滚动更新。若应用必须使用公网域名,不能在没核对证书、回调和访问控制前强行替换。

分支二:受控回退 Docker Engine

如果业务架构暂时无法改掉宿主机 IP 路径,且问题确实从 29.8.0 升级后开始,可评估回退到升级前已经验证的 Engine 版本。先排空一个 worker,只在该节点按发行版官方包管理流程锁定完整的 Docker Engine、CLI 与 containerd 兼容版本;不要只替换单个二进制,也不要删除 /var/lib/docker。回退会重启 Docker,必须在维护窗口执行。

若节点承载有状态服务,先确认副本、持久卷和备份。回退失败时恢复原软件包版本与 daemon 配置,重新加入调度前确认节点状态为 Ready、overlay 网络存在且服务任务稳定。

怎样验证修复与回退

  1. 重复四点连通性矩阵,确认同节点与跨节点路径均符合预期。
  2. 检查 docker node ls、docker service ps,确认节点 Ready、任务没有反复重启。
  3. 从服务名访问目标端口,并从外部负载入口访问已发布端口。
  4. 观察 Docker 日志、连接错误和应用指标至少一个完整业务周期。
  5. 记录临时绕行或回退版本,待上游发布修复后先在排空节点复测,再逐节点升级。

若更换调用地址后失败,恢复原环境变量或配置版本并滚动回退服务;若 Engine 回退造成新的网络或运行时问题,恢复升级前保存的包版本组合与 daemon 配置。任何回退都不应删除容器数据目录或卷。

相关教程

官方与上游来源

云服务器教程Docker 执行 buildx prune 后缓存全失效:怎样判断并恢复 BuildKit 命中2026-09-28云服务器教程Docker push 报 timeout awaiting response headers:怎样排查 containerd 镜像提交超时2026-09-27云服务器教程NGINX Gateway Fabric 的 HTTPRoute 状态正常却返回 503:怎样定位 fallback upstream2026-09-26

加入开发者交流社区

与全球开发者、运维和工作室一起交流技术、分享经验、配置、账号与最新优惠信息

  • 云平台使用交流
  • 资源优惠信息
  • 最新教程与资讯
  • 开发者经验分享
联系 Telegram 客服
加入开发者交流社区