容器 DNS 与服务发现
Docker 内置 DNS 服务,实现容器间服务名解析,下面介绍其工作原理。
内置 DNS
Bash
# 自定义网络中的容器自动注册 DNS
docker network create my-network
docker run -d --name web --network my-network nginx
docker run -d --name app --network my-network my-app
# app 可通过名称访问 web
docker exec app curl web:80
Docker 内置 DNS 服务器监听
127.0.0.11,容器自动注册名称。
DNS 解析
Bash
# 查看容器 DNS 配置
docker exec app cat /etc/resolv.conf
# 输出
nameserver 127.0.0.11
options ndots:0
# DNS 解析顺序:
# 1. 容器名称(web)
# 2. 网络别名(web.my-network)
# 3. 外部 DNS(/etc/resolv.conf 其他 nameserver)
网络别名
Bash
# 启动时指定别名
docker run -d --name db \
--network my-network \
--network-alias database \
--network-alias postgres \
postgres:15
# 可通过多个名称访问
docker exec app curl database:5432
docker exec app curl postgres:5432
docker exec app curl db:5432
Compose 中的 DNS
YAML
version: '3.8'
services:
web:
image: nginx
networks:
- frontend
app:
image: my-app
networks:
- frontend
- backend
db:
image: postgres
networks:
backend:
aliases:
- database
- postgres-db
networks:
frontend:
backend:
Bash
# app 可通过以下名称访问 db
docker compose exec app curl database:5432
docker compose exec app curl postgres-db:5432
DNS 与网络隔离
Bash
# 不同网络的容器 DNS 隔离
docker network create frontend
docker network create backend
docker run -d --name web --network frontend nginx
docker run -d --name db --network backend postgres
# web 无法解析 db(不在同一网络)
docker exec web curl db:5432 # 失败
外部 DNS 配置
Bash
# Docker Daemon 配置
# /etc/docker/daemon.json
{
"dns": ["8.8.8.8", "8.8.4.4"],
"dns-search": ["example.com"]
}
# 容器创建时指定 DNS
docker run -d \
--dns 8.8.8.8 \
--dns-search example.com \
--dns-opt "timeout:3" \
nginx
调试 DNS
Bash
# 测试 DNS 解析
docker exec app nslookup web
docker exec app dig web
# 查看 Docker DNS 日志
docker logs <dns-container>
DNS 缓存
Bash
# Docker DNS 有缓存机制
# 容器 IP 变化后,DNS 记录会更新(有延迟)
# 避免缓存问题
# 1. 使用服务名而非 IP
# 2. 重试机制等待 DNS 更新
YAML
# 等待 DNS 就绪
services:
app:
command: >
sh -c "
until nslookup db; do
echo 'Waiting for DNS...'
sleep 2
done
node server.js
"
要点总结
- Docker 内置 DNS 服务器(127.0.0.11),容器自动注册名称
- 自定义网络中容器可通过名称互相访问
- 网络别名提供多个访问路径,提高配置灵活性
- 不同网络的容器 DNS 隔离,无法跨网络解析
- 外部 DNS 通过 daemon.json 或 run 参数配置
📝 发现内容有误?点击此处直接编辑