docker 容器中的DNS 问题
docker run 命令 设置dns
docker run --dns=8.8.8.8 ···· 后可以生效
docker-compose.yml 文件中 设置dns
官方文档 说的是在service 下直接使用 dns参数,还有两个参数没使用
dns
dns defines custom DNS servers to set on the container network interface configuration. Can be a single value or a list.
dns: 8.8.8.8
dns_opt
dns_opt list custom DNS options to be passed to the container’s DNS resolver (/etc/resolv.conf file on Linux).
dns_opt:
- use-vc
- no-tld-query
dns_search
dns defines custom DNS search domains to set on container network interface configuration. Can be a single value or a list.
dns_search: example.com
在docker-compose.yaml 中设置的并不能生效,主要表现在 容器中 /etc/resolv.conf 中的地址没有变化,修改文件重启后不生效。
使用docker inspect 查看容器虽然 两种方式设置的 dns 都是设置后dns,但其实 /etc/resolv.conf 文件并没有变。
原因分析:
因为 容器的 /etc/hosts 、hostname 等文件 都是默认挂载宿主机里的配置的,这个 在进入容器中 使用mount
命令可以看到。
一般容器中默认的 nameserver 就是 127.0.0.11 。
解决方案
-
直接使用 volume 设置重新映射 /etc/resolv.conf 文件到宿主机的位置。
-
在 daemon.json 中可以配置 所有docker 容器的缺省 dns。
-
使用参数
network_mode: bridge
,但是不能再用networks 配置额外的网络了,也就似乎不能固定容器的ip地址了。
问题进展
https://github.com/docker/compose/issues/2847
refer to https://docs.docker.com/config/containers/container-networking/
参考官方文档,意思如果使用默认的的docker0 网络的话,dns 配置会生效,但是使用自定义网络话,就不会用宿主机的 dns文件,从而不能覆盖配置。
而恰好使用 docker run 命令时默认使用的是桥接模式下的 docker0 网桥,所以生效。docker-compose 文件启动会创建新的网桥,所以不生效。
所以,方案3 就是在 compose 的yaml 中设置 network_mode: bridge
,再指定dns,此时容器的dns 就被覆盖了。
此时 启动的时候没有创建网络的步骤,而且查看容器 果然使用的就是 docker0 网桥。
但是也有一个新的问题,compose 中指定其他网段的ip,还可以再用 这个 network_mode 参数吗?
同时使用network_mode 和 networks 参数报错如下:
ERROR: 'network_mode' and 'networks' cannot be combined
至此,基本确认了 network_mode: bridge
使用的就是 docker0 的网络,目前只有这样才能在 compose 中指定 dns。
所以,问题最后变成了 如何让使用docker0 的容器分配指定ip。docker 容器默认需要指定ip的话一般都是需要自建网络的。
容器启动后可以进入直接 修改 /etc/resolv.conf 文件,也能直接生效,所以如果经常重启容器,其实不设定初始DNS也无伤大雅。