前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >谈谈cgroups机制

谈谈cgroups机制

作者头像
机械视角
发布2020-12-31 10:45:50
1.4K0
发布2020-12-31 10:45:50
举报
文章被收录于专栏:TensorbytesTensorbytes

cgroup是什么

cgroup(control groups,控制组群) 是 Linux 内核提供的一个用来限制和控制进程组的资源(CPU、内存、磁盘io等)的功能。cgroup 大家最熟知得场景应该就是容器了,LXC 和 docker 都用 cgroup 和命名空间来控制和限制资源,当然我们也可以直接用它来限制应用程序。 cgroup 为每种可以控制的资源定义了一个子系统:

  • cpu 子系统,主要用于限制进程的 cpu 使用率,一般和 cpuacct 一起。
  • cpuacct 子系统,主要用于统计 cgroups 中的进程的 cpu 使用报告。
  • cpuset 子系统,可以为 cgroups 中的进程分配单独的 cpu 节点或者内存节点。
  • memory 子系统,可以限制进程的 memory 使用量。
  • blkio 子系统,可以限制进程的块设备 io。
  • devices 子系统,可以控制进程能够访问某些设备。
  • net_cls 子系统,可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制。
  • freezer 子系统,可以挂起或者恢复 cgroups 中的进程。
  • ns 子系统,可以使不同 cgroups 下面的进程使用不同的 namespace。

查询资源目录

cgroup 子系统挂载目录查询:

代码语言:javascript
复制
$ mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)

cgroup 资源一般都挂载在/sys/fs/cgroup下面:

代码语言:javascript
复制
$ ll /sys/fs/cgroup
total 0
drwxr-xr-x 4 root root  0 Jun 18 01:40 blkio
lrwxrwxrwx 1 root root 11 Jun 18 01:40 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 Jun 18 01:40 cpuacct -> cpu,cpuacct
drwxr-xr-x 5 root root  0 Aug  6 11:21 cpu,cpuacct
drwxr-xr-x 3 root root  0 Jun 18 01:40 cpuset
drwxr-xr-x 4 root root  0 Jun 18 01:40 devices
drwxr-xr-x 3 root root  0 Jun 18 01:40 freezer
drwxr-xr-x 3 root root  0 Jun 18 01:40 hugetlb
drwxr-xr-x 5 root root  0 Aug  6 11:21 memory
lrwxrwxrwx 1 root root 16 Jun 18 01:40 net_cls -> net_cls,net_prio
drwxr-xr-x 3 root root  0 Jun 18 01:40 net_cls,net_prio
lrwxrwxrwx 1 root root 16 Jun 18 01:40 net_prio -> net_cls,net_prio
drwxr-xr-x 3 root root  0 Jun 18 01:40 perf_event
drwxr-xr-x 4 root root  0 Jun 18 01:40 pids
drwxr-xr-x 4 root root  0 Jun 18 01:40 systemd

用法

案例:基于 cgroups 构建受 CPU 和内存限制应用程序

要构建这么一个收限制的应用程序,本质就是将应用程序的进程组加入 cgroup 中。

创建一个 cgroup

由于 cgroups 是通过 VFS(Virtual File System, 虚拟文件系统)的方式把相关的功能暴露给用户,因此我们可以直接通过对文件的操作来实现 cgroups。

比如我们要创建一个限制 CPU 的 cgroups,名字叫 webtest,我们可以直接用 mkdir 命令进行创建:

  • mkdir的创建文件夹的方法

因此,我们创建的时候用mkdir -p直接在 cpu 目录下面创建文件夹即可:

代码语言:javascript
复制
$ mkdir -p /sys/fs/cgroup/cpu/webtest
``` 

在系统目录下创建文件夹之后, cgroups 程序会某人为一个cgroup,因此会在新生成的文件夹中自动生成相关设置文件,这样要注意的是,cpu 文件夹是指向 cpu,cpuacct:
```bash
$ ll /sys/fs/cgroup/cpu
lrwxrwxrwx 1 root root 11 Jun 21  2019 /sys/fs/cgroup/cpu -> cpu,cpuacct

因此,我们要看到真实目录是要在cpu,cpuacct/目录下:

代码语言:javascript
复制
$ ll /sys/fs/cgroup/cpu,cpuacct/
total 0
-rw-r--r--  1 root root 0 Jun 21  2019 cgroup.clone_children
--w--w--w-  1 root root 0 Jun 21  2019 cgroup.event_control
-rw-r--r--  1 root root 0 Jun 21  2019 cgroup.procs
-r--r--r--  1 root root 0 Jun 21  2019 cgroup.sane_behavior
-r--r--r--  1 root root 0 Jun 21  2019 cpuacct.stat
-rw-r--r--  1 root root 0 Jun 21  2019 cpuacct.usage
-r--r--r--  1 root root 0 Jun 21  2019 cpuacct.usage_percpu
-rw-r--r--  1 root root 0 Jun 21  2019 cpu.cfs_period_us
-rw-r--r--  1 root root 0 Jun 21  2019 cpu.cfs_quota_us
-rw-r--r--  1 root root 0 Jun 21  2019 cpu.rt_period_us
-rw-r--r--  1 root root 0 Jun 21  2019 cpu.rt_runtime_us
-rw-r--r--  1 root root 0 Jun 21  2019 cpu.shares
-r--r--r--  1 root root 0 Jun 21  2019 cpu.stat
-rw-r--r--  1 root root 0 Jun 21  2019 notify_on_release
-rw-r--r--  1 root root 0 Jun 21  2019 release_agent
drwxr-xr-x 58 root root 0 Sep 30 22:03 system.slice
-rw-r--r--  1 root root 0 Jun 21  2019 tasks
drwxr-xr-x  2 root root 0 Jun 23  2019 user.slice
drwxr-xr-x  2 root root 0 Oct  1 00:12 webtest

除了mkdir命令,我们也可以用cgcreate创建。

  • cgcreate的创建文件夹的方法

除了mkdir这种直接创建文件目录的方法外,官方提供cgcreate命令用于创建 cgroups :

代码语言:javascript
复制
$ cgcreate admin:admin -g cpu:website

cgcreate 命令参数:

代码语言:javascript
复制
$ man cgcreate
cgcreate [-h] [-s] [-t <tuid>:<tgid>] [-a <agid>:<auid>] [-f mode] [-d mode] -g <controllers>:<path>
-t <tuid>:<tgid>
定义拥有cgroup的任务文件文件权限用户及用户组,
-a <agid>:<auid>
定义拥有cgroup的其他文件权限用户及用户组,如设置子系统参数和创建subgroups
-d, --dperm mode
文件目录权限
-f, --fperm mode
文件夹权限
-g <controllers>:<path>
子系统和新建文件路径

设置参数

cgroups 下面每个子系统都有很多参数,其中cpu.cfs_quota_us 是控制CPU 运行时间的,其默认值为100000,我们将其改为 3000,即使用 3% 的CPU:

代码语言:javascript
复制
echo 3000 > /sys/fs/cgroup/cpu/webtest/cpu.cfs_quota_us

将需要控制的进程加入 cgroup 中

我们通过sha1sum /dev/zero来跑满单颗 CPU。查看应用 PID :

将应用程序 PID 写入 webtest 目录的 tasks 中,我们这次的应用程序PID是22413:

代码语言:javascript
复制
$ echo "22413" > /sys/fs/cgroup/cpu/webtest/tasks

可以看到,CPU 使用率已经由百分之百降到百分之三以内:

经过一段时间的观察,不过有意思的是,程序偶尔有超过 3%,这也是为什么 cgroup 并不是严格的 CPU 分片。

使用 containerd/cgroups 库在代码中控制 cgroups

containerd 提供了一个 cgroups 库,用于 cgroups 控制,详见:https://github.com/containerd/cgroups 这里简单介绍下其基本用法:

CPU 事件
代码语言:javascript
复制
shares := uint64(100)
control, err := cgroups.New(cgroups.V1, cgroups.StaticPath("/test"), &specs.LinuxResources{
    CPU: &specs.CPU{
        Shares: &shares,
    },
})

参考文献

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • cgroup是什么
    • 查询资源目录
    • 用法
      • 案例:基于 cgroups 构建受 CPU 和内存限制应用程序
      • 创建一个 cgroup
      • 设置参数
      • 将需要控制的进程加入 cgroup 中
        • 使用 containerd/cgroups 库在代码中控制 cgroups
          • CPU 事件
      • 参考文献
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档