docker自身不提供完整分布式服务发现,但可通过原生dns(单机)、swarm内置dns(跨主机)、consul/etcd(中大型)等组合方案实现;需规避默认bridge限制、dns不注销、跨网调用失效等常见误区。

Docker 本身不提供完整的分布式服务发现方案,但能通过组合网络模型、内置机制和外部工具,构建适配不同规模场景的服务发现能力。关键在于明确需求:单机轻量级协作可用原生 DNS;跨主机或生产环境则需 Consul、etcd 等协调系统。
用 Docker 自定义网络 + 内置 DNS(适合单机或 Swarm)
这是最轻量、零依赖的方式,适用于开发测试或小型集群。
- 创建自定义 bridge 网络:
docker network create mynet - 启动容器并指定网络与名称:
docker run -d --name api --network mynet nginx和docker run -it --network mynet alpine wget -qO- http://api - 同一网络内,容器可通过 服务名直接解析为 IP,Docker 内置 DNS 自动完成注册与查询
- 在 Swarm 模式下,服务名(如
web)会解析为多个实例 IP,支持 DNS 轮询负载均衡;还可通过虚拟 IP(VIP)实现更稳定的请求分发
集成 Consul 实现动态服务注册与健康检查
Consul 提供服务注册、健康探测、KV 存储和 DNS/HTTP 接口,适合中大型分布式部署。
- 启动 Consul Server(开发模式):
consul agent -dev -client=0.0.0.0 -bind=0.0.0.0 - 用 registrator 监听 Docker 事件:运行容器时自动将服务(IP+端口)注册到 Consul,无需修改应用代码
- 服务消费者通过
nslookup api.service.consul或 HTTP APIcurl http://localhost:8500/v1/health/service/api获取健康实例列表 - Consul 定期执行 TCP/HTTP 健康检查,自动剔除故障节点,保障服务列表实时准确
基于 etcd 构建轻量级服务注册中心
etcd 作为高可靠键值存储,适合已有 Kubernetes 或偏好命令行管理的团队。
- 启动 etcd:
etcd --advertise-client-urls http://localhost:2379 --listen-client-urls http://0.0.0.0:2379 - 服务启动时写入信息:
etcdctl put /services/api '{"host":"172.18.0.3","port":80}' - 客户端监听变更:
etcdctl watch --prefix /services/,收到增删事件后更新本地连接池 - 配合 docker-discover 这类工具,还能自动注入 HAProxy 配置,实现服务发现 + 负载均衡一体化
避免常见误区
实际落地时容易忽略几个关键点:
- 默认 bridge 网络不支持跨主机通信,必须使用 overlay 网络(Swarm)或 host 网络 + 外部协调器
- Docker 内置 DNS 不支持服务注销——容器退出后记录仍存在,需搭配健康检查或使用 Consul/etcd 的 TTL 机制清理
- 单纯靠容器名访问只在同网络内有效,跨网络或跨主机调用必须引入中心化注册中心
- 服务发现不是“一次注册,永久可用”,必须设计定期心跳或主动注销逻辑,否则会积累僵尸实例











