云原生一文带你搞懂docker容器的核心基石cgroups(代码片段)

dvlinker dvlinker     2022-11-30     448

关键词:

目录

大家好,本文是对 Docker 容器的核心基石Cgroups的详细讲解,讲解了Cgroups的相关概念、Cgroups的构成与作用、如何查看和使用Cgroups等,对大家后续理解容器有很大的帮助~

1、为什么要了解Cgroups

2、Cgroups简介

3、什么是Cgroups?

4、为什么需要Cgroups?

5、Cgroups是如何实现的?

6、Cgroups的作用

7、Cgroups相关概念及相互关系

7.1、相关概念

7.2、相互关系

8、Cgroups子系统介绍

8.1、如何查看当前系统支持哪些subsystem?

8.2、Cgroups下的CPU子系统

8.3、在CentOS中安装Cgroups

8.4、查看service服务在哪个cgroup组

9、如何使用Cgroups?

9.1、通过systemctl设置cgroup

9.2、设置 CPU 资源的使用上限

9.3、通过配置文件设置cgroup(/etc/cgconfig.conf)

10、查看Cgroup

10.1、通过systemd查看cgroup

10.2、通过proc查看cgroup

10.3、通过/sys查看cgroup


       Cgroups是Linux系统内核提供的一种机制,这种机制可以根据需求将一些列系统任务机器子任务整合或分离到按资源划分登记的不同组内,从而为系统资源管理提供一个的框架。简单地说,cgroups可以限制、记录任务组所使用的物理组员(比如CPU、Memory、IO等),为容器实现虚拟化提供了基本保证,是构建Docker等一些列虚拟化管理工具的基石。今天我们就来详细介绍一下cgroups相关的内容。

1、为什么要了解Cgroups

       从2013年开源的Docker推出、2014年开源的 Kubernetes出现,到现在的云原生技术与生态的全面普及与火热化,容器技术已经逐步成为主流的基础云原生技术之一。使用容器技术,可以很好地实现资源层面上的限制和隔离,这都依赖于Linux系统内核所提供的Cgroups和 Namespace技术。

Cgroups 主要用来管理资源的分配、限制;

Namespace主要用来封装抽象、限制、隔离资源,使命名空间内的进程拥有它们自己的全局资源。

       Linux内核提供的Cgroups和 Namespace技术,为容器实现虚拟化提供了基本保证,是构建Docker等一些列虚拟化管理工具的基石。下面我们就来详细介绍一下Cgroups相关的内容。 

2、Cgroups简介

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

通过使用Cgroups,系统管理员在分配、排序、拒绝、管理和监控系统资源等方面,可以进行精细化控制。硬件资源可以在应用程序和用户间智能分配,从而增加整体效率。最初由google 的工程师提出,后来被整合进Linux内核。也是目前轻量级虚拟化技术 XC(Linux Container)的基础之一。

       Cgroups和 Namespace类似,也是将进程进行分组,但它的目的和 Namespace不一 样,Namespace是为了隔离进程组之间的资源,而 Cgroups是为了对一组进程进行统一的资源监控和限制。

       Cgroups分 v1 和 v2 两个版本,v1 实现较早,功能比较多,但是由于它里面的功能都是零零散散的实现的,所以规划的不是很好,导致了一些使用和维护上的不便,v2 的出现 就是为了解决 v1 中这方面的问题,在最新的 4.5 内核中,Cgroups v2 声称已经可以用于生产环境了,但它所支持的功能还很有限,随着 v2 一起引入内核的还有 Cgroups、Namespace。v1 和 v2 可以混合使用,但是这样会更复杂,所以一般没人会这样用。

3、什么是Cgroups?

       Cgroups 是 Linux 下的一种将进程按组进行管理的机制,在用户层看来,Cgroups技术就是把系统中的所有进程组织成一颗一颗独立的树,每棵树都包含系统的所有进程,树的每个节点是一个进程组,而每颗树又和一个或者多个 subsystem关联,树的作用是将进程分组,而subsystem的作用就是对这些组进行操作。Cgroups的主体架构提如下:

Cgroups主要包括下面两部分:

       subsystem : 一个 subsystem 就是一个内核模块,他被关联到一颗 cgroup 树之后, 就会在树的每个节点(进程组)上做具体的操作。subsystem 经常被称作 resource controller,因为它主要被用来调度或者限制每个进程组的资源,但是这个说法不完全准 确,因为有时我们将进程分组只是为了做一些监控,观察一下他们的状态,比如 perf_event subsystem。到目前为止,Linux 支持 12 种 subsystem,比如限制 CPU 的使 用时间,限制使用的内存,统计 CPU 的使用情况,冻结和恢复一组进程等,后续会对它们 一一进行介绍。

       hierarchy : 一个 hierarchy 可以理解为一棵 cgroup 树,树的每个节点就是一个进程 组,每棵树都会与零到多个 subsystem 关联。在一颗树里面,会包含 Linux 系统中的所有 进程,但每个进程只能属于一个节点(进程组)。系统中可以有很多颗 cgroup 树,每棵树 都和不同的 subsystem 关联,一个进程可以属于多颗树,即一个进程可以属于多个进程 组,只是这些进程组和不同的 subsystem 关联。

       目前 Linux 支持 12 种 subsystem,如果不考虑不与任何 subsystem 关联的情况(systemd 就属于这种情况),Linux 里面最多可以建 12 颗 cgroup 树,每棵树关联一个 subsystem,当然也可以只建一棵树,然后让这 棵树关联所有的 subsystem。当一颗 cgroup 树不和任何 subsystem 关联的时候,意味着 这棵树只是将进程进行分组,至于要在分组的基础上做些什么,将由应用程序自己决定, systemd 就是一个这样的例子。

4、为什么需要Cgroups?

       在 Linux 里,一直以来就有对进程进行分组的概念和需求,比如 session group, progress group 等,后来随着人们对这方面的需求越来越多,比如需要追踪一组进程的内存和 IO使用情况等,于是出现了cgroup,用来统一将进程进行分组,并在分组的基础上对进程进行监控和资源控制管理等。

举个例子,Linux系统中安装了杀毒软件ESET或者ClamAV,杀毒时占用系统资源过高,影响系统承载业务运 行,怎么办?单个虚拟机进程或者docker进程使用过高的资源,怎么办? 单个Java进行占用系统过多的内存的资源,怎么办?

        cgroup就是能够控制并解决上述问题的工具,cgroup在linux内核实现、用于控制 linux系统资源。

5、Cgroups是如何实现的?

        在 CentOS 7 系统中(包括 Red Hat Enterprise Linux 7),通过将 cgroup 层级系统与systemd 单位树捆绑,可以把资源管理设置从进程级别移至应用程序级别。默认情况 下,systemd 会自动创建 slice、scope 和 service 单位的层级(具体的意思稍后再解释),来为 cgroup 树提供统一结构。

       可以通过 systemctl 命令创建自定义 slice 进一步修 改此结构。 如果我们将系统的资源看成一块馅饼,那么所有资源默认会被划分为 3 个 cgroup: System, User 和 Machine。每一个 cgroup 都是一个 slice,每个 slice 都可以有自己的子 slice,如下图所示:


下面我们以 CPU 资源为例,来解释一下上图中出现的一些关键词。

        如上图所示,系统默认创建了 3 个顶级 slice(System, User 和 Machine),每个 slice 都会获得相同的 CPU 使用时间(仅在 CPU 繁忙时生效),如果 user.slice 想获得 100% 的 CPU 使用时间,而此时 CPU 比较空闲,那么 user.slice 就能够如愿以偿。这三种顶级 slice 的含义如下:

1)system.slice:所有系统 service 的默认位置。

2)user.slice:所有用户会话的默认位置。每个用户会话都会在该 slice 下面创建一个子 slice, 如果同一个用户多次登录该系统,仍然会使用相同的子 slice。

3)machine.slice:所有虚拟机和 Linux 容器的默认位置 控制 CPU 资源使用的其中一种方法是 shares。shares 用来设置 CPU 的相对值(你可以理解为权 重),并且是针对所有的 CPU(内核),默认值是 1024。因此在上图中,httpd, sshd, crond 和 gdm 的 CPU shares 均为 1024,System, User 和 Machine 的 CPU shares 也是 1024。

       假设该系统上运行了 4 个 service,登录了两个用户,还运行了一个虚拟机。同时假设 每个进程都要求使用尽可能多的 CPU 资源(每个进程都很繁忙),则:

1)system.slice 会获得 33.333% 的 CPU 使用时间,其中每个 service 都会从 system.slice 分配的 资源中获得 1/4 的 CPU 使用时间,即 8.25% 的 CPU 使用时间。

2)user.slice 会获得 33.333% 的 CPU 使用时间,其中每个登录的用户都会获得 16.5% 的 CPU 使 用时间。假设有两个用户:tom 和 jack,如果 tom 注销登录或者杀死该用户会话下的所有进程, jack 就能够使用 33.333% 的 CPU 使用时间。

3)machine.slice 会获得 33.333% 的 CPU 使用时间,如果虚拟机被关闭或处于 idle 状态,那么 system.slice 和 user.slice 就会从这 33.333% 的 CPU 资源里分别获得 50% 的 CPU 资源,然后 均分给它们的子 slice。

6、Cgroups的作用

       Cgroups最初的目标是为资源管理提供的一个统一的框架,既整合现有的cpuset等子系统,也为未来开发新的子系统提供接口。现在的cgroups适用于多种应用场景,从单个进程的资源控制,到实现操作系统层次的虚拟化(OS Level Virtualization),框架图如下:

Cgroups提供了以下功能:

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子系统可以将进程组挂起和恢复。

7、Cgroups相关概念及相互关系

7.1、相关概念

1)任务(task)

在cgroups中,任务就是系统的一个进程。

2)控制族群(control group)

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

3)层级(hierarchy)

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

4)子系统(subsystem)

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

7.2、相互关系

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

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

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

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

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

8、Cgroups子系统介绍

       可以看到,在/sys/fs/cgroup下面有很多cpu、memory这样的子目录,也就称为子系统subsystem:

它是一组资源控制模块,一般包含如下几项:

1)net_cls:将cgroup中进程产生的网络包分类,以便Linux的tc(traffic controller)可 以根据分类区分出来自某个cgroup的包并做限流或监控。这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序 (tc)识别从具体 cgroup 中生成的数据包。

2)net_prio:设置cgroup中进程产生的网络流量的优先级。
3)memory:控制cgroup中进程的内存占用。

4)cpuset:在多核机器上设置cgroup中进程可以使用的cpu和内存。这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。

5)freezer:挂起(suspend)和恢复(resume)cgroup中的进程。这个子系统挂起或者恢复 cgroup 中的任务。

6)blkio:设置对块设备(如硬盘)输入输出的访问控制。这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等 等)。

7)cpu:设置cgroup中进程的CPU占用。这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。

8)cpuacct:统计cgroup中进程的CPU占用。这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。

9)devices:控制cgroup中进程对设备的访问 16 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。

8.1、如何查看当前系统支持哪些subsystem?

       可以通过查看/proc/cgroups(since Linux 2.6.24)知道当前系统支持哪些subsystem,下面 是一个例子:

#subsys_name hierarchy num_cgroups enabled 
cpuset 11 1 1 
cpu 3 64 1 
cpuacct 3 64 1 
blkio 8 64 1 
memory 9 104 1 
devices 5 64 1 
freezer 10 4 1 
net_cls 6 1 1 
perf_event 7 1 1 
net_prio 6 1 1 
hugetlb 4 1 1 
pids 2 68 1

每一列的说明:

1)subsys_name:subsystem的名字

2)hierarchy:subsystem所关联到的cgroup树的ID,如果多个subsystem关联到同一颗cgr oup树,那么他们的这个字段将一样,比如这里的cpu和cpuacct就一样,表示他们绑定到了同 一颗树。 如果出现下面的情况,这个字段将为0:

i)当前subsystem没有和任何cgroup树绑定

ii)当前subsystem已经和cgroup v2的树绑定
iii)当前subsystem没有被内核开启

3)num_cgroups:subsystem所关联的cgroup树中进程组的个数,也即树上节点的个数

4)enabled:1表示开启,0表示没有被开启(可以通过设置内核的启动参数“cgroup_disable”来控制subsystem的开启).

8.2、Cgroups下的CPU子系统

        cpu子系统用于控制cgroup中所有进程可以使用的cpu时间片。 cpu subsystem主要涉及5接口:cpu.cfs_period_us,cpu.cfs_quota_us,cpu.shares, cpu.rt_period_us,cpu.rt_runtime_us. cpu.

1)cfs_period_us

       cfs_period_us表示一个cpu带宽,单位为微秒。系统总CPU带宽: cpu核心数 * cfs_period_us cpu.

2)cfs_quota_us

       cfs_quota_us表示Cgroup可以使用的cpu的带宽,单位为微秒。cfs_quota_us为-1,表示使用的 CPU不受cgroup限制。cfs_quota_us的最小值为1ms(1000),最大值为1s。 结合cfs_period_us,就可以限制进程使用的cpu。例如配置cfs_period_us=10000,而 cfs_quota_us=2000。那么该进程就可以可以用2个cpu core。

3)cpu.shares

       通过cfs_period_us和cfs_quota_us可以以绝对比例限制cgroup的cpu使用,即 cfs_quota_us/cfs_period_us 等于进程可以利用的cpu cores,不能超过这个数值。 而cpu.shares以相对比例限制cgroup的cpu。例如:在两个 cgroup 中都将 cpu.shares 设定为 1 的任务将有相同的 CPU 时间,但在 cgroup 中将 cpu.shares 设定为 2 的任务可使用的 CPU 时间 是在 cgroup 中将 cpu.shares 设定为 1 的任务可使用的 CPU 时间的两倍。

4)cpu.rt_runtime_us

       以微秒(µs,这里以“us”代表)为单位指定在某个时间段中 cgroup 中的任务对 CPU 资源的最 长连续访问时间。建立这个限制是为了防止一个 cgroup 中的任务独占 CPU 时间。如果 cgroup 中的任务应该可以每 5 秒中可有 4 秒时间访问 CPU 资源,请将 cpu.rt_runtime_us 设定为 4000000,并将 cpu.rt_period_us 设定为 5000000。

5)cpu.rt_period_us

       以微秒(µs,这里以“us”代表)为单位指定在某个时间段中 cgroup 对 CPU 资源访问重新分配 的频率。如果某个 cgroup 中的任务应该每 5 秒钟有 4 秒时间可访问 CPU 资源,则请将 cpu.rt_runtime_us 设定为 4000000,并将 cpu.rt_period_us 设定为 5000000。

       注意 sched_rt_runtime_us 是实时任务的保证时间和最高占用时间,如果实时任务没有使用,可以分配给非实时任务,并且实时任务最终占用的时间不能超过这个数值,参考 Linux-85 关于 sched_rt_runtime_us 和 sched_rt_period_us 。

        对 cpu.rt_period_us 参数的限制是必须小于父目录中的同名参数值。 对 cpu.rt_runtime_us 的限制是:

\\Sum_i runtime_i / global_period <= global_runtime / global_period

即:

\\Sum_i runtime_i <= global_runtime 

        当前的实时进程调度算法可能导致部分实时进程被饿死,如下A和B是并列的,A的运行时时长正好覆盖了B的运行时间:

* group A: period=100000us, runtime=50000us
- this runs for 0.05s once every 0.1s

* group B: period= 50000us, runtime=25000us
- this runs for 0.025s twice every 0.1s (or once every 0.05 sec).

       Real-Time group scheduling 中提出正在开发 SCHED_EDF (Earliest Deadline First scheduling),优先调度最先结束的实时进程。

8.3、在CentOS中安装Cgroups

#若系统未安装则进行安装,若已安装则进行更新。 
yum install libcgroup 

#查看运行状态,并启动服务 
[root@localhost ~] service cgconfig status 
Stopped 

[root@localhost ~] service cgconfig start 
Starting cgconfig service: [ OK ] 
service cgconfig status 9 Running 1011 

#查看是否安装cgroup
[root@localhost ~] grep cgroup /proc/filesystems

8.4、查看service服务在哪个cgroup组

systemctl status [pid] | grep CGroup 23 
cat /proc/[pid]/cgroup 
cd /sys/fs/ && find * ‐name "*.procs" ‐exec grep [pid]  /dev/null \\; 2> /dev/null 

#查看进程cgroup的最快方法是使用以下bash脚本按进程名: 
#!/bin/bash 
THISPID=`ps ‐eo pid,comm | grep $1 | awk 'print $1'` 
cat /proc/$THISPID/cgroup

9、如何使用Cgroups?

9.1、通过systemctl设置cgroup

        在使用命令 systemctl set-property 时,可以使用 tab 补全:

$ systemctl set‐property user‐1000.slice 
AccuracySec= CPUAccounting= Environment= LimitCPU= LimitNICE= LimitSIGPEN DING= SendSIGKILL= 
BlockIOAccounting= CPUQuota= Group= LimitDATA= LimitNOFILE= LimitSTACK= U ser= 
BlockIODeviceWeight= CPUShares= KillMode= LimitFSIZE= LimitNPROC= MemoryA ccounting= WakeSystem= 
BlockIOReadBandwidth= DefaultDependencies= KillSignal= LimitLOCKS= LimitR SS= MemoryLimit=
BlockIOWeight= DeviceAllow= LimitAS= LimitMEMLOCK= LimitRTPRIO= Nice= 
BlockIOWriteBandwidth= DevicePolicy= LimitCORE= LimitMSGQUEUE= LimitRTTIM E= SendSIGHUP=

这里有很多属性可以设置,但并不是所有的属性都是用来设置 cgroup 的,我们只需要关注 Block, CPU 和 Memory。

       如果你想通过配置文件来设置 cgroup,service 可以直接在 /etc/systemd/system/xxx.service.d 目录下面创建相应的配置文件,slice 可以直接在 /run/systemd/system/xxx.slice.d 目录下面创建相应的配置文件。

       事实上通过 systemctl 命令行工具设置 cgroup 也会写到该目录下的配置文件中:

$ cat /run/systemd/system/user‐1000.slice.d/50‐CPUQuota.conf 
[Slice] 
CPUQuota=20%

9.2、设置 CPU 资源的使用上限

       如果想严格控制 CPU 资源,设置 CPU 资源的使用上限,即不管 CPU 是否繁忙,对 CPU 资源的使用都不能超过这个上限。可以通过以下两个参数来设置:

1)cpu.cfs_period_us = 统计CPU使用时间的周期,单位是微秒(us)

2)cpu.cfs_quota_us = 周期内允许占用的CPU时间(指单核的时间,多核则需要在设置时累加)

systemctl 可以通过 CPUQuota 参数来设置 CPU 资源的使用上限。例如,如果你想将用户 tom 的 CPU 资源使用上限设置为 20%,可以执行以下命令:

$ systemctl set‐property user‐1000.slice CPUQuota=20%

9.3、通过配置文件设置cgroup(/etc/cgconfig.conf)

      cgroup配置文件所在位置 /etc/cgconfig.conf,其默认配置文件内容

mount 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 ;

相当于执行命令:

mkdir /cgroup/cpuset 
mount ‐t cgroup ‐o cpuset red /cgroup/cpuset
…… 
mkdir /cgroup/blkio 

[root@localhost ~] vi /etc/cgrules.conf 
[root@localhost ~] echo 524288000 > /cgroup/memory/foo/memory.limit_in_b ytes 

       使用cgroup临时对进程进行调整,直接通过命令即可,如果要持久化对进程进行控 制,即重启后依然有效,需要写进配置文件/etc/cgconfig.conf及/etc/cgrules.conf 

10、查看Cgroup

10.1、通过systemd查看cgroup

1)systemd-cgls 命令

       通过 systemd-cgls 命令来查看,它会返回系统的整体 cgroup 层级,cgroup 树的最高层 由 slice 构成,如下所示:

$ systemd‐cgls ‐‐no‐page 

├─1 /usr/lib/systemd/systemd ‐‐switched‐root ‐‐system ‐‐deserialize 22 
├─user.slice 
│ ├─user‐1000.slice 
│ │ └─session‐11.scope 
│ │ ├─9507 sshd: tom [priv] 
│ │ ├─9509 sshd: tom@pts/3 
│ │ └─9510 ‐bash 
│ └─user‐0.slice 
│ └─session‐1.scope 
│ ├─ 6239 sshd: root@pts/0 
│ ├─ 6241 ‐zsh 
│ └─11537 systemd‐cgls ‐‐no‐page 
└─system.slice 15 ├─rsyslog.service 
│ └─5831 /usr/sbin/rsyslogd ‐n 
├─sshd.service 18 │ └─5828 /usr/sbin/sshd ‐D 
├─tuned.service 
│ └─5827 /usr/bin/python2 ‐Es /usr/sbin/tuned ‐l ‐P 21 ├─crond.service 
│ └─5546 /usr/sbin/crond ‐n

       可以看到系统 cgroup 层级的最高层由 user.slice 和 system.slice 组成。因为系统中没有 运行虚拟机和容器,所以没有 machine.slice,所以当 CPU 繁忙时,user.slice 和 system.slice 会各获得 50% 的 CPU 使用时间。

     user.slice 下面有两个子 slice:user-1000.slice 和 user-0.slice,每个子 slice 都用 User ID (UID) 来命名,因此我们很容易识别出哪个 slice 属于哪个用户。例如:从上面的输出信 息中可以看出 user-1000.slice 属于用户 tom,user-0.slice 属于用户 root。

2)systemd-cgtop 命令

       systemd-cgls 命令提供的只是 cgroup 层级的静态信息快照,要想查看 cgroup 层级的动 态信息,可以通过 systemd-cgtop 命令查看:

$ systemd‐cgtop 

Path Tasks %CPU Memory Input/s Output/s 
/ 161 1.2 161.0M ‐ ‐ 5 /system.slice ‐ 0.1 ‐ ‐ ‐ 
/system.slice/vmtoolsd.service 1 0.1 ‐ ‐ ‐ 
/system.slice/tuned.service 1 0.0 ‐ ‐ ‐ 
/system.slice/rsyslog.service 1 0.0 ‐ ‐ ‐ 
/system.slice/auditd.service 1 ‐ ‐ ‐ ‐ 
/system.slice/chronyd.service 1 ‐ ‐ ‐ ‐ 
/system.slice/crond.service 1 ‐ ‐ ‐ ‐ 
/system.slice/dbus.service 1 ‐ ‐ ‐ ‐ 
/system.slice/gssproxy.service 1 ‐ ‐ ‐ ‐ 
/system.slice/lvm2‐lvmetad.service 1 ‐ ‐ ‐ ‐ 
/system.slice/network.service 1 ‐ ‐ ‐ ‐ 
/system.slice/polkit.service 1 ‐ ‐ ‐ ‐ 
/system.slice/rpcbind.service 1 ‐ ‐ ‐ ‐ 
/system.slice/sshd.service 1 ‐ ‐ ‐ ‐ 
/system.slice/system‐getty.slice/getty@tty1.service 1 ‐ ‐ ‐ ‐ 
/system.slice/systemd‐journald.service 1 ‐ ‐ ‐ ‐ 
/system.slice/systemd‐logind.service 1 ‐ ‐ ‐ ‐ 
/system.slice/systemd‐udevd.service 1 ‐ ‐ ‐ ‐ 
/system.slice/vgauthd.service 1 ‐ ‐ ‐ ‐ 
/user.slice 3 ‐ ‐ ‐ ‐ 
/user.slice/user‐0.slice/session‐1.scope 3 ‐ ‐ ‐ ‐ 
/user.slice/user‐1000.slice 3 ‐ ‐ ‐ ‐ 
/user.slice/user‐1000.slice/session‐11.scope 3 ‐ ‐ ‐ ‐ 
/user.slice/user‐1001.slice/session‐8.scope

scope systemd-cgtop 提供的统计数据和控制选项与 top 命令类似,但该命令只显示那些开启了 资源统计功能的 service 和 slice。

       如果你想开启 sshd.service 的资源统计功能,可以进行如下操作:

$ systemctl set‐property sshd.service CPUAccounting=true MemoryAccounting=true 

#该命令会在 /etc/systemd/system/sshd.service.d/ 目录下创建相应的配置文件: 
$ ll /etc/systemd/system/sshd.service.d/ 
总用量 8 
4 ‐rw‐r‐‐r‐‐ 1 root root 28 5月 31 02:24 50‐CPUAccounting.conf 
4 ‐rw‐r‐‐r‐‐ 1 root root 31 5月 31 02:24 50‐MemoryAccounting.conf 

$ cat /etc/systemd/system/sshd.service.d/50‐CPUAccounting.conf 
[Service] 
CPUAccounting=yes 1415 

$ cat /etc/systemd/system/sshd.service.d/50‐MemoryAccounting.conf 
[Service] 
MemoryAccounting=yes 1819 

#配置完成之后,再重启 sshd 服务: 
$ systemctl daemon‐reload 21 $ systemctl restart sshd

这时再重新运行 systemd‐cgtop 命令,就能看到 sshd 的资源使用统计了。

10.2、通过proc查看cgroup

       如何查看当前进程属于哪些cgroup 可以通过查看/proc/[pid]/cgroup(since Linux 2.6.24)知道指定进程属于哪些cgroup,如下:

$ cat /proc/777/cgroup 

11:cpuset:/ 
10:freezer:/ 
9:memory:/system.slice/cron.service 
8:blkio:/system.slice/cron.service 
7:perf_event:/ 7 6:net_cls,net_prio:/ 
5:devices:/system.slice/cron.service 
4:hugetlb:/ 
3:cpu,cpuacct:/system.slice/cron.service 
2:pids:/system.slice/cron.service 
1:name=systemd:/system.slice/cron.service

 每一行包含用冒号隔开的三列,他们的意思分别是:

cgroup树的ID :和cgroup树绑定的所有subsystem :进程在cgroup树中的路径

1)cgroup树的ID, 和/proc/cgroups文件中的ID一一对应。

2)和cgroup树绑定的所有subsystem,多个subsystem之间用逗号隔开。这里name=systemd 表示没有和任何subsystem绑定,只是给他起了个名字叫systemd。

3)进程在cgroup树中的路径,即进程所属的cgroup,这个路径是相对于挂载点的相对路径。

10.3、通过/sys查看cgroup

       查看cgroup下CPU资源的使用上限:

$ cat /sys/fs/cgroup/cpu,cpuacct/user.slice/user‐1000.slice/cpu.cfs_perio d_us 
100000 

$ cat /sys/fs/cgroup/cpu,cpuacct/user.slice/user‐1000.slice/cpu.cfs_quota _us 
20000 

这表示用户 tom 在一个使用周期内(100 毫秒)可以使用 20 毫秒的 CPU 时间。不管 CPU 是否空闲,该用户使用的 CPU 资源都不会超过这个限制。

       CPUQuota 的值可以超过 100%,例如:如果系统的 CPU 是多核,且 CPUQuota 的值为 200%,那么该 slice 就能够使用 2 核的 CPU 时间。

云原生|docker-一文了解docker(代码片段)

...推动了虚拟化、容器化技术的产生和发展,以及现在的云原生时代的到来,都极大提高了其资源利用率。DockerDocker本身不是容器,它只是一个应用容器引擎,这么解释可能有些抽象,大家理解下面内容。三大核心镜像(Image)容器... 查看详情

一文带你搞懂内存泄漏!!!(代码片段)

好文推荐:作者:codelang检测内存是否泄漏非常简单,只要在任意位置调用Debug.dumpHprofData(file)即可,通过拿到hprof文件进行分析就可以知道哪里产生了泄漏,但dump的过程会suspend所有的java线程,导致用户界... 查看详情

一文带你搞懂“数据”在内外网环境下怎么流通

大学还没毕业,刚出来实习,在搞网络安全的同时我连内外网网络数据包的走向,我都搞不明白怎么去搞安全,所以下面咱们一起学习网络数据包在内外网环境下是怎么进行流通的。1.内网和外网的含义       ... 查看详情

一文带你搞懂rpc到底是个啥(代码片段)

RPC(RemoteProcedureCall),是一个大家既熟悉又陌生的词,只要涉及到通信,必然需要某种网络协议。我们很可能用过HTTP,那么RPC又和HTTP有什么区别呢?RPC还有什么特点,常见的选型有哪些?1.RPC... 查看详情

一文搞懂云原生架构

云原生前言俯瞰:什么是云原生?后起之秀:云原生日薄西山:传统的软件开发模型?横空出世:云原生简介纵横驰骋:三大技术基石1:基础设施即代码2:不可变基础设施3:声明式API如日中天:... 查看详情

一文带你搞懂c++如何操作文件对话框(附源码)(代码片段)

    在C++程序中有时需要通过系统的文件对话框去操作文件或者文件夹,我们有必要熟练掌握操作文件对话框的细节,去更好的为我们软件服务。本文我们就来讲述一下C++在操作文件夹对话框的相关细节ÿ... 查看详情

❤️野指针?悬空指针?❤️一文带你搞懂!(代码片段)

🎈作者:Linux猿🎈简介:CSDN博客专家🏆,C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊!🎈关注专栏:C/C++面试通关集锦 (优质好文持续更新中……)... 查看详情

云原生之docker容器安装以及入门docker部署web应用&&云原生基石

一.前言1.1Docker是什么?Docker是一个应用打包、分发、部署的工具。基本就是一个轻量的虚拟机。虚拟机里只有我们需要的东西,其他多余的东西是必要的。我们看下图,来看一下它和普通的虚拟机对比图:如下:1.2打包、分发、... 查看详情

微信小程序一文带你搞懂小程序的页面配置和网络数据请求(代码片段)

文章目录页面配置页面配置文件的作用页面配置和全局配置的关系页面配置网络数据请求网络数据请求的限制配置request合法域名发起get/post请求在页面刚加载时请求数据跳过request合法域名校验关于跨域和ajax请求页面配置每个小... 查看详情

app自动化测试很重要?一文带你搞懂怎么测app

现在是移动互联网的时代,移动端APP产品在不断推陈出新,相应的APP测试人员也变得炙手可热。今天小濠跟大家全面谈谈APP应该怎么做测试。一、首先,移动测试要注意以下几点:移动APP测试中如何设计TestCaseÿ... 查看详情

app自动化测试很重要?一文带你搞懂怎么测app

现在是移动互联网的时代,移动端APP产品在不断推陈出新,相应的APP测试人员也变得炙手可热。今天小濠跟大家全面谈谈APP应该怎么做测试。一、首先,移动测试要注意以下几点:移动APP测试中如何设计TestCaseÿ... 查看详情

javascript中的浅拷贝深拷贝是什么?一文带你搞懂,不再犯错(代码片段)

⭐️本文首发自前端修罗场,是一个由资深开发者独立运行的专业技术社区,我专注Web技术、模拟面试、简历修改、Web3、区块链以及职业发展。创作的《前端面试复习笔记》(点击阅读原文订阅),广受好评&... 查看详情

一文就带你搞懂✨为什么重写equals时必须重写hashcode方法?(代码片段)

文章目录🔥整体结构图✨前景说明⭐为什么?有什么作用OR好处?🚀实战演练没有重写hashcode()解决办法:重写hashcode()😘尾言🔥整体结构图✨前景说明为什么重写equals时必须重写hashCode方法?相信... 查看详情

一篇文零基础带你搞懂回溯(万字:核心思维+图解+习题+题解思路+代码注释)

认真看完本篇文章你将精通掌握关于回溯的以下几点:回溯的本质是什么?如何轻松的写出回溯的代码?如何一眼看穿题目可以用回溯求解?如何通过startIndex进行去重、剪枝?什么是回溯中去重等级?如... 查看详情

挑战华为社招:这一次带你搞懂springboot核心原理(代码片段)

一、网络编程基础回顾1.SocketSocket本身有“插座”的意思,不是Java中特有的概念,而是一个语言无关的标准,任何可以实现网络编程的编程语言都有Socket。在Linux环境下,用于表示进程间网络通信的特殊文件类型&#... 查看详情

一文带你彻底搞懂docker中的cgroup(代码片段)

前言进程在系统中使用CPU、内存、磁盘等计算资源或者存储资源还是比较随心所欲的,我们希望对进程资源利用进行限制,对进程资源的使用进行追踪。这就让cgroup的出现成为了可能,它用来统一将进程进行分组࿰... 查看详情

一文带你搞懂如何优化慢sql(代码片段)

最近通过SGM监控发现有两个SQL的执行时间占该任务总执行时间的90%,通过对该SQL进行分析和优化的过程中,又重新对SQL语句的执行顺序和SQL语句的执行计划进行了系统性的学习,整理的相关学习和总结如下;作者:京东科技 ... 查看详情

不容错过的nginx配置详解,一文带你搞懂nginx

参考技术ANginx是一个高性能的HTTP和反向代理服务器,特点是占用内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网页服务器中表现好。Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率,能经... 查看详情