Docker 无法解析专用网络上的 DNS
Docker cannot resolve DNS on private network
我的机器在一个私有网络上,有私有 DNS 服务器,以及一个用于 DNS 解析的私有区域。我可以从我的主机解析此区域上的主机,但我无法从我主机上的容器 运行 解析它们。
主机:
root@host:~# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1
root@host:~# ping privatedomain.io
PING privatedomain.io (192.168.0.101) 56(84) bytes of data.
容器:
root@container:~# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 8.8.8.8
nameserver 8.8.4.4
root@container:~# ping privatedomain.io
ping: unknown host privatedomain.io
很明显,Google 的 public DNS 服务器无法解析我的私有 DNS 请求。我知道我可以用 docker --dns 192.168.0.1
强制它,或者在 /etc/default/docker
中设置 DOCKER_OPTS="--dns 192.168.0.1"
,但我的笔记本电脑经常切换网络。似乎应该有一个系统的方法来解决这个问题。
Docker 通过复制主机的 /etc/resolv.conf
并过滤掉任何本地名称服务器(例如 127.0.1.1)来填充 /etc/resolv.conf
。如果在那之后没有留下任何名称服务器,Docker 将添加 Google 的 public DNS 服务器(8.8.8.8 和 8.8.4.4)。
Note: If you need access to a host’s localhost resolver, you must modify your DNS service on the host to listen on a non-localhost address that is reachable from within the container.
主机上的 DNS 服务是 dnsmasq,所以如果你让 dnsmasq 监听你的 docker IP 并将其添加到 resolv.conf,docker 将配置容器使用它作为名称服务器。
1 . Create/edit /etc/dnsmasq.conf
† 并添加以下行:
interface=lo
interface=docker0
2 . 找到您的 docker IP(在本例中,172.17.0.1
):
root@host:~# ifconfig | grep -A2 docker0
docker0 Link encap:Ethernet HWaddr 02:42:bb:b4:4a:50
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
3 . Create/edit /etc/resolvconf/resolv.conf.d/tail
并添加此行:
nameserver 172.17.0.1
4 . 重启网络,更新 resolv.conf
,重启 docker:
sudo service network-manager restart
sudo resolvconf -u
sudo service docker restart
您的容器现在可以从主机使用的任何 DNS 服务器解析 DNS。
† 路径可能是 /etc/dnsmasq.conf
、/etc/dnsmasq.conf.d/docker.conf
、/etc/NetworkManager/dnsmasq.conf
或 /etc/NetworkManager/dnsmasq.d/docker.conf
,具体取决于您的系统和个人喜好。
对于Ubuntu 18.04 和其他使用systemd-resolved 的系统,可能需要安装dnsmasq 和resolvconf。 systemd 解析为 hard-coded to listen on 127.0.0.53, and Docker filters out any loopback address when reading resolv.conf.
1 . 安装 dnsmasq 和 resolvconf.
sudo apt update
sudo apt install dnsmasq resolvconf
2 . 找到您的 docker IP(在本例中为 172.17.0.1):
root@host:~# ifconfig | grep -A2 docker0
docker0 Link encap:Ethernet HWaddr 02:42:bb:b4:4a:50
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
3 . 编辑 /etc/dnsmasq.conf
并添加以下行:
interface=docker0
bind-interfaces
listen-address=172.17.0.1
4 . Create/edit /etc/resolvconf/resolv.conf.d/tail
并添加此行:
nameserver 172.17.0.1
5 . 重启网络,更新 resolv.conf
,重启 docker:
sudo service network-manager restart
sudo resolvconf -u
sudo service dnsmasq restart
sudo service docker restart
您的容器现在可以从主机使用的任何 DNS 服务器解析 DNS。
对于 Ubuntu 18.04 LTS 来说已经足够了:
sudo service network-manager restart
sudo resolvconf -u
sudo service dnsmasq restart
sudo service docker restart
如你所知,Docker复制host/etc/resolv.conf 文件到容器,但删除任何本地名称服务器。
我对这个问题的解决方案是继续使用 systemd-resolvd 和 NetworkManager 但添加 dnsmasq 并将其用于 "forward" Docker 容器 DNS 查询 systemd-resolvd.
分步指南:
- 制作/etc/resolv.conf一个"real"文件
sudo rm /etc/resolv.conf
sudo touch /etc/resolv.conf
- 创建文件 /etc/NetworkManager/conf.d/systemd-resolved-for-docker.conf 通知 NetworkManager 通知 systemd-resolvd 但不要触摸 /etc/resolv.conf
[main]
# NetworkManager will push the DNS configuration to systemd-resolved
dns=systemd-resolved
# NetworkManager won’t ever write anything to /etc/resolv.conf
rc-manager=unmanaged
- 安装dnsmasq
sudo apt-get -y install dnsmasq
- 在/etc/dnsmasq.conf中配置dnsmasq以监听DNS查询来自 Docker 并使用 systemd-resolvd 名称服务器
# Use interface docker0
interface=docker0
# Explicitly specify the address to listen on
listen-address=172.17.0.1
# Looks like docker0 interface is not available when dnsmasq service starts so it fails. This option makes dynamically created interfaces work in the same way as the default.
bind-dynamic
# Set systemd-resolved DNS server
server=127.0.0.53
- 编辑 /etc/resolv.conf 以使用 systemd-resolvd 名称服务器 (127.0.0.53) 和主机 IP (172.17.0.1) 在Docker网络中
# systemd-resolvd name server
nameserver 127.0.0.53
# docker host ip
nameserver 172.17.0.1
- 重启服务
sudo service network-manager restart
sudo service dnsmasq restart
sudo service docker restart
有关详细信息,请参阅我的 post(西班牙语)https://rubensa.wordpress.com/2020/02/07/docker-no-usa-los-mismos-dns-que-el-host/
我的 docker 容器中的 DNS 解析器有问题。我尝试了很多不同的东西,最后,我发现我的 Hostgator 中的 CentOS VPS 默认没有安装 NetworkManager-tui (nmtui), 我刚刚安装并重新启动它。
sudo yum install NetworkManager-tui
并使用默认 DNS 重新配置我的 resolv.conf
8.8.8.8
。
nano /etc/resolv.conf
如果您使用的是 VPN,则 VPN 协议可能会附加到超出您专用网络上配置的 MTU 的出站数据包。
典型的 MTU 是 1500。
尝试将此内容添加到 /etc/docker/daemon。json
{
"mtu": 1300,
"dns": ["<whatever DNS server you need in your private network>"]
}
然后systemctl restart docker
.
我的案例有许多来自 docker 集线器(nodered、syncthing 和其他)的图像:
- 容器在非根用户
下运行
- /etc/resolv.conf 容器内的权限为 600 且归 root
所有
所以我的解决方法很简单
root@container:~# chmod 644 /etc/resolv.conf
赚了! :))
我的 systemctl 状态 docker 中有相同的错误消息。
我 运行 一个 Nextcloud 和一个 nextcloud nginx 代理容器,并使用 docker compose 来安装它。它在没有 big hickups 的情况下工作了好几个月,但在星期五它无法访问。服务器已关闭。
我重新启动了它,我的 icecast2 实例工作正常,并在这个星期天用于我们教堂的服务。但是 docker 容器不见了。 docker ps -a 没有显示任何内容,我无法像往常一样通过 docker exec 访问 nextcloud。我收到错误消息:
No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: [nameserver 8.8.8.8 nameserver 8.8.4.4]"
Feb 06 19:04:58 ncxxxxxxxxx dockerd[21551]: time="2022-02-06T19:04:58.894366765Z" level=info msg="IPv6 enabled; Adding default IPv6 external servers: [nameserver 2001:4860:4860::8888 nameserver 2001:4860:4860::8844]
我的 resolv.conf 看起来像这样:
GNU nano 4.8
/etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search fritz.box
基于@rubensa 的回答,但更简单、更完整的恕我直言:
- 安装dnsmasq
sudo apt-get -y install dnsmasq
- 在/etc/dnsmasq.d/docker-dns-fix.conf配置dnsmasq监听DNS 来自 Docker 并使用 systemd-resolvd 名称服务器的查询
# Use interface docker0
interface=docker0
# Explicitly specify the address to listen on
listen-address=172.17.0.1
# Looks like docker0 interface is not available when dnsmasq service starts so it fails. This option makes dynamically created interfaces work in the same way as the default.
bind-dynamic
# Set systemd-resolved DNS server
server=127.0.0.53
- 通过editing/crea告诉Docker使用dnsmasq
{
"dns": ["172.17.0.1"]
}
- 重启服务
sudo service dnsmasq restart
sudo service docker restart
我的机器在一个私有网络上,有私有 DNS 服务器,以及一个用于 DNS 解析的私有区域。我可以从我的主机解析此区域上的主机,但我无法从我主机上的容器 运行 解析它们。
主机:
root@host:~# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1
root@host:~# ping privatedomain.io
PING privatedomain.io (192.168.0.101) 56(84) bytes of data.
容器:
root@container:~# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 8.8.8.8
nameserver 8.8.4.4
root@container:~# ping privatedomain.io
ping: unknown host privatedomain.io
很明显,Google 的 public DNS 服务器无法解析我的私有 DNS 请求。我知道我可以用 docker --dns 192.168.0.1
强制它,或者在 /etc/default/docker
中设置 DOCKER_OPTS="--dns 192.168.0.1"
,但我的笔记本电脑经常切换网络。似乎应该有一个系统的方法来解决这个问题。
Docker 通过复制主机的 /etc/resolv.conf
并过滤掉任何本地名称服务器(例如 127.0.1.1)来填充 /etc/resolv.conf
。如果在那之后没有留下任何名称服务器,Docker 将添加 Google 的 public DNS 服务器(8.8.8.8 和 8.8.4.4)。
Note: If you need access to a host’s localhost resolver, you must modify your DNS service on the host to listen on a non-localhost address that is reachable from within the container.
主机上的 DNS 服务是 dnsmasq,所以如果你让 dnsmasq 监听你的 docker IP 并将其添加到 resolv.conf,docker 将配置容器使用它作为名称服务器。
1 . Create/edit /etc/dnsmasq.conf
† 并添加以下行:
interface=lo
interface=docker0
2 . 找到您的 docker IP(在本例中,172.17.0.1
):
root@host:~# ifconfig | grep -A2 docker0
docker0 Link encap:Ethernet HWaddr 02:42:bb:b4:4a:50
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
3 . Create/edit /etc/resolvconf/resolv.conf.d/tail
并添加此行:
nameserver 172.17.0.1
4 . 重启网络,更新 resolv.conf
,重启 docker:
sudo service network-manager restart
sudo resolvconf -u
sudo service docker restart
您的容器现在可以从主机使用的任何 DNS 服务器解析 DNS。
† 路径可能是 /etc/dnsmasq.conf
、/etc/dnsmasq.conf.d/docker.conf
、/etc/NetworkManager/dnsmasq.conf
或 /etc/NetworkManager/dnsmasq.d/docker.conf
,具体取决于您的系统和个人喜好。
对于Ubuntu 18.04 和其他使用systemd-resolved 的系统,可能需要安装dnsmasq 和resolvconf。 systemd 解析为 hard-coded to listen on 127.0.0.53, and Docker filters out any loopback address when reading resolv.conf.
1 . 安装 dnsmasq 和 resolvconf.
sudo apt update
sudo apt install dnsmasq resolvconf
2 . 找到您的 docker IP(在本例中为 172.17.0.1):
root@host:~# ifconfig | grep -A2 docker0
docker0 Link encap:Ethernet HWaddr 02:42:bb:b4:4a:50
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
3 . 编辑 /etc/dnsmasq.conf
并添加以下行:
interface=docker0
bind-interfaces
listen-address=172.17.0.1
4 . Create/edit /etc/resolvconf/resolv.conf.d/tail
并添加此行:
nameserver 172.17.0.1
5 . 重启网络,更新 resolv.conf
,重启 docker:
sudo service network-manager restart
sudo resolvconf -u
sudo service dnsmasq restart
sudo service docker restart
您的容器现在可以从主机使用的任何 DNS 服务器解析 DNS。
对于 Ubuntu 18.04 LTS 来说已经足够了:
sudo service network-manager restart
sudo resolvconf -u
sudo service dnsmasq restart
sudo service docker restart
如你所知,Docker复制host/etc/resolv.conf 文件到容器,但删除任何本地名称服务器。
我对这个问题的解决方案是继续使用 systemd-resolvd 和 NetworkManager 但添加 dnsmasq 并将其用于 "forward" Docker 容器 DNS 查询 systemd-resolvd.
分步指南:
- 制作/etc/resolv.conf一个"real"文件
sudo rm /etc/resolv.conf sudo touch /etc/resolv.conf
- 创建文件 /etc/NetworkManager/conf.d/systemd-resolved-for-docker.conf 通知 NetworkManager 通知 systemd-resolvd 但不要触摸 /etc/resolv.conf
[main] # NetworkManager will push the DNS configuration to systemd-resolved dns=systemd-resolved # NetworkManager won’t ever write anything to /etc/resolv.conf rc-manager=unmanaged
- 安装dnsmasq
sudo apt-get -y install dnsmasq
- 在/etc/dnsmasq.conf中配置dnsmasq以监听DNS查询来自 Docker 并使用 systemd-resolvd 名称服务器
# Use interface docker0 interface=docker0 # Explicitly specify the address to listen on listen-address=172.17.0.1 # Looks like docker0 interface is not available when dnsmasq service starts so it fails. This option makes dynamically created interfaces work in the same way as the default. bind-dynamic # Set systemd-resolved DNS server server=127.0.0.53
- 编辑 /etc/resolv.conf 以使用 systemd-resolvd 名称服务器 (127.0.0.53) 和主机 IP (172.17.0.1) 在Docker网络中
# systemd-resolvd name server nameserver 127.0.0.53 # docker host ip nameserver 172.17.0.1
- 重启服务
sudo service network-manager restart sudo service dnsmasq restart sudo service docker restart
有关详细信息,请参阅我的 post(西班牙语)https://rubensa.wordpress.com/2020/02/07/docker-no-usa-los-mismos-dns-que-el-host/
我的 docker 容器中的 DNS 解析器有问题。我尝试了很多不同的东西,最后,我发现我的 Hostgator 中的 CentOS VPS 默认没有安装 NetworkManager-tui (nmtui), 我刚刚安装并重新启动它。
sudo yum install NetworkManager-tui
并使用默认 DNS 重新配置我的 resolv.conf
8.8.8.8
。
nano /etc/resolv.conf
如果您使用的是 VPN,则 VPN 协议可能会附加到超出您专用网络上配置的 MTU 的出站数据包。
典型的 MTU 是 1500。
尝试将此内容添加到 /etc/docker/daemon。json
{
"mtu": 1300,
"dns": ["<whatever DNS server you need in your private network>"]
}
然后systemctl restart docker
.
我的案例有许多来自 docker 集线器(nodered、syncthing 和其他)的图像:
- 容器在非根用户 下运行
- /etc/resolv.conf 容器内的权限为 600 且归 root 所有
所以我的解决方法很简单
root@container:~# chmod 644 /etc/resolv.conf
赚了! :))
我的 systemctl 状态 docker 中有相同的错误消息。 我 运行 一个 Nextcloud 和一个 nextcloud nginx 代理容器,并使用 docker compose 来安装它。它在没有 big hickups 的情况下工作了好几个月,但在星期五它无法访问。服务器已关闭。 我重新启动了它,我的 icecast2 实例工作正常,并在这个星期天用于我们教堂的服务。但是 docker 容器不见了。 docker ps -a 没有显示任何内容,我无法像往常一样通过 docker exec 访问 nextcloud。我收到错误消息:
No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: [nameserver 8.8.8.8 nameserver 8.8.4.4]"
Feb 06 19:04:58 ncxxxxxxxxx dockerd[21551]: time="2022-02-06T19:04:58.894366765Z" level=info msg="IPv6 enabled; Adding default IPv6 external servers: [nameserver 2001:4860:4860::8888 nameserver 2001:4860:4860::8844]
我的 resolv.conf 看起来像这样:
GNU nano 4.8
/etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search fritz.box
基于@rubensa 的回答,但更简单、更完整的恕我直言:
- 安装dnsmasq
sudo apt-get -y install dnsmasq
- 在/etc/dnsmasq.d/docker-dns-fix.conf配置dnsmasq监听DNS 来自 Docker 并使用 systemd-resolvd 名称服务器的查询
# Use interface docker0 interface=docker0 # Explicitly specify the address to listen on listen-address=172.17.0.1 # Looks like docker0 interface is not available when dnsmasq service starts so it fails. This option makes dynamically created interfaces work in the same way as the default. bind-dynamic # Set systemd-resolved DNS server server=127.0.0.53
- 通过editing/crea告诉Docker使用dnsmasq
{ "dns": ["172.17.0.1"] }
- 重启服务
sudo service dnsmasq restart sudo service docker restart