记一次docker容器bridge网络访问异常缓慢问题

  • 内容
  • 评论
  • 相关

由于公司YAPI被不知名的访客注册了N多垃圾账号,为了防止后期继续出现这种情况遂打算将YAPI服务宿主防火墙重新配置一下,调整为YAPI服务只能通过内网访问,外网访问则需经过NGINX密码认证。由于非主业务服务,配置过程也是采用最暴力的方式,直接清空iptables现有规则,删除掉firewalld配置目录下的zones目录,然后重启firewalld并重新配置防火墙策略。

配置过程很顺利,配置完防火墙后访问YAPI服务也很正常。SO EASY!当然就在奶嘴以为万事大吉的时候,开始出事了。陆续有同事反馈和YAPI同服务器的禅道打开异常缓慢,打开一个页面大概要10~40s。

问题不大,不慌。一顿操作打开FPM慢日志:

从慢日志来看,是数据库连接引起??

慢日志信息量很少很难判断问题,祭出strace,找到fpm woker进程打进去,多刷新几次禅道的页面,出现以下信息

从进程的network调用信息来看,和mysql的通信都是卡在首次向MYSQL发送数据的时候,第二次再发送数据就是毫秒级响应了。这下就有点奇怪了,都是都在一个内网的服务,为何首次通信需要耗时这么长呢?inspect看了下容器网络,bridge模式。

有点没头绪,翻了下docker官网文档以及docker博客:https://docs.docker.com/network/bridge/  、 https://www.docker.com/blog/understanding-docker-networking-drivers-use-cases/

发现对docker bridge网络模式有这么一段描述:

Behind the scenes, the Docker Engine creates the necessary Linux bridges, internal interfaces, iptables rules, and host routes to make this connectivity possible. In the example highlighted below, a Docker bridge network is created and two containers are attached to it. With no extra configuration the Docker Engine does the necessary wiring, provides service discovery for the containers, and configures security rules to prevent communication to other networks. A built-in IPAM driver provides the container interfaces with private IP addresses from the subnet of the bridge network.

大意是bridge网络下docker需要建立虚拟网卡,并且建立一个网桥到docker虚拟网卡,然后通过网桥将网络数据转发到对应的docker容器。

难道是网桥数据转发这块出问题了?窗口直接拉到MYSQL容器所在的宿主,查看防火墙配置

防火墙的转发功能是关闭的。将masquerade功能打开,再次尝试访问禅道,瞬间恢复正常???

这时奶嘴有个疑问,讲道理,如果是按docker官方的说法,正常情况应该是masquerade没开bridge模式的容器应该是无法访问才对啊?为何会出现容器能访问但是响应异常缓慢的情况呢?打开谷歌、gitlab乱翻一通。发现一个老哥对此问题的回复(@https://github.com/moby/moby/issues/11911):

So, I'm going to completely ignore the metrics you provided and answer why this test would perform so slow in that one scenario.
The reason actually has nothing to do with the bridge, or NAT. The issue is likely that your redis-benchmark utility is connecting to localhost. When using container port forwarding, connecting to localhost from the docker host goes through the docker proxy. Meaning it does not use the iptables port redirection. The docker proxy is a userspace utility which forwards the TCP connection on to the container. Userspace utilities are inefficient when compared to the kernel.

哦吼,破案~原来是docker在通信的时候如果数据不从网桥转发的话会默认通过docker proxy代理来转发,但是用户空间的docker proxy程序效率实在是太烂了。。。所以

 

本文搜索关键字

docker firewalld  docker防火墙 docker centos7防火墙 docker容器网络慢 docker网络很慢


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可,非商业性质可转载须署名链接,详见本站版权声明。

评论

0条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注