通过使用LXCFS提供容器CPU,内存正确限制

自在的LEE · · 2489 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

我是LEE,老李。

今天跟大家分享一个Docker底层软件利器 - lxcfs。 我们先从一些场景和问题开始了解起这个软件到底有什么用。

1. 大家在日常使用docker,尤其是在生产系统为了避免某些容器过分使用CPU或者内存,与其他的容器发生资源争抢,都会在docker启动加上资源限制。但是实际工作中docker的通过cgroup做的资源隔离真的是那么满意吗? 容器内看到的还是宿主机的资源。

2. 我们的研发小伙在开发服务端( golang中 runtime.GOMAXPROCS(runtime.NumCPU()) ) 或者运维小伙伴在设置服务启动进程数量的时候( 比如 nginx 配置中的 worker_processes auto ),都喜欢通过程序自动判断所在运行环境CPU的数量。

3. golang的小伙伴在编译好的代码,在一个docker中运行的时候,gc时候使用的内存应该是怎么计算呢? 是不是应该按照我们在直接从系统中直接获得内存来设定呢?

当然这样的情况还有很多很多,我就不一一列举。为啥突然要说这个,是因为今天最近自己做研究和设计时候,碰到这个问题。记得那是2017的时候曾经也碰到这样要求,可是社区没有太多解决方案,后来美团也提出了解决思路,并提议修改。 但是看到回馈说是,老外觉得这个需求不重要,而且在一定程度违背了docker的设计理念。最后当时的工作不得不停下来了,换用别的方案来解决。

现在已经到2019年了,什么都是快速发展的( 好像最近下岗也是很快速的,唉! ),我想回去看看这个问题解了吗? 今天偶然测试了一下。 好像这个问题已经得到解决,虽然还有一些地方需要改进,但是通过今天的测试发现已经到了可以使用的程度。所以决定将 lxcfs 的测试效果分享给大家。 以后再docker底层资源隔离这方面( 至少在CPU和内存方面 ),可以做到跟虚拟机比较像。 也方便以后小伙伴能够将虚拟机上跑的业务平滑的过度到docker里。

好了,言归正传,我们了解下 lxcfs 的机制:

lxcfs 是一个开源的FUSE(用户态文件系统)实现来支持LXC容器,它也可以支持Docker容器。让容器内的应用在读取内存和CPU信息的时候通过lxcfs的映射,转到自己的通过对cgroup中容器相关定义信息读取的虚拟数据上。 有点绕,没有关系我们往下继续看。

LXCFS通过用户态文件系统,在容器中提供下列 procfs 的文件。

/proc/cpuinfo

/proc/diskstats

/proc/meminfo

/proc/stat

/proc/swaps

/proc/uptime


简单的说一句话说:就是通过文件挂载的方式,把cgroup中关于系统的相关信息读取出来,通过docker的volume挂载给容器内部的proc系统。 然后让docker内的应用读取proc中信息的时候以为就是读取的宿主机的真实的proc。

挂载命令也非常的简单:   lxcfs /var/lib/lxcfs   就OK了。 是不是突然觉得这个世界挺美好的。 

这里我们用内存资源举例:

lxcfs 内存使用架构图

当我们把宿主机的 /var/lib/lxcfs/proc/memoinfo 文件挂载到Docker容器的/proc/meminfo位置后。容器中进程读取相应文件内容时,LXCFS的FUSE实现会从容器对应的Cgroup中读取正确的内存限制。从而使得应用获得正确的资源约束设定。 CPU这块原理一样,这里就不做列举,自行脑补。

我们看看挂载前后的差别: (环境准备了一台虚拟机 2C1G 的环境)

挂载前:

执行命令: docker run --cpus 1 --memory 50m -it ubuntu bash

容器内存跟宿主机一样是1G

容器内存

容器CPU跟宿主机一样2核

容器CPU

好像docker run起来没有啥效果嘛? 

挂载后:

执行命令: docker run --cpus 1 --memory 50m -it -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw -v /var/lib/lxcfs/proc/stat:/proc/stat:rw -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw ubuntu bash

容器内存跟宿主机不一样,是50M


容器内存

容器CPU跟宿主机不一样,是1核


容器CPU

嘿嘿,docker run 起来,起到应该有的效果了。 以后我们从虚拟机转移代码到容器的时候,再也不用担心CPU和内存资源获得总数不正确了。



小Tips:

容器的CPU设置有两种方式,一个是--cpus 2,限定容器最多只能使用两个逻辑CPU,另一个是--cpuset-cpus "0,1",限定容器 可以使用的宿主机CPU。

top命令显示的是容器 可以使用的 宿主机cpu,如果使用--cpus 2,看到的cpu个数是宿主机上的cpu个数。使用--cpuset-cpus "0,1"的时候,在容器看到cpu个数是--cpuset指定的cpu的个数。


当然最后不能忘记分享我编译好的 lxcfs 二进制软件包:

https://pan.baidu.com/s/14iz_2wrrjgwe2hbnBMzYUg

使用非常简单:

# rpm -ivh lxcfs-3.0.4-1.el7.x86_64.rpm

# systemctl enable lxcfs.service

# systemctl start lxcfs.service


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:自在的LEE

查看原文:通过使用LXCFS提供容器CPU,内存正确限制

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2489 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传