本文是一系列对 cgroup 说明的文档,已期望说明 cgroup 子系统涉及的所有子系统,本文只对 cpu,cpuacct 进行说明,本文的目录如下
什么是 cpu 子系统 ?
runc cgroup cpu 是如何调用的?
什么是 cpuacct 子系统?
runc cgroup cpuacct 是如何调用的
1 什么是 cpu 子系统 ?
cpu 子系统调度 CPU 对 cgroup 的访问。 可以使用两个调度程序来调度 CPU 资源。一种是 Completely Fair Scheduler (CFS) ,一种是 Real-Time scheduler (RT) 。在 cgroup 下相关的目录内容如下:
ls -al /sys/fs/cgroup/cpu,cpuacct/
## 使用cfs调度,比如在1s周期内任务请求0.2s执行时间,
## cpu.cfs_period_us=1000000,cpu.cfs_quota_us=200000
cpu.cfs_period_us ## cgroup请求分配cpu的周期
cpu.cfs_quota_us ## cpu.cfs_period_us周期内分配的任务时间
cpu.rt_period_us ## 实时调度请求分配cpu周期
cpu.rt_runtime_us ## 实时调度分配的周期内的任务运行时间
## cpu.shares共享相对时间。
## 举例1来说,task1所在cgroup.share=100,
## task2所在cgroup.share=100,两者共享cpu比例1:1
## 举例2来说,task1所在cgroup.share=100,
## task2所在cgroup.share=200,两者共享cpu比例1:2
cpu.shares
## cpu元数据信息,
## cpu.stat含有nr_periods,nr_throttled,throttled_time
## nr_periods代表走过多少个cpu.cfs_period_us周期
## nr_throttled代表有多少次任务执行超过了分配的周期
## throttled_time超过分配周期的时间
cpu.stat
复制代码
2 runc cgroup cpu 是如何调用的?
目前的常见的容器技术 docker 底层其实是 runc 的调用实现,
runc 对 cpu 的限制正是通过 cgroup 来实现的,以容器运行时中 runc 中的设置 cpu 权限逻辑为例:
查看 cpu.shares 参数是否合理,可以写入。需要保证写入的 cpu.shares 和设置的值保持一致。
查看 cpu.cfs_period_us 是否需要设置。不设置继承父级参数。
查看 cpu.cfs_quota_us 是否需要设置。不设置继承父级参数。
查看 cpu.rt_period_us 是否需要设置。不设置继承父级参数。
查看 cpu.rt_runtime_us 是否需要设置。不设置继承父级参数。
3 什么是 cpuacct 子系统 ?
CPU (cpuacct) 子系统会自动生成 cgroup 中的任务使用的 CPU 资源报告,包括子组中的任务。 提供三种报告:
cpuacct.usage:cgroup 中所有任务(包括层次结构中较低的任务)消耗的总 CPU 时间(以纳秒为单位)。
cpuacct.stat:报告此 cgroup 中所有任务(包括层次结构中较低的任务)消耗的用户和系统 CPU 时间:user — 用户模式下任务消耗的 CPU 时间。system — 系统(内核)模式下的任务消耗的 CPU 时间。
cpuacct.usage_percpu 报告此 cgroup 中的所有任务(包括层次结构中较低的任务)在每个 CPU 上消耗的 CPU 时间(以纳秒为单位)。
对应的文件如下:
# cat /sys/fs/cgroup/cpu,cpuacct/user.slice/a/cpuacct.usage
13295407
# cat /sys/fs/cgroup/cpu,cpuacct/user.slice/a/cpuacct.usage_all
cpu user system
0 0 0
1 0 0
2 0 0
3 0 0
...
79 0 0
# cat /sys/fs/cgroup/cpu,cpuacct/user.slice/a/cpuacct.usage_percpu
0 0 0 0 0 0 0 63245 0 90847 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 584011 0 0 0 0 0 0 0 0 0 0 0 0 0 1569189 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9476900 0 0 0 0 0 953186 0 56507 0 50333 0 0 0 0 0 451189 0 0 0 0
# cat /sys/fs/cgroup/cpu,cpuacct/user.slice/a/cpuacct.usage_percpu_sys
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 463393 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4398319 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30973 0 0 0 0
# cat /sys/fs/cgroup/cpu,cpuacct/user.slice/a/cpuacct.usage_percpu_user
0 0 0 0 0 0 0 63245 0 90847 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 584011 0 0 0 0 0 0 0 0 0 0 0 0 0 1105796 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5078581 0 0 0 0 0 983178 0 56507 0 50333 0 0 0 0 0 420216 0 0 0 0
# cat /sys/fs/cgroup/cpu,cpuacct/user.slice/a/cpuacct.usage_sys
4892685
# cat /sys/fs/cgroup/cpu,cpuacct/user.slice/a/cpuacct.usage_user
8432714
复制代码
4 runc cgroup cpu 是如何调用的?
目前的常见的容器技术 docker 底层其实是 runc 的调用实现,
runc 对 cpu 的限制正是通过 cgroup 来实现的,以容器运行时中 runc 中的设置 cpu 权限逻辑为例:
任务写入/sys/fs/cgroup/cpu,cpuacct/user.slice/test/cgroup.procs
后续读取 cpuacct.usage,cpuacct.stat 等文件内容
参考文献
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/sec-cpu
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/sec-cpuacct
https://www.slideshare.net/Docker/container-performance-analysis-brendan-gregg-netflix
评论