容器 DNS 是怎么定的
容器里的解析配置有三个来源,优先级从高到低是:启动时的显式参数、守护进程配置、宿主机的解析文件。此外,用户自定义网络会给容器内置一个解析服务地址,用它解析同一网络内的容器名与网络别名,这让服务之间可以按名字互访而不必写死地址。默认桥接网络不具备这个能力,所以“容器名解析不到”几乎总是网络类型选错造成的。
基本信息
| 显式指定 | --dns 指定解析地址,--dns-search 指定搜索域,--dns-opt 传解析选项 |
|---|---|
| 优先级 | 启动参数高于守护进程配置,守护进程配置高于宿主的解析文件 |
| 内置解析 | 用户自定义网络使用固定回环地址解析容器名、服务名与网络别名 |
| 临时映射 | --add-host 名称:地址 可注入一条静态映射,可多次使用 |
| 查看方式 | 进入容器看解析文件内容,或用解析工具验证结果 |
| 注意点 | 运行中的容器不会随守护进程配置变化而更新,需要重建容器 |
典型使用场景
- 内网域名解析:容器需要访问只在内网可达的服务地址
- 容器之间按名字互访:省去写死地址与改配置的成本
- 联调时把某个域名临时指向测试地址,不动正式解析
- 宿主解析服务慢或不稳定时,显式指定更快的解析地址
- 排查解析超时:先确认容器实际使用的是哪一组解析地址
使用示例
使用示例
docker run --rm alpine cat /etc/resolv.conf # 看容器实际使用的解析配置
docker run --rm --dns 223.5.5.5 alpine nslookup example.com # 显式指定解析地址
docker run --rm --dns-search corp.example.com alpine nslookup app # 指定搜索域,短名可用
docker run --rm --add-host api.local:10.0.0.8 alpine getent hosts api.local # 注入一条映射
docker exec web getent hosts db # 自定义网络内按容器名解析
docker network inspect mynet -f '{{json .IPAM}}' # 看网段与网关配置解析来源与优先级
| 来源 | 优先级 | 说明 |
|---|---|---|
| 启动参数 --dns | 最高 | 只对本次容器生效,最可控 |
| 守护进程配置 | 次之 | 全局生效,已有容器需重建 |
| 宿主解析文件 | 最低 | 宿主的配置直接决定容器可见的解析 |
| 自定义网络内置解析 | 独立生效 | 解析容器名、服务名与网络别名 |
默认桥接网络不做容器名解析:要按名字互相访问,必须使用自定义网络,或用静态映射手工补齐。
宿主使用本地解析缓存服务时,容器看到的解析行为可能与宿主不同:排查解析问题时先对比两边的实际配置。