docker服务发现依赖自定义网络+内置dns+声明式依赖:需创建bridge/overlay网络启用dns解析,容器间通过service名(如web、db)直接通信,swarm模式还提供vip与负载均衡。

Docker 服务编排实现多个容器自动服务发现与通信,核心在于网络抽象 + DNS 注册 + 声明式依赖三者协同。不需要手动记 IP、写脚本或硬编码地址,系统会在容器启动时自动完成定位和连通。
自定义网络是自动服务发现的前提
默认 bridge 网络不支持容器名解析,必须显式创建自定义网络(bridge 或 overlay),才能启用内置 DNS:
- 容器加入同一自定义网络后,Docker 内置 DNS 服务器会为每个服务名(或容器名)生成 A 记录
- 其他容器可直接用
http://web、redis://cache:6379这类名称访问,无需知道真实 IP - 示例命令:
docker network create app-net docker run -d --name web --network app-net nginx docker run -it --network app-net alpine ping web # 成功解析并连通
Compose 中通过 service 名实现跨容器通信
在 docker-compose.yml 中,每个 service 的名字就是 DNS 主机名,同网络下可直接使用:
- 所有 service 默认接入同一自定义网络(如
default或显式声明的backend) -
depends_on控制启动顺序,但不保证服务就绪;真正可靠的服务可用性需配合健康检查或应用层重试 - 示例片段:
services: api: image: my-api networks: [backend] db: image: postgres networks: [backend] environment: POSTGRES_HOST: db # ← 直接用 service 名,Docker 自动解析 networks: backend: driver: bridge
Swarm 模式下服务发现更进一步:VIP + 内置负载均衡
Swarm 不仅支持 service 名解析,还为每个服务分配虚拟 IP(VIP)和 DNS 条目,请求自动分发到任意健康副本:
- 创建 overlay 网络,部署服务时指定
--network my-overlay - 其他服务或容器访问
http://web时,DNS 返回 VIP,Swarm 负载均衡器将请求转发至某个运行中的 task - 即使某节点宕机,VIP 不变,DNS 不刷新,流量自动绕过故障实例
注意关键细节避免踩坑
- 同一网络内才可互通,跨网络需显式连接或使用 ingress 暴露端口
- DNS 解析有缓存(如 Go 应用默认缓存 30 秒),若服务频繁启停,建议应用层加重试或降低 DNS TTL
- Redis、MySQL 等客户端库通常支持域名直连,但部分旧版驱动需设置
host=service-name而非host=127.0.0.1 - 不要依赖
links(已弃用)或/etc/hosts手动映射,那是 Docker 1.9 之前的做法
不复杂但容易忽略











