docker cgroup 技术之memory(首篇)

本文深入探讨了Docker中cgroup的内存管理,包括内存回收、进程内存空间、内存限制及内核扩展。介绍了如何通过cgroup限制和回收内存,以及内存分配和回收的机制,如伙伴系统和LRU列表。同时,文章讨论了内存限制的设置,以及内核内存和用户内存之间的关系,帮助理解Docker容器的内存管控策略。
摘要由CSDN通过智能技术生成

测试环境centos7,内核版本4.20

内核使用cgroup对进程进行分组,并限制进程资源和对进程进行跟踪。内核通过名为cgroupfs类型的虚拟文件系统来提供cgroup功能接口。cgroup有如下2个概念:

subsystem:用于控制cgroup中的进程行为的内核组件,可以在/proc/cgroups查看所有支持的subsystemsubsystem也别称为resource controller;第二列为croup id;第三列为cgroup中进程数目。

# cat /proc/cgroups
#subsys_name    hierarchy   num_cgroups enabled
    cpuset          8           6           1
    cpu             7           105         1
    cpuacct         7           105         1
    blkio           5           105         1
    memory          3           327         1
    devices         6           106         1
    freezer         4           6           1
    net_cls         2           6           1
    perf_event      11          6           1
    net_prio        2           6           1
    hugetlb         9           6           1
    pids            12          106         1
    rdma            10          1           1

hierarchy:由cgroup组成的层级树,每个hierarchy都对应一个cgroup虚拟文件系统,每个hierarchy都有系统上的所有task,此外低levelhierarchy不能超过高level设定的资源上限

系统默认会挂载cgroup,路径为/sys/fs/cgroup,查看当前系统挂载的cgroup,可以看到在默认路径下挂载了所有的子系统。
后续可以直接使用下述hierarchy作为父hierarchy
进程的cgroup可以在/proc/$pid/cgroup文件中查看。

# mount|grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,seclabel,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,perf_event)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,hugetlb)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,rdma)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpu,cpuacct)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,net_cls,net_prio)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpuset)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,blkio)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,freezer)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,memory)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,pids)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,devices)

cgroup有如下4个规则:

  • 一个hierarchy可以有一个或多个subsystem,这个从/sys/fs/cgroup中可以看出来cpucpuacct可以同属于一个hierarchy,而memory则仅属于一个hierarchy
  • 一个subsystem不能挂载到一个已经挂载了不同subsystemhierarchy上(下面讲);
  • 一个task不能同时存在于同一个hierarchy下的两个cgoup中,但可以存在于不同类型的hierarchy中;如下例中,在hierarchy memory中创建2cgroup mem1mem2,可以看到将当前bash进程写入到mem2/tasks之后,mem1/tasks中的内容就会被清空。注:删除cgroup之前需要退出所有attach到该cgroup的进程,如下面的进程为bashexit退出即可
[root@ memory]# echo $$
9439
[root@ memory]# echo $$ > mem1/tasks 
[root@ memory]# cat mem1/tasks 
9439
9680
[root@ memory]# echo $$ > mem2/tasks 
[root@ memory]# cat mem2/tasks 
9439
9693
[root@ memory]# cat mem1/tasks 
[root@ memory]# 

相同类型subsystemhierarchy为同一个hierarchy,如下例中创建一个包含memory subsystemhierarchy,它与/sys/fs/cgroup下面的memory是一致的,在cgrp1中创建一个名为mem1cgroup。在/sys/fs/cgroup/memory下可以看到新创建的mem1

[root@ cgroup]# mount -t cgroup -o memory mem cgrp1/
[root@ cgroup]# cd cgrp1/
[root@ cgrp1]# mkdir mem1

子进程会继承父进程的hierarchy,但可以将子进程调整到其他cgroup。下例中可以看到子进程同样受到父进程hierarchy的限制

[root@ mem1]# echo $$
10928
[root@ mem1]# echo $$>tasks
[root@ mem1]# cat /proc/10928/cgroup 
11:devices:/user.slice
10:perf_event:/
9:pids:/user.slice
8:freezer:/
7:cpuacct,cpu:/
6:hugetlb:/
5:memory:/mem1
4:cpuset:/
3:net_prio,net_cls:/
2:blkio:/
1:name=systemd:/user.slice/user-1000.slice/session-1.scope

[root@ mem1]# bash #创建一个子进程
[root@ mem1]# echo $$
11402
[root@ mem1]# cat /proc/11402/cgroup 
11:devices:/user.slice
10:perf_event:/
9:pids:/user.slice
8:freezer:/
7:cpuacct,cpu:/
6:hugetlb:/
5:memory:/mem1
4:cpuset:/
3:net_prio,net_cls:/
2:blkio:/
1:name=systemd:/user.slice/user-1000.slice/session-1.scope

从上面可以看到,subsystem相同的hierarchy是被重复使用的;当创建一个新的hierarchy时,如果使用的subsystem被其他hierarchy使用,则会返回EBUSY错误。
/sys/fs/cgroup中已经在cpusetmemory中单独使用了名为cpusetmemorysubsystem,则重新创建一个包含了它们的hierarchy会返回错误

[root@ cgroup]# mount -t cgroup -o cpuset,memory mem1 cgrp1/
mount: mem1 is already mounted or /cgroup/cgrp1 busy

可以创建没有subsystemhierarchy,默认包含如下文件:

  • tasks:包含了attach到该cgouppid。如上述例子中所示,将进程pid写入到该文件会将进程转移到该cgroup。(cgroupv2中移除了该文件,使用cgroup.procs)
  • cgroup.procs:包含了线程的group id。将一个线程的group id写入该文件,会
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值