docker:EC2实例中堆栈中的容器不继承dns名称服务器
我已经在AWS上设置了一个EC2实例 已正确设置我的安全组,以便实例能够访问Internet,例如docker:EC2实例中堆栈中的容器不继承dns名称服务器,docker,docker-networking,Docker,Docker Networking,我已经在AWS上设置了一个EC2实例 已正确设置我的安全组,以便实例能够访问Internet,例如 ubuntu@ip-10-17-0-78:/data$ ping www.google.com PING www.google.com (216.58.211.164) 56(84) bytes of data. 64 bytes from dub08s01-in-f4.1e100.net (216.58.211.164): icmp_seq=1 ttl=46 time=1.02 ms 64 by
ubuntu@ip-10-17-0-78:/data$ ping www.google.com
PING www.google.com (216.58.211.164) 56(84) bytes of data.
64 bytes from dub08s01-in-f4.1e100.net (216.58.211.164): icmp_seq=1 ttl=46 time=1.02 ms
64 bytes from dub08s01-in-f4.1e100.net (216.58.211.164): icmp_seq=2 ttl=46 time=1.00 ms
但是,当我执行到容器中时,这是不可能的:
root@d1ca5ce50d3b:/app# ping www.google.com
ping: www.google.com: Temporary failure in name resolution
更新\u 1:连接问题与特定堆栈中使用docker stack deploy
启动的容器有关
当我刚启动一个独立容器时,可以连接到Internet:
ubuntu@ip-10-17-0-78:/data$ docker run -it alpine:latest /bin/ash
/ # ping www.google.gr
PING www.google.gr (209.85.203.94): 56 data bytes
64 bytes from 209.85.203.94: seq=0 ttl=38 time=1.148 ms
64 bytes from 209.85.203.94: seq=1 ttl=38 time=1.071 ms
更新_2:经过调查,结果表明:
- 独立容器,继承EC2实例的dns名称服务器李>
- 通过
donot启动的容器李>docker stack deploy
- 通过
docker swarm
启动的容器:
ubuntu@ip-10-17-0-78:~$ docker exec -it d1ca5ce50d3b bash
root@d1ca5ce50d3b:/app# cat /etc/resolv.conf
search eu-west-1.compute.internal
nameserver 127.0.0.11
options ndots:0
更新_3:当我用docker compose
而不是docker stack deploy
启动堆栈时,问题也是一样的;似乎不是特定于swarm的问题
update_4:我已明确添加了gfile/etc/docker/daemon.json
,内容如下:
{
"dns": ["10.0.0.2", "8.8.8.8"]
}
ubuntu@ip-10-17-0-78:/data$docker运行busybox nslookup google.com
服务器:8.8.8.8
地址:8.8.8.8:53
非权威性回答:
名称:google.com
地址:216.58.211.174
***找不到google.com:没有答案
但查找仍然失败:
有什么建议可以解释为什么会出现这种情况吗?我刚刚遇到了一个类似的问题。我知道这是11个月前的事了,但是要找到关于这个话题的信息有点困难,所以我会在这里发布信息 我的问题是docker swarm overlay网络的默认子网与我的vpcs子网重叠,因此在我的例子中,默认的amazon ec2 dns服务器(10.0.0.2)混淆了docker守护进程的ip地址路由,认为它是swarm overlay本地服务(我认为)。无论如何,我通过stack files networking:部分更改了默认覆盖子网,解决了问题。我的docker守护程序再次开始解析10.0.0.2 vpc dns服务器 如果将节点docker daemon放在调试模块中(在linux上
/etc/docker/daemon.json
,将“debug”:true
添加到json中),则可以通过跟踪特定系统上的守护进程日志来监视调试输出。如果守护进程通过systemd运行,journalctl-u docker
将向您提供日志<代码>-f将跟随日志
在那里,我找到了有关连接问题的信息(docker daemon未能在10.0.0.2:54(udp dns端口)上与dns服务器取得联系)。然而,nslookup在主机操作系统上运行良好,/etc/resolve.conf
看起来很合适。如果您使用docker exec在其中一个正在运行的服务中获取交互式/bin/sh
,那么问题很明显。对于任何外部域,nslookup都会失败,docker守护进程调试日志会显示更多关于10.0.0.2的“连接被拒绝”类型的消息。在查看了docker对dns解析的支持问题一两个小时后,我发现了一条评论,指出docker swarm虚拟网络是根据一些默认值分配的地址,有时这些默认值与您设置本地子网的方式重叠。我推断,如果它们与我的vpc上的dns服务器重叠,它可能试图在群内路由dns数据包,而不是解析到vpc子网路由。[edit@2020-02-10]虽然我认为下面的内容可能仍然很有趣,但我不再认为这是解决问题的最佳方法。这并不意味着它不起作用,但它需要调整docker compose.yml
以适应它将要启动的环境,而人们更希望正确地进行修改
免责声明:这个“答案”与其说是一个授权的解决方案,不如说是一个记录让它看起来对我有用的事情,以及它们是如何产生的 鉴于:
- AWS EC2 docker主机实例的私有IP地址在
范围内李>10.0.0.0/16
- 已被
序列化李>docker swarm init
- 它有一个应用程序,比如说
,部署为myapp
李>docker stack deploy-c docker-compose.yml myapp
- Docker将为
网络为每个容器分配一个myapp_默认值
专用范围之外的IP地址10.0.x.0/24
这可以从docker network inspect myapp|u default | less-p'10\.0(\.[0-9]+){2}'的输出推断出来。李> - EC2实例本身可以访问
(AWS提供)以获取其DNS李>10.0.0.2
- 但是,从docker容器中进行DNS查找会失败-除非
守护进程已额外配置为与公共DNS服务器联系(如dockerd
)-并且实例的安全组允许此类通信dockerd--DNS 8.8.8…
OP也已经发现了这一点 - 显式执行
似乎没有任何帮助李>dockerd-dns10.0.0.2…
dockerd
无法在其myapp_默认
网络的私有10.0.x.0/24
范围与其EC2主机实例所在的网络之间调解DNS查找;毕竟,它们仍然是两个完全断开连接的网络,只是碰巧选择了重叠的ip范围,但是很显然,@Josh已经指出了这一点
此外,考虑到这一问题的根源是什么,人们不禁想知道为什么“docker”没有自动检测到这种情况,然后简单地为myapp\u默认值
网络选择一个不重叠的范围
会的
networks:
default:
ipam:
config:
-
subnet: '192.168.0.0/24'
driver: 'default'
Server:
…
Swarm: active
…
Default Address Pool: 10.0.0.0/8
SubnetSize: 24
…
Server:
Swarm: active
…
Default Address Pool: 192.168.0.0/16
SubnetSize: 24
…
[
{
"Name": "myapp_default",
…
"Containers": {
"…": {
…
"IPv4Address": "192.168.1.12/24",
},
…
},
…