为什么代理容器不会自动使用 DNS 容器
共享 Docker 主机、共享网络与选择解析器是三件不同的事。从代理内部追踪 DNS 查询。
在同一个 Docker 主机上运行代理和 DNS 服务器,并不会把两者的 DNS 路径连接起来。有三层彼此独立的关系值得注意:
- 网络可达性。 不同的 Compose 项目通常各有默认网络。要把服务放到合适的共享网络上,可以在同一项目内,也可以经由项目之间显式共享的网络。
- 服务发现。 自定义 Docker 网络的内嵌 DNS 能解析容器名。这让应用可以发现邻居,但并不会自动把该邻居选作自己的 DNS 解析器。
- 解析器选择。 先确认代理容器内部实际使用的解析器。Compose 的
dns字段接收的是 DNS 服务器地址。像dns.local这样在应用中能解析的名字,并不能成为该字段的合法取值。
从代理容器出发,一路追到它配置的解析器地址,确认该地址上既有路由也有 DNS 监听。发布主机的 53 端口只是建立了主机侧的访问路径,并不等于告诉容器去使用它。共享同一网络的容器反而可以直接通信。
如果配置引用了 DNS 容器的地址,请在相互兼容的 IPAM 配置下保持该地址稳定。从昨天的容器里抄下来的动态分配地址,在重建时可能失效。也要检查解析器的上游路径:把无应答的查询转发回它自己,造成的故障与解析器不可达并不相同。
最后要判断究竟是谁在解析目标地址。解析 CONNECT 主机名的 HTTP 代理可以走这条容器路径;在本地解析的 SOCKS 客户端则未必。在主机上查询只能证明主机的路由,证明不了代理进程的路由。