docker网络的疑难问题之三
侧边栏壁纸
博主昵称
yuc

  • 累计撰写 291 篇文章
  • 累计收到 0 条评论

docker网络的疑难问题之三

yuc
yuc
2024-07-29 / 最后修改: 2024-07-29 10:27 / 0 评论 / 3 阅读 / 正在检测是否收录...
前提背景

20240701 继之前的docker网络的dns解析问题 疑难问题如鲠在喉,如果不能解决,始终是一个风险,这里记录下来,尽快找到办法解决

  1. 关于 dns 解析的问题,现象为:如果本机宿主机上同时配置了VIP+BIND容器,这也是我们需要的模式,并且本机/etc/resolv.conf配置了VIP作为nameserver,那么其他容器则无法解析外网地址,容器内默认的/etc/resolv.conf配置为127.0.0.11。其他机器容器可以正常解析。这个情况在之前的帖子已经追踪过,经过排查后发现可能是NAT有问题,所以BIND服务不能使用与其他容器相同的overlay网络,而是改成host模式,当然目前来看,为了保证必定不出问题,最好是把bind服务隔离到单独的一台机器上,这样就完全避免了本机的nat转换错误问题

  2. 关于容器内访问 nginx 错误问题 从其他容器访问nginx,发现必定出现两次拒绝,一次可以访问。发现正好对应了 nginx 有三个副本,便使用 curl -v 查看了访问的ip地址,都是一样的。

[root@253258ad95d3 /]# curl http://nginx
curl: (7) Failed connect to nginx:80; 拒绝连接
[root@253258ad95d3 /]# curl http://nginx
curl: (7) Failed connect to nginx:80; 拒绝连接
[root@253258ad95d3 /]# curl http://nginx
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>

查询三个 nginx 容器的ip地址,可以看到其实容器内部访问过程中还是有负载均衡的,如果是多个副本,并不会直接访问到某一个节点上,而是访问到了另外一个ip

172.21.1.185    # 其他容器curl http://nginx 解析的ip
172.21.0.200    # 节点一ip
172.21.11.227   # 节点二ip
172.21.23.214   # 节点三ip

第一个IP是容器内dns解析到的VIP(docker swarm VIP策略),另外三个则是 nginx 服务器的 3 副本实际ip

可以猜测是到了overlay网络的负载均衡地址,而overlay网络的VIP模式负载均衡是用ipvs实现的。那么如何证明呢? 我们可以进入 /var/run/docker/netns 目录下,这里包括了本机的容器、网络配置的命名空间。其中有几个特殊的是网络的,可以看到其中有一个是 lb_1jo63pzkt,这个前缀 lb + 后面的 id 刚好是我们需要的overlay id,所以基本上确定是这个

使用命令进入 nsenter --net=lb_1jo63pzkt sh 接着可以使用命令查询防火墙规则和ipvs规则,需要注意的是,这里的命令是调用的宿主机操作系统命令,所以宿主机需要提前安装ipvs,yum -y install ipvsadm 查看防火墙mangle规则:

iptables -L -t mangle -n 
MARK       all  --  0.0.0.0/0            172.21.1.185         MARK set 0x11e

第一行是 nginx 的VIP规则,其中最后的MARK打标值为 0x11e,转换为10进制为286 接着查看 ipvs 规则:

ipvsadm -l
FWM  286 rr
  -> 172.21.0.200:0               Masq    1      0          0
  -> 172.21.11.227:0              Masq    1      0          0
  -> 172.21.23.214:0              Masq    1      0          0

根据MARK值286可以找到对应的三个转发条目。那么172.21.1.185是怎么回事呢?如何解释呢? 既然打标和转发都有了,可以确定172.21.1.185 ip应该是在本机的,否则怎么转发呢? 所以通过 ifconfig命令查看,发现此ip在接口上,同时可以看到此接口还有非常多的额外ip,应该都是其他容器的VIP地址,附加到这里做ipvs转发

最终方案

选择解藕服务,前面增加4层nginx,高可用放到此处,VIP也不再放到docker集群中,docker集群只需要保证自身的集群高可用即可,docker中再运行7层nginx,接受4层的请求。至此VIP所在机器上的容器无法解析dns的问题解决

20240702 nginx启动
docker service create --name nginx \
--mount type=bind,src=/docker/others/nginx/conf,dst=/usr/local/nginx/conf \
--mount type=bind,src=/docker/others/nginx/conf.d,dst=/usr/local/nginx/conf.d \
--mount type=bind,src=/docker/others/nginx/logs,dst=/usr/local/nginx/logs \
--network mynets \
-p target=80,published=80 \
-p target=443,published=443 \
-p target=8080,published=8080 \
--constraint node.role==manager \
--replicas 1 \
harbor.succez.com/sz/nginx-v20220701v1
0

评论

博主关闭了当前页面的评论