服务发现
什么是服务发现
在容器化环境中,容器 IP 是动态分配的,每次重启都会变化。服务发现允许服务通过逻辑名称而非固定 IP 来找到彼此。
为什么容器环境需要服务发现
传统架构: 容器化架构:
user-service user-service-1 (10.0.0.5)
↓ 固定 IP 用户请求 user-service
db: 192.168.1.5 ↓
DNS 解析 → 10.0.0.5
如果挂了,重新调度
user-service-2 (10.0.0.6)
IP 变了,但名称不变
Docker 内置服务发现
1. 默认 Bridge 网络
容器的通信只能通过 IP,不支持服务名解析。
2. 自定义网络(推荐)
# 创建自定义网络
docker network create myapp-net
# 在这个网络中的容器可以通过容器名通信
docker run -d --name db --network myapp-net postgres:15
docker run -d --name app --network myapp-net myapp:latest
# app 容器中可以直接访问
# ping db
# curl http://db:5432
3. Docker Compose
version: '3.8'
services:
web:
image: nginx
depends_on:
- api
api:
image: myapi:latest
environment:
DB_HOST: database # 服务名 DNS
database:
image: postgres:15
Compose 自动为每个服务创建 DNS 记录,服务名即为主机名。
4. Docker Swarm
# Swarm 内置 DNS 和负载均衡
docker service create --name web --replicas 3 nginx
# 任何容器访问 web 都会被负载均衡到任意一个副本
docker service create --name consumer alpine \
sh -c "while true; do wget -qO- http://web; done"
Kubernetes 服务发现
ClusterIP Service
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 8080
Pod 可以通过 user-service 或 user-service.namespace.svc.cluster.local 访问。
Headless Service
apiVersion: v1
kind: Service
metadata:
name: stateful-service
spec:
clusterIP: None
selector:
app: stateful
直接返回所有 Pod IP,适合有状态应用。
外部服务发现方案
1. Consul
# 启动 Consul
docker run -d \
--name consul \
-p 8500:8500 \
consul:latest
# 注册服务
docker run -d \
-e SERVICE_NAME=web \
-e SERVICE_TAGS=prod \
progrium/consul
2. etcd
# 启动 etcd
docker run -d \
--name etcd \
-p 2379:2379 \
quay.io/coreos/etcd
# 注册服务
etcdctl put /services/web/1 '{"ip":"10.0.0.5","port":8080}'
3. ZooKeeper
# 创建节点
create /services/myapp "10.0.0.5:8080"
# 读取
get /services/myapp
服务发现的模式
客户端发现
客户端 → 服务注册表 → 获取 IP 列表 → 选择一个发起请求
- 客户端需要集成服务发现逻辑
- 优点:简单,没有中间层
- 缺点:每个客户端需要实现发现逻辑
服务端发现
客户端 → 负载均衡器 → 转发到可用服务
- 客户端只需访问一个地址
- 优点:对客户端透明
- 缺点:需要额外部署负载均衡器
面试要点
- Docker 自定义网络内置 DNS 服务发现:在同一网络中的容器可以通过容器名互相访问
- Swarm 和 Compose 天然支持服务名解析
- K8s 通过 Service 资源提供了 DNS 和服务发现
- 服务发现是微服务通信的基础设施
- 外部方案(Consul/etcd)适用于跨集群的场景
面试官常问:Docker 自定义网络的服务发现是怎么实现的?和 K8s 的 Service 有什么异同?
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容