浅谈Linux Cgroups机制

2021-09-15  本文已影响0人  夏胖运维

来源:浅谈Linux Cgroups机制 - 知乎 (zhihu.com)

1. Cgroups简介

1.1 功能和定位

Cgroups全称Control Groups,是Linux内核提供的物理资源隔离机制,通过这种机制,可以实现对Linux进程或者进程组的资源限制、隔离和统计功能。

比如可以通过cgroup限制特定进程的资源使用,比如使用特定数目的cpu核数和特定大小的内存,如果资源超限的情况下,会被暂停或者杀掉。

Cgroup是于2.6内核由Google公司主导引入的,它是Linux内核实现资源虚拟化的技术基石,LXC(Linux Containers)和docker容器所用到的资源隔离技术,正是Cgroup。

1.2 相关概念介绍

概念间的关系:

cgroup关系图如下:

img

两个任务组成了一个 Task Group,并使用了 CPU 和 Memory 两个子系统的 cgroup,用于控制 CPU 和 MEM 的资源隔离。

1.3 子系统

1.4 cgroups文件系统

Linux通过文件的方式,将cgroups的功能和配置暴露给用户,这得益于Linux的虚拟文件系统(VFS)。VFS将具体文件系统的细节隐藏起来,给用户态提供一个统一的文件系统API接口,cgroups和VFS之间的链接部分,称之为cgroups文件系统。

比如挂在 cpu、cpuset、memory 三个子系统到 /cgroups/cpu_mem 目录下

mount -t cgroup -o cpu,cpuset,memory cpu_mem /cgroups/cpu_mem

关于虚拟文件系统机制,见浅谈Linux虚拟文件系统机制

2. cgroups子系统

这里简单介绍几个常见子系统的概念和用法,包括cpu、cpuacct、cpuset、memory、blkio。

2.1 cpu子系统

cpu子系统限制对CPU的访问,每个参数独立存在于cgroups虚拟文件系统的伪文件中,参数解释如下:

2.2 cpuacct子系统

子系统生成cgroup任务所使用的CPU资源报告,不做资源限制功能。

通过cpuacct如何计算CPU利用率呢?可以通过cpuacct.usage来计算整体的CPU利用率,计算如下:

# 1. 获取当前时间(纳秒)
tstart=$(date +%s%N)
# 2. 获取cpuacct.usage
cstart=$(cat /xxx/cpuacct.usage)
# 3. 间隔5s统计一下
sleep 5
# 4. 再次采点
tstop=$(date +%s%N)
cstop=$(cat /xxx/cpuacct.usage)
# 5. 计算利用率
($cstop - $cstart) / ($tstop - $tstart) * 100

2.3 cpuset子系统

适用于分配独立的CPU节点和Mem节点,比如将进程绑定在指定的CPU或者内存节点上运行,各参数解释如下:

2.4 memory子系统

memory子系统主要涉及内存一些的限制和操作,主要有以下参数:

2.5 blkio子系统 - block io

主要用于控制设备IO的访问。有两种限制方式:权重和上限,权重是给不同的应用一个权重值,按百分比使用IO资源,上限是控制应用读写速率的最大值。

按权重分配IO资源:

按上限限制读写速度:

针对特定操作 (read, write, sync, 或 async) 设定读写速度上限

3. cgroups的安装和使用

测试环境为 ubuntu 18.10

3.1 cgroups的安装

  1. 安装 cgroups
sudo apt install cgroup-bin

安装完成后,系统会出现该目录/sys/fs/cgroup

  1. 创建cpu资源控制组,限制cpu使用率最大为50%
$ cd /sys/fs/cgroup/cpu
$ sudo mkdir test_cpu
$ sudo echo '10000' > test_cpu/cpu.cfs_period_us
$ sudo echo '5000' > test_cpu/cpu.cfs_quota_us
  1. 创建mem资源控制组,限制内存最大使用为100MB
$ cd /sys/fs/cgroup/memory
$ sudo mkdir test_mem
$ sudo echo '104857600' > test_mem/memory.limit_in_bytes

3.2 将进程加入到资源限制组

测试代码test.cc如下:

#include <unistd.h>
#include <stdio.h>
#include <cstring>
#include <thread>

void test_cpu() {
    printf("thread: test_cpu start\n");
    int total = 0;
    while (1) {
        ++total;
    }
}

void test_mem() {
    printf("thread: test_mem start\n");
    int step = 20;
    int size = 10 * 1024 * 1024; // 10Mb
    for (int i = 0; i < step; ++i) {
        char* tmp = new char[size];
        memset(tmp, i, size);
        sleep(1);
    }
    printf("thread: test_mem done\n");
}

int main(int argc, char** argv) {
    std::thread t1(test_cpu);
    std::thread t2(test_mem);
    t1.join();
    t2.join();
    return 0;
}

1. 编译该程序

g++ -o test test.cc --std=c++11 -lpthread

2. 观察限制之前的运行状态

img

3. 测试cpu的限制

cgexec -g cpu:test_cpu ./test

cpu使用率降低了一半。

img

除了使用 cgexec 限制进程外,还可以通过将进程号加入到 cgroup.procs 的方式,来达到限制目的。

4. 总结

本文简单介绍了Cgroups的概念和使用,通过Cgroups可以实现资源限制和隔离。在实际的生产环境中,Cgroups技术被大量应用在各种容器技术中,包括docker、rocket等。

这种资源限制和隔离技术的出现,使得模块间相互混部成为可能,大大提高了机器资源利用率,这也是云计算的关键技术之一。

5. 参考

上一篇 下一篇

猜你喜欢

热点阅读