引子
最近在研究k8s,学习到容器的一些知识。了解到docker的核心原理:
- 利用linux namespace 隔离资源;
- 利用cgroups 限制资源的使用;
- 利用chroot 改变进程的根目录到指定的目录;
我来详细的了解下cgroups。
物理机是4C8G 首先看下操作的系统版本
基本概念
Cgroups全称为:linux Control Group,crgroups为每种可以控制的资源定义了一个子系统。这么说有点抽象,直白点它的主要作用就是限制一个进程组能够使用cpu、内存、磁盘、带宽等资源的上限。提供以下功能:
- 限制资源使用,各种子系统的资源限制;
- 优先级控制,cpu使用、内存、磁盘io吞吐等;
- 资源使用报告,可以用来计费;
- 控制,挂起、恢复进程;
子系统
我们看下都有哪些子系统。
- systemd 是维护的自己使用子系统;
- net_cls,net_prio :可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制;
- pids:可以限制cgroup的进程数,里面有各种策略;
- cpuset:如果为多核cpu,可以为cgroups中的任务分配单独的cpu和内存;
- memory :设置每个cgroup的内存限制以及产生内存资源报告
- hugetlb:这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统;
- perf_event:增加了对每group的监测跟踪的能力,即可以监测属于某个特定的group的所有线程以及运行在特定CPU上的线程,此功能对于监测整个group非常有用
- blkio:可以限制进程的块设备(磁盘、usb)的输入/输出存取限制;
- devices:可以控制进程能够访问某些设备
- cpu:主要限制进程的cpu使用率
- cpuacct:可以统计cgroups中的进程使用cpu的资源报告
- freezer:可以挂起或者恢复cgroups中的进程
cgroup形态
- hierarchy: cgroups从用户态看,提供了一种组cgroup类型的文件系统(Filesystem),这是一组虚拟的文件系统,通过对这个文件系统的配置,告诉内核,如何希望对哪些进程使用多少资源。文件系统本身是层级的,所以构成了hierarchy。
- task:进程在cgroups中称为task,taskid就是pid;
- subsystem:cgroup支持的所有可配置的资源称为子系统,如:cpu、内存、网络等都是子系统;
- libcgroup: 一个开源的软件,提供一组cgroups的应用程序和库;
cgroups 层级结构(Hierarchy)
内核使用 cgroup 结构体来表示一个 control group 对某一个或者某几个 cgroups 子系统的资源限制。cgroup 结构体可以组织成一颗树的形式,每一棵cgroup 结构体组成的树称之为一个 cgroups 层级结构。
cgroups层级结构可以 attach 一个或者几个 cgroups 子系统,当前层级结构可以对其 attach 的 cgroups 子系统进行资源的限制。每一个 cgroups 子系统只能被 attach 到一个 cpu 层级结构中。
好好理解下这个图即可:
创建了 cgroups 层级结构中的节点(cgroup 结构体)之后,可以把进程加入到某一个节点的控制任务列表中,一个节点的控制列表中的所有进程都会受到当前节点的资源限制。同时某一个进程也可以被加入到不同的 cgroups 层级结构的节点中,因为不同的 cgroups 层级结构可以负责不同的系统资源。所以说进程和 cgroup 结构体是一个多对多的关系。
上面这个图从整体结构上描述了进程与 cgroups 之间的关系。最下面的P代表一个进程。每一个进程的描述符中有一个指针指向了一个辅助数据结构css_set(cgroups subsystem set)。指向某一个css_set的进程会被加入到当前css_set的进程链表中。一个进程只能隶属于一个css_set,一个css_set可以包含多个进程,隶属于同一css_set的进程受到同一个css_set所关联的资源限制。
上图中的”M×N Linkage”说明的是css_set通过辅助数据结构可以与 cgroups 节点进行多对多的关联。但是 cgroups 的实现不允许css_set同时关联同一个cgroups层级结构下多个节点。这是因为 cgroups 对同一种资源不允许有多个限制配置。
一个css_set关联多个 cgroups 层级结构的节点时,表明需要对当前css_set下的进程进行多种资源的控制。而一个 cgroups 节点关联多个css_set时,表明多个css_set下的进程列表受到同一份资源的相同限制。
我们来实际操作下:
我们可以看到21699把进程打满了
之前我们创建的cpu子系统,没有说明对哪些资源做怎么样的限制,我们操作下
我们再top看下
cpu已经限制在了50%了。
此处有两个参数:
- cpu.cfs_quota_us 默认值-1,此值越高cpu使用率越高
- cpu.cfs_period_us 默认值100000,表示cpu的时间片分为100000份,此值越低cpu使用越高
容器技术就是通过这一系列的子系统来限制资源的使用。
如果觉得对你有帮助,请关注公众号:5ycode,后续会不断更新哦