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 。

解决方案

  1. 直接使用 volume 设置重新映射 /etc/resolv.conf 文件到宿主机的位置。

  2. 在 daemon.json 中可以配置 所有docker 容器的缺省 dns。

  3. 使用参数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也无伤大雅。

posted @ 2022-08-16 14:28  风风羊  阅读(4224)  评论(0编辑  收藏  举报