WVP学习–一、优化内存
部署完zlm后发现一个问题,服务器原本的内存8个G,基本没有安装其他应用,但是装完zlm后发现内存已严重不足,如下图
为什么zlm会这么迟内存呢?
于是使用如下命令查看查看实际内存占用
docker stats
执行完成后发现实际内存不到100M,那就奇怪了,内存去哪儿了?
简单起见,将zlm移除,发现内存马上下来,其实问题还是出在zlm上。那使用内存命令看看占内存的应用吧
top -o %MEM
看完上面的截图可以发现,最大的服务占用内存也只有0.4%,那说明不是某个服务内存占用大引起的,那么是不是服务多的问题造成的呢?我们发现里面存在着大量的docker-proxy服务,该服务虽然每个占用很少只有0.1%左右,由于这里保留的两位小数实际上可能存在四舍五入不足导致进位的情况,那么按最少占用情况起码也得0.05%,然后乘以8G,大概就4M左右,但是禁不住服务多啊。
接着往下查,看看这玩意儿是干嘛的,为什么会这么多
ps -ax|grep docker-proxy
这服务好几页啊,然后发现基本是指向容器端口的。30382、20383、30384。。。30500,等等怎么这么熟悉?这不就是zlm的配置docker-compose里面的端口吗
这里tcp+udp约1000个配置,那么乘以至少4M的内存占用那不得至少4个G就没了吧,实际上6,7个G,所以服务器的8个G内存就这样被耗没了,难怪光看zlm其实占用不高,但是实际内存一下就没了。
现在来看看这个是什么,网上查了一下,大概是这么说的:
众所周知,在Docker的桥接bridge网络模式下,Docker容器是通过宿主机上的NAT模式,建立与宿主机之外世界的通信。然而在宿主机上,一般情况下,进程可以通过三种方式访问容器,分别为:
: 走iptables nat映射方式
: 走iptables nat 映射方式
<0.0.0.0>:走docker-proxy映射方式
容器互相访问
实际上,最后一种方式的成功访问完全得益于userland-proxy,即Docker Daemon在启动一个Docker容器时,每次为容器在宿主机上映射一个端口,都会启动一个docker-proxy进程,实现宿主机上0.0.0.0地址上对容器的访问代理。我们发现docker-proxy生成的映射规则是-host-ip 0.0.0.0,也就是说只有以<0.0.0.0>:
形式访问时,才会走代理路径。为什么是这样的逻辑呢?根源在于iptalbes的缺陷,对于0.0.0.0支持很差(或者压根就不支持,待研究),因此通过docker-proxy来实现访问的补充。
详细例子:
场景 | 开启docker-proxy时刻 | 关闭docker-proxy时刻 |
---|---|---|
外部主机访问目标主机192.168.126.222:8080 | 通过iptables nat规则访问 | 通过iptables nat规则访问 |
在主机上访问容器192.168.126.222:8080 | 通过iptables nat规则访问 | 通过iptables nat规则访问 |
在主机上访问目标容器127.0.0.1:8080 | 通过docker-proxy 转发 | 通过iptables nat规则访问 |
在主机上其他容器内部访问目标容器 172.17.0.4:8080 | 通过docker proxy转发 | 通过iptables nat规则访问 |
怎么理解?大意就是说通过该台机器访问自身docker容器中的内容都是做了优化,无论是在该机器上访问某个docker容器还是该机上上其他容器访问该容器都是走的docker-proxy转发,只有非丐太机器上访问才是走的nat。本人尝试过关闭docker-proxy,发现同一台上的某些服务并不能访问同一台上的mysql,可能就是前面说的0.0.0.0支持的不是很好的原因,所以在不确定自己的服务是否存在调用同一台机器上其他服务的时候不建议关闭docker-proxy.
由于这里不存在当前zlm主机访问其他服务或者被当前机器的其他服务访问的情况,因此可以考虑关闭docker-proxy,毕竟这内存占用不是唬人的。
首先找到docker的daemon.json文件位置,一般在/etc/docker目录下,加上如下配置
"userland-proxy": false
重启docker 服务
systemctl restart docker
发现docker-proxy的服务消失了
最新的内存占用也恢复了正常
发表回复
要发表评论,您必须先登录。