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

Linux 资源管理机制-CGroup[上]

技术万花筒 2021-02-21
1553

容器即应用,容器使用了OS本来就具备的一些能力,namespace做了资源的隔离,使得容器中的进程看起来就像在一个独立环境中运行一样。但是,光有运行环境隔离还不够,因为这些进程还是可以不受限制地使用系统资源,比如网络、磁盘、CPU以及内存等。此时就会存在某些进程占用太多资源,影响到了其他进程;同时,在系统资源耗尽的时候,Linux 内核会触发 OOM killer 特性,选择性的干掉一些进程以求释放一些内存。因此为了让容器更加受控,CGroup就出现了,cgroup用来限制隔离下的进程资源使用,二者有机搭配,成功营造出了一种虚拟化的环境,让进程有一种唯吾独尊的感觉,但是其实对内核来讲,进程还是进程,都是直接在内核上跑的

. 基础知识

1.CGroup是什么

Cgroup control groups(控制族群)的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO 等等)的机制。

2.CGroup主要功能

  1. 限制进程组可以使用的资源数量(Resource limiting )。比如:memory 子系统可以为进程组设定一个 memory 使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发 OOM out of memory)。

  2. 进程组的优先级控制(Prioritization )。比如:可以使用 cpu 子系统为某个进程组分配特定 cpu share

  3. 记录进程组使用的资源数量(Accounting )。比如:可以使用 cpuacct 子系统记录某个进程组使用的 cpu 时间

  4. 进程组隔离(isolation)。比如:使用 ns 子系统可以使不同的进程组使用不同的 namespace以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。

  5. 进程组控制(control)。比如:使用 freezer 子系统可以将进程组挂起和恢复。

在实践中,系统管理员一般会利用 CGroup 做下面这些事(有点像为某个虚拟机分配资源似的):

  • 隔离一个进程集合(比如:nginx的所有进程),并限制他们所消费的资源,比如绑定CPU的核。

  • 为这组进程分配其足够使用的内存

  • 为这组进程分配相应的网络带宽和磁盘存储限制

  • 限制访问某些设备(通过设置设备的白名单)

3.CGroup 相关概念解释

  1. 任务(task)。在 cgroups 中,任务就是系统的一个进程。

  2. 控制族群(control group)。控制族群就是一组按照某种标准划分的进程。Cgroups 中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用 cgroups 以控制族群为单位分配的资源,同时受到 cgroups 以控制族群为单位设定的限制。

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

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

4.相互关系

  1. 每次在系统中创建新层级时,该系统中的所有任务都是那个层级的默认 cgroup(我们称之为 root cgroup ,此cgroup在创建层级时自动创建,后面在该层级中创建的cgroup都是此 cgroup的后代)的初始成员。

  2. 一个子系统最多只能附加到一个层级。

  3. 一个层级可以附加多个子系统。

  4. 一个任务可以是多个cgroup的成员,但是这些cgroup必须在不同的层级。

  5. 系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 成员。然后可根据需要将该子任务移动到不同的 cgroup 中,但开始时它总是继承其父任务cgroup

5.CGroup子系统及其功能:

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

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

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

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

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

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

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

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

  • ns -- 名称空间子系统。

6.CGroup架构

二、CGroup使用(Centos 6

1.安装

#root身份

yum install libcgroup

Copy

2.服务查看和启停

service cgconfig status

service cgconfig start

service cgconfig stop

 

#重新启动此服务将导致重建整个cgroup层次结构,从而删除以前存在的任何cgroup

service cgconfig restart

Copy

3.挂载/卸载子系统

方法一:
cgroup
启动时,会读取配置文件/etc/cgconfig.conf mount section 配置,根据其内容创建和挂载指定的cgroup子系统。

mount {

    <controller> = <path>;

    ...

}

#########################################

# controller:内核子系统的名称

# path:该子系统的挂载点

#########################################

举个例子:

 

mount {

    cpuset  = /cgroup/cpu_mem;

    cpu     = /cgroup/cpu_mem;

    cpuacct = /cgroup/cpu_mem;

    memory  = /cgroup/cpu_mem;

}

上面定义相当于如下shell指令:

 

mkdir /cgroup/cpu_mem

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

Copy

方法二:

mkdir /cgroup/cpu_mem

#挂载 mount -t cgroup -o subsystems name /cgroup/name

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

 

#卸载 umount /cgroup/name

umount /cgroup/cpu_mem

#将卸载其挂载的所有层次结构

Copy

如果层级当前为空(只包含根cgroup),则在卸载层级时,该层级将被禁用。如果层级包含任何其他cgroup,则即使不再挂载的层级仍然在内核中处于活动状态。要删除层级,请确保在卸载层级之前删除所有子组,或者使用cgclear命令停用所有层级(即使不为空的也可以停用层级的命令)

4.查看挂载点

~]# lssubsys -am

cpu,cpuset,cpuacct,memory /cgroup/cpu_and_mem

net_cls

ns

devices

freezer

blkio

Copy

5.新建/删除cgroup

方法一:利用cgconfig服务及其配置文件 /etc/cgconfig.conf group section 配置,在服务启动时自动创建cgroup

group <name> {

    [<permissions>]  

    <controller> { 

        <param name> = <param value>;

            …

    }

    …

}

Copy

方法二:命令行

#新建方法1

cgcreate -t uid:gid -a uid:gid -g subsystems:path

#新建方法2

mkdir /cgroup/hierarchy/name/child_name

#删除方法1(使用 -r 递归删除)

cgdelete subsystems:path

#删除方法2

rm -rf /cgroup/hierarchy/name/child_name

Copy

样例:

#当前层级挂载状态

[root@iZuf6d3awpcinf0nq2kvqeZ cgroup]# lssubsys -am

ns

perf_event

net_prio

cpuset /cgroup/cpuset

cpu /cgroup/cpu

cpuacct /cgroup/cpuacct

memory /cgroup/memory

devices /cgroup/devices

freezer /cgroup/freezer

net_cls /cgroup/net_cls

blkio /cgroup/blkio

 

# cpu n et_cls 子系统被分别安装在单独的层级中,执行 cgcreate 命令

] cgcreate -g cpu,net_cls:/test-subgroup

#则会分别在 cpu net_cls 层级下各自创建 test-subgroup ,等价于执行

] mkdir /cgroup/cpu/test-subgroup

] mkdir /cgroup/net_cls/test-subgroup

 

# cgdelete也可以递归地删除所有的子组与选项-r,当删除cgroup时,其所有任务将移动到其父组

] cgdelete cpu,net_cls:/test-subgroup

Copy

6.权限管理

方法一:利用cgconfig服务及其配置文件 /etc/cgconfig.conf group section 配置,在服务启动时自动配置权限

perm {

    task {

        uid = <task user>;

        gid = <task group>;

    }

    admin {

      uid = <admin name>;

      gid = <admin group>;

    }

}

 

#例子:

  group daemons {

      cpuset { # 设定 daemons cgroup cpu 资源限制

          cpuset.mems = 0;

          cpuset.cpus = 0;

      }

  }

 

 

# 设定 sql cgroup 权限:sqladmin组的用户可以添加 task 到该 cgrouproot用户可以修改该 cgroup 参数设置

  group daemons/sql {

      perm {

          task {

              uid = root;

              gid = sqladmin;

          }

          admin {

              uid = root;

              gid = root;

          }

      }

      cpuset {

          cpuset.mems = 0;

          cpuset.cpus = 0;

      }

  }

Copy

方法二:命令行操作 chown

  ~]$ mkdir -p /cgroup/cpu_mem/wangzhe

  ~]$ mkdir -p /cgroup/cpu_mem/wangzhe/child_1

  ~]$ mkdir -p /cgroup/cpu_mem/wangzhe/child_1

  ~]$ chown root:root /cgroup/cpu_mem/wanghe/*

  ~]$ chown root:wangzhe /cgroup/cpu_mem/wanghe/tasks

  ~]$ echo 0 > /cgroup/cpu_mem/wanghe/cpuset.mems

  ~]$ echo 0 > /cgroup/cpu_mem/wanghe/cpuset.cpus

  ~]$ echo 0 > /cgroup/cpu_mem/wanghe/child_1/cpuset.mems

  ~]$ echo 0 > /cgroup/cpu_mem/wanghe/child_1/cpuset.cpus

Copy

7.cgroup参数设定

  • 命令行cgset -r parameter=value path_to_cgroup(相对于层次结构根的cgroup的路径)

  • 命令行cgset --copy-from path_to_source_cgroup path_to_target_cgroup

  • 文件 echo value > path_to_cgroup/parameter

 ~]$ cgset -r cpuset.cpus=0-1 child_1

 ~]$ cgset --copy-from child_1/ child_2/

 ~]$ echo 0-1 > /cgroup/cpu_mem/wangzhe/child_1/cpuset.cpus

Copy

8.添加task

  • 命令行添加进程 cgclassify -g subsystems:path_to_cgroup pidlist(path_to_cgroup是其层次结构中cgroup的路径,pidlist是进程标识符(PID)的空格分隔列表)

  • 文件添加进程 echo pid > path_to_cgroup/tasks

  • cgroup中启动进程 cgexec -g subsystems:path_to_cgroup command arguments

  • cgroup中启动服务 echo 'CGROUP_DAEMON="subsystem:control_group"' >> /etc/sysconfig/<service>

样例:

#移动用的PID的处理17011138cgroupgroup1/

cgclassify -g cpu,memory:group1 1701 1138

echo -e "1701\n1138" | tee -a /cgroup/cpu/group1/tasks /cgroup/memory/group1/tasks

 

#group1中启动firefox浏览器,受group1挂载的cpu子系统限制

cgexec -g cpu:group1 firefox http://www.redhat.com

sh -c "echo \$$ > /cgroup/lab1/group1/tasks && firefox http://www.redhat.com"

Copy

  • 利用cgrulesengd服务初始化,cgrulesengd会根据/etc/cgrules.conf文件中设置的参数将任务移动到对应的cgroup中的服务

9.cgsnapshot

cgsnapshot会根据当前cgroup情况生成/etc/cgconfig.conf文件内容

~]# mkdir /cgroup/cpu

~]# mount -t cgroup -o cpu cpu /cgroup/cpu

~]# mkdir /cgroup/cpu/lab1

~]# mkdir /cgroup/cpu/lab2

~]# echo 2 > /cgroup/cpu/lab1/cpu.shares

~]# echo 3 > /cgroup/cpu/lab2/cpu.shares

~]# echo 5000000 > /cgroup/cpu/lab1/cpu.rt_period_us

~]# echo 4000000 > /cgroup/cpu/lab1/cpu.rt_runtime_us

~]# mkdir /cgroup/cpuacct

~]# mount -t cgroup -o cpuacct cpuacct /cgroup/cpuacct

Copy

上述命令生成的 cgroup 配置可以通过 cgsnapshot 命令生成对应的 /etc/cgconfig.conf 文件

~]$ cgsnapshot -s

# Configuration file generated by cgsnapshot

mount {

        cpu = /cgroup/cpu;

        cpuacct = /cgroup/cpuacct;

}

 

group lab2 {

        cpu {

                cpu.rt_period_us="1000000";

                cpu.rt_runtime_us="0";

                cpu.shares="3";

        }

}

 

group lab1 {

        cpu {

                cpu.rt_period_us="5000000";

                cpu.rt_runtime_us="4000000";

                cpu.shares="2";

        }

}

Copy

gsnapshot 命令

gsnapshot  [-s] [-b FILE] [-w FILE] [-f FILE] [controller]

  -b, --blacklist=FILE  设置黑名单的生成文件,即不生成对应配置文件(默认/etc/cgsnapshot_blacklist.conf)

  -f, --file=FILE       将输出结果重定向到output_fil

  -s, --silent          忽略所有警告

  -t, --strict          不显示不在白名单中的变量

  -w, --whitelist=FILE  设置白名单的生成文件(不使用默认值)

Copy

10.获取 CGroup 的信息

  • 查看进程在哪个cgroup

·       #方法一

·       ps -O cgroup

·        

·       #方法二

·       cat /proc/<PID>/cgroup

Copy

  • 查看subsystem mount情况

·       #方法一

·       ~]$ cat /proc/cgroups

·       #subsys_name    hierarchy       num_cgroups     enabled

·       cpuset  2       1       1

·       ns      0       1       1

·       cpu     3       1       1

·       cpuacct 4       1       1

·       memory  5       1       1

·       devices 6       1       1

·       freezer 7       1       1

·       net_cls 8       1       1

·       blkio   9       3       1

·       perf_event      0       1       1

·       net_prio        0       1       1

·        

·       #方法二

·       ~]$ lssubsys -m subsystems

Copy

  • 查看cgroup lscgroup

  • 查看cgroup参数值

·       #cgget -r parameter list_of_cgroups

·       ~]$ cgget -r cpuset.cpus -r memory.limit_in_bytes group1 group2

·        

·       #cgget -g <controllers>:<path>

·       ~]$ cgget -g cpuset /

Copy

  • cgclear删除hierarchy极其所有cgroup

使用mount命令创建cgroups(而不是使用该cgconfig服务创建它们)导致在/etc/mtab文件(挂载的文件系统表)中创建一个条目。该更改也反映在 /proc/mounts文件中。但是,使用该cgclear命令卸载cgroups 以及其他cgconfig命令直接使用内核接口,它不会将其更改反映到/etc/mtab文件中,而只会将新信息写入/proc/mounts文件。使用cgclear命令卸载cgroup后,卸载的cgroup仍然可以在/etc/mtab文件中显示,因此在mount执行命令时显示。

11.CGroup事件通知API

cgroups事件通知API允许用户空间应用程序接收关于cgroup的更改状态的通知。目前,通知API仅支持监视内存不足(OOM)控制文件:memory.oom_control

12.libcgroup手册

  • cgclassifycgclassify命令用于将运行的任务移动到一个或多个cgroup

  • cgclearcgclear命令用于删除层次结构中的所有cgroup

  • cgconfig.conf- cgroupscgconfig.conf文件中定义。

  • cgconfigparsercgconfigparser命令解析cgconfig.conf文件并挂载层次结构。

  • cgcreatecgcreate命令在层次结构中创建新的cgroup

  • cgdeletecgdelete命令删除指定的cgroups

  • cgexeccgexec命令在指定的cgroups中运行任务。

  • cggetcgget命令显示cgroup参数。

  • cgsnapshotcgsnapshot命令从现有子系统生成配置文件。

  • cgred.confcgred.conf是服务的配置文件cgred

  • cgrules.confcgrules.conf包含用于确定任务何时属于某些cgroup的规则。

  • cgrulesengdcgrulesengd服务将任务分配给cgroups

  • cgsetcgset命令设置cgroup的参数。

  • lscgrouplscgroup命令列出层次结构中的cgroup

  • lssubsyslssubsys命令列出包含指定子系统的层次结构。

未完待续..


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

评论