Docker Swarm环境下容器IP获取与服务配置咨询
问题分析与解决方案
你的方案存在两个核心概念错误,导致无法稳定运行:
- Docker Swarm 中
depends_on不保证启动顺序与就绪状态:Swarm 模式下的depends_on仅确保服务被调度部署,不会等待依赖服务的容器完全启动就绪;且 Swarm 容器的 IP 是动态分配的,重启、调度后 IP 会变更,硬编码 IP 必然导致服务失效。 - 依赖容器 IP 的思路完全错误:Swarm 内置了集群 DNS 服务,同一 overlay 网络内的服务可直接通过服务名称通信,无需依赖容器 IP。
正确实现方案
利用 Swarm 内置 DNS 服务,通过服务名称替代 IP 完成解析与访问,无需关心启动顺序与 IP 变动。
步骤1:创建专用 Overlay 网络
所有服务加入同一个 overlay 网络,确保集群 DNS 生效:
docker network create --driver overlay services-net
步骤2:部署 Traefik 服务
无需特殊配置,只需加入创建的 overlay 网络:
services: traefik: image: traefik:v2.11 command: - "--providers.docker=true" - "--providers.docker.swarmMode=true" - "--entrypoints.web.address=:80" networks: - services-net deploy: mode: replicated replicas: 1
步骤3:部署 DNSMasq 服务
配置域名解析时直接使用 Traefik 的服务名称(traefik),Swarm DNS 会自动将服务名解析为对应容器的动态 IP:
dnsmasq: image: jpillora/dnsmasq command: - "--address=/example.com/traefik" # 用服务名替代硬编码IP networks: - services-net deploy: mode: replicated replicas: 1
步骤4:部署 Wireguard 服务
将客户端默认 DNS 设置为 DNSMasq 的服务名称(dnsmasq),同样依赖 Swarm DNS 完成解析:
wireguard: image: linuxserver/wireguard environment: - PUID=1000 - PGID=1000 - TZ=Europe/London - PEERS=1 - PEERDNS=dnsmasq # 用DNSMasq服务名作为客户端DNS networks: - services-net cap_add: - NET_ADMIN - SYS_MODULE sysctls: - net.ipv4.conf.all.src_valid_mark=1 deploy: mode: replicated replicas: 1
可选:DNSMasq 作为主机系统服务的处理方式
若坚持将 DNSMasq 部署在主机而非容器中,可在主机 DNSMasq 配置中添加规则,将 example.com 的解析请求转发至 Docker 内置 DNS(127.0.0.11),由 Docker DNS 自动解析 Traefik 服务名:
# 主机 DNSMasq 配置片段 server=/example.com/127.0.0.11
核心优势
- 无需依赖启动顺序:服务间通过名称访问,只要服务部署完成,Swarm DNS 会自动处理解析,无需等待容器就绪
- 动态 IP 自动适配:无论容器重启、调度,服务名称对应的 IP 都会被自动更新,不会出现解析失效问题
内容的提问来源于stack exchange,提问作者Ottavio Miele
相关产品推荐
相关产品推荐

