三节点Docker Swarm下Traefik跨节点负载均衡配置问题排查
核心问题根源
- 你当前配置的
external: true的shared_network大概率不是跨节点可路由的overlay类型网络。如果当初创建这个外部网络时没指定overlay驱动,Docker默认会创建本地bridge网络,这类网络仅支持单节点内部通信:当whoami副本全在manager上时,Traefik能正常访问;一旦副本调度到worker节点,Traefik从manager上拿到的容器IP是worker节点本地的网卡地址,跨节点根本路由不通,就会出现“第一次凑巧命中manager本地的副本能通,后续路由到worker节点的副本直接超时”的现象。 - 给Traefik绑定挂载的
/var/lib/docker/containers目录在跨节点场景下完全多余,这个路径下仅存储manager节点本地的容器数据,不仅帮不上忙,还可能导致Traefik错误读取本地容器的网络配置,匹配到不可达的后端IP。 - Traefik v1.7在Swarm模式下做服务发现时,必须准确匹配对应服务的overlay网络标识,一旦网络类型不对,即使标签写得再标准,拿到的后端IP本身就不具备跨节点可达性。
具体调整步骤
- 先校验现有
shared_network的属性:在任意Swarm节点执行docker network inspect shared_network,查看输出里的Driver字段,如果不是overlay,先删除旧网络,重新创建带跨节点能力的网络:
必须加docker network rm shared_network docker network create --driver overlay --attachable shared_network--attachable参数,否则只有Swarm部署的服务能接入网络,像Traefik这类需要通过sock对接Swarm的服务,会出现网络接入不完整的问题。 - 删掉Traefik配置里多余的
/var/lib/docker/containers绑定挂载,仅保留docker.sock的挂载即可,对应配置片段删除:- type: bind source: /var/lib/docker/containers target: /var/lib/docker/containers - 核对Traefik启动参数,补充避免误识别的配置,在原有command列表里新增
--docker.exposedbydefault=false,防止集群里所有带端口暴露的容器都被Traefik自动抓取为后端服务。 - 保留whoami服务的现有标签配置,重点确认
traefik.docker.network=shared_network的网络名和你实际创建的overlay网络名完全一致,不能有拼写、大小写差异。 - 如果要实现任意节点IP访问80端口都能正常处理请求,调整Traefik的部署策略:
让所有manager节点上都运行一个Traefik实例,通过host模式绑定80端口,请求落到哪个节点,就由哪个节点本地的Traefik处理,再通过Swarm内置的overlay网络转发到对应副本,从根本上避免跨节点路由的超时问题。deploy: mode: global placement: constraints: - node.role == manager
验证方式
- 重新部署服务栈后,执行
docker service ps 你的栈名_whoami,确认3个副本已经分布在不同的Swarm节点上。 - 多次执行
curl http://[任意节点IP]/whoami,核对返回的Hostname字段,确认三个节点上的副本都能被正常轮询访问,不会再出现Gateway Timeout错误。
注意:Traefik v1.7已经停止社区维护,当前使用的标签规则仅适配1.7版本,如果后续要升级到Traefik v2及以上版本,需要整体替换标签的格式规则。
内容的提问来源于stack exchange,提问作者Paul Stoner
相关产品推荐
相关产品推荐

