容器之间为什么能按名字互相访问?127.0.0.11 是什么?--dns 和 --dns-search 又改了什么?这篇读 resolv.conf、用 nslookup 和 ping 逐项验证,并看 127.0.0.11 在容器里具体监听在哪里。
默认 bridge 上的容器:nameserver <本机局域网IP> 自定义网络上的容器:nameserver 127.0.0.11 ; options ndots:0
自定义网络里的容器 resolv.conf 指向 127.0.0.11,选项 ndots:0;默认 bridge 上的容器拿到的是 Docker Desktop 的 DNS 地址 192.168.65.7,所以解析不了容器名。
nslookup bwlab-c48a:退出码 0;地址 ['127.0.0.11:53', '172.19.0.2'] nslookup web:退出码 0;地址 ['127.0.0.11:53', '172.19.0.2'] nslookup frontend:退出码 0;地址 ['127.0.0.11:53', '172.19.0.2'] nslookup bwlab-c48b:退出码 0;地址 ['127.0.0.11:53', '172.19.0.3'] nslookup nonexistent-name:退出码 1;地址 ['127.0.0.11:53'];["** server can't find nonexistent-name: NXDOMAIN"] 容器 a 的真实 IP:172.19.0.2 反向:别的容器在默认 bridge 上,能解析 bwlab-c48a 吗?不能
容器名、--network-alias 都能解析,不存在的名字失败,别的网络里的容器名解析不了。一个名字对应多个容器时的表现(轮询),见后面的 DNS 轮询一篇。
容器里监听的 UDP / TCP 端口:udp 0 0 127.0.0.11:56362 0.0.0.0:* ; tcp 0 0 127.0.0.11:46227 0.0.0.0:* LISTEN 外部名字(github.com)解析:Address: 127.0.0.11:53 Address: 20.205.243.166 real 0.00
127.0.0.11:53 只是客户端看到的地址;容器自己的网络命名空间里,127.0.0.11 的一个随机 UDP 端口和一个随机 TCP 端口在监听(这里是 56362 和 46227)。把 53 端口的请求如何转到这些端口,我没有看 iptables 规则。外部名字被转发给上游,github.com 解析正常。
自定义网络 + --dns 1.1.1.1 --dns-search example.internal --dns-opt ndots:2:nameserver 127.0.0.11 ; search example.internal ; options ndots:2 这个容器 ping bwlab-c48a(走 getaddrinfo,会用 search 和 ndots):退出码 0;PING bwlab-c48a (172.19.0.2): 56 data bytes 同一个容器 nslookup bwlab-c48a:退出码 1 同一个容器 nslookup bwlab-c48a.(末尾带点,不走 search):退出码 0 默认 bridge + --dns 1.1.1.1:nameserver 1.1.1.1
自定义网络里 --dns 1.1.1.1 并不出现在 resolv.conf,内置 DNS 继续服务容器名,外部名字才转给指定的上游(我没有验证上游确实换成了 1.1.1.1);--dns-search、--dns-opt 则直接写进 resolv.conf。默认 bridge 上 --dns 直接写进 resolv.conf。注意 busybox 的 nslookup 在有 search 域时对短名字表现不同于 ping。