暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Docker资源隔离——认识Cgroup和Namespace

深夜IT研究猿 2019-03-01
2881

K8s是高效的跨集群容器编排工具,容器是由Cgroup、Namespace、rootfs、容器引擎等核心部分组成,今天在这里主要为大家介绍Cgroup和Namespace。



一、Cgroup简介

Cgroup是种可以限制、记录、隔离进程组 (process groups) 所使用的物力资源的机制。Namespace主要解决的是环境隔离的问题,是一种轻量级的虚拟化形式,使容器置身一个独立的系统环境中。如果将一台机器比作一栋楼,那么通过Namespace隔离出来的空间就好比这栋楼中的每个房间,每个房间中有什么东西,有多少东西那就是Cgroup在起作用了,这么类比可能不太贴切,因为Cgroup和Namespace不是谁包含谁的关系,但是小猿我认为这么类比印象会比较深刻。

Cgroup和Namespace毕竟都是Linux内核的东西,我们也无需深入代码层面去剖析,除非你有那个需求,那么接下来就为大家简单的介绍一下这两种内核特性。

谈及cgroup,也就是房子中都有些什么东西,东西的量有多少,就会涉及到它的四个相关概念:

a、任务(task):在 Cgroup 中,任务就是系统的一个进程.

b、控制族群(controlgroup):一组按照某种标准划分的进程。Cgroup 中的资源控制都是以控制族群为单位实现

c、层级(hierarchy)。控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性;

d、子系统(subsystem)。一个子系统就是一个资源控制器,比如CPU子系统就是控制 CPU时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。

当然这些都是百度百科的结果,看完第一遍的时候自己也是一知半解,半脸懵逼,接下来我看到了大多文章都会用到的一张图:

这张图是讲层级关系的,类似于二叉树的形式,其实就是文件夹的一层一层嵌套,形成了上述的层级。在实际中看到的就是下图这种形式:

上面说cgroup是linux限制资源的机制,它所限制的资源就是上图第一次ls的那些子系统所代表的东西,顾名思义:

  • blkio — 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等)

  • cpu — 这个子系统使用调度程序提供对CPU 的Cgroup 任务访问。

  • cpuacct — 这个子系统自动生成Cgroup 中任务所使用的CPU 报告。

  • cpuset — 这个子系统为Cgroup 中的任务分配独立CPU(在多核系统)和内存节点。

  • devices — 这个子系统可允许或者拒绝Cgroup 中的任务访问设备。

  • freezer — 这个子系统挂起或者恢复Cgroup 中的任务。

  • memory — 这个子系统设定Cgroup 中任务使用的内存限制,并自动生成内存资源使用报告。

  • net_cls — 这个子系统使用等级识别符(classid)标记网络数据包,可允许Linux 流量控制程序(tc)识别从具体 cgroup中生成的数据包。

  • net_prio — 这个子系统用来设计网络流量的优先级

  • hugetlb — 这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统。


二、使用Cgroup限制CPU使用率

这里以CPU为例,实际操作了一下,

1.进入Cgroup的CPU层级:cd sys/fs/cgroup/cpu,cpuacct

2.创建一个文件夹f1(层级f1):mkdir f1 && cd f1

3.将当前bash的进程号放入tasks:echo $$ > cgroup.procs

4.设置CPU的可用时间分片:echo 20000 > cpu.cfs_quota_us

5.理论上进程的CPU最大使用率 = cpu.cfs_quota_us cpu.cfs_period_us = 20000/100000 = 20%

6.实际上,执行一个无限循环脚本进行测试,发现CPU最多使用20%

7.理论值=实际值,可以看出,确实是起到了限制的作用,而且是强限制。

对于Cgroup父-子层级关系可以理解为父Cgroup是大房间,子Cgroup就是从大房间中划分出来的一个小房间,大房间中有什么,小房间中就能用什么,当然使用什么以及使用多少也会受到大房间的限制,毕竟不能无中生有还要遵循“质量守恒”。


三、Namespace简介

说完了房子中都有什么东西以及多少可以使用之后,接下来就是介绍这个房子的外围了,也就是前面说的内核特性之一的Namespace。

Namespace的种类(也可以说是构建房子外围的材料)有6种,分别是IPC,Network,Mount,PID,User,UTS,每一个种类都有自己的功能。相同种类的Namespace隔离出来的每个房间都会有一套相同的装修,这让他们在自己内部看起来是别无二致的,只是在整栋楼的范围来看有区别,比如楼层位置的差别。

就拿Mouut namespace来说,实现不同mount 命名空间的进程看到的文件系统层次不一样。也就是说,不同的容器,以及容器与主机之间,可以出现不同目录结构;当然也可以出现相同的目录结构,但是他们在磁盘的位置不一样。

或者就PID namespace而言,每个容器内部的进程应该拥有独立的PID,在Linux里面,init进程的PID是1,容器化后,每个容器都有一个1以及由1衍生的子进程和子进程的子进程。

对于其余的namespace种类,实现方式类似,只是实现的功能不同而已。



四、Namespace的不足

实际生活中构建房子的材料不止6种,同样,Namespace仍旧会有一些隔离不太完善,因为Docker容器共享主机内核,因此某些层面没有做到完全的隔离。

就小猿我了解到的而言有 /proc、/sys等未完全隔离;top, free, iostat等命令展示的信息未隔离;Root用户未隔离;/dev设备未隔离;内核模块未隔离;SELinux、time、syslog等所有现有Namespace之外的信息都未隔离等等。

举例来说:Docker 起一个容器,限制内存上限为500m,但是在容器内部free -h查看到的仍是宿主机的内存:

到此,关于房子外围是什么,房子内部是什么,有多少东西,也就是我们说的Namespace,Cgroup基本介绍完了,小猿个人能力有限,如有错误,你顺着网线来打我呀!


文章转载自深夜IT研究猿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论