在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
内核中强大的工具cgroup,不仅可以限制被NameSpace隔离起来的资源,还可以为资源设置权重,计算用量等 什么是cgroupcgroup全称是control groups control groups:控制组,被整合在了linux内核当中,把进程(tasks)放到组里面,对组设置权限,对进程进行控制。可以理解为用户和组的概念,用户会继承它所在组的权限。 cgroups是linux内核中的机制,这种机制可以根据特定的行为把一系列的任务,子任务整合或者分离,按照资源划分的等级的不同,从而实现资源统一控制的框架,cgroup可以控制、限制、隔离进程所需要的物理资源,包括cpu、内存、IO,为容器虚拟化提供了最基本的保证,是构建docker一系列虚拟化的管理工具 对于开发cgroup的特点
cgroup的作用cgroup的内核通过hook钩子来实现管理进程资源,提供了一个统一的接口,从单个进程的资源控制到操作系统层面的虚拟卡的过渡 cgroup提供了四个功能:
术语表
关系:一个cgroup里可以有多个task,subsystem相当于控制cgroup限制的类型, hierarchy里可以有多个cgroup,一个系统可以有多个hierarchy。 层级树的四大规则传统的进程启动,是以init为根节点,也叫父进程,由它来创建子进程,作为子节点,而每个子节点还可以创建新的子节点,这样构成了树状结构。而cgroup的结构跟他类似的。子节点继承父节点的属性。他们最大的不同在于,系统的cgroup构成的层级树允许有多个存在,如果进程模型是init为根节点形成一个树,那cgroup的模型由多个层级树来构成。 如果只有一个层级树,所有的task都会受到一个subsystem的相同的限制,会给不需要这种限制的task造成麻烦 1.同一个层级树(hierarchy)可以附加一个或多个子系统(subsystem)
2.一个子系统(subsystem)可以附加到多个层级树(hierarchy)中,但是仅仅是可以附加到多个没有任何子系统的层级树中。 如图所示,cpu子系统先附加到层级树A上,同时就不能附加到层级树B上,因为B上已经有了一个mem子系统,如果B和A同时都是没有任何子系统时,这时,cpu子系统可以同时附加到A和B两个层级树中 言外之意就是,如果多个层级树中都没有子系统,这个时候一个cpu子系统依次可以附加到这些层级树中 3.一个进程(task)不能属于同一个层级树(hierarchy)的不同cgroup 系统每次新建一个层级树(hierarchy)时,默认的构成了新的层级树的初始化的cgroup,这个cgroup被称为root cgroup,对于你自己成功的层级树(hierarchy)来说,task只能存在这个层级树的一个cgroup当中,意思就是一个层级树中不能出现两个相同的task,但是它可以存在不同的层级树中的其他cgroup。 如果要将一个层级树cgroup中的task添加到这个层级树的其他cgroup时,会被从之前task所在的cgroup移除 如以上图中示例: httpd已经加入到层级树(hierarchy)A中的cg1中,且pid为58950,此时就不能将这个httpd进程放入到cg2中,不然cg1中的httpd进程就会被删除,但是可以放到层级树(hierarchy)B的cg3控制组中 其实是为了防止出现进程矛盾,如:在层级树A中的cg1中存在httpd进程,这时cpu对cg1的限制使用率为30%,cg2的限制使用率为50%,如果再将httpd进程添加到cg2中,这时httpd的cpu使用率限制就有了矛盾。 4.刚fork出的子进程在初始状态与父进程处于同一个cgroup 进程task新开的一个子进程(child_task)默认是和原来的task在同一个cgroup中,但是child_task允许被移除到该层级树的其他不同的cgroup中。 当fork刚完成之后,父进程和子进程是完全独立的 如图中所示中,httpd58950进程,当有人访问时,会fork出另外一个子进程httpd58951,这个时候默认httpd58951和httpd58950都在cg1中,他们的关系也是父子进程,httpd58951是可以移动到cg2中,这时候就改变了他们的关系,都变为了独立的进程。 Subsystem子系统subsystem究竟可以控制什么东西 通过以下的操作来验证 [root@localhost ~]# yum -y install libcgroup-tools 安装这个工具后就看可以通过使用cgroup命令来查看 列出系统中所有的cgroup控制组 [root@localhost ~]# lscgroup net_cls,net_prio:/ freezer:/ hugetlb:/ cpu,cpuacct:/ cpu,cpuacct:/machine.slice cpu,cpuacct:/user.slice cpu,cpuacct:/system.slice cpu,cpuacct:/system.slice/network.service cpu,cpuacct:/system.slice/docker.service ... 查看subsystem可以控制的硬件 [root@localhost ~]# lssubsys -a cpuset cpu,cpuacct memory devices freezer net_cls,net_prio blkio perf_event hugetlb pids 以上查看到的,有存在的对应目录, [root@localhost ~]# ll /sys/fs/cgroup/ total 0 drwxr-xr-x. 5 root root 0 Mar 25 04:50 blkio lrwxrwxrwx. 1 root root 11 Mar 25 04:50 cpu -> cpu,cpuacct lrwxrwxrwx. 1 root root 11 Mar 25 04:50 cpuacct -> cpu,cpuacct drwxr-xr-x. 5 root root 0 Mar 25 04:50 cpu,cpuacct drwxr-xr-x. 2 root root 0 Mar 25 04:50 cpuset drwxr-xr-x. 5 root root 0 Mar 25 04:50 devices drwxr-xr-x. 2 root root 0 Mar 25 04:50 freezer drwxr-xr-x. 2 root root 0 Mar 25 04:50 hugetlb drwxr-xr-x. 5 root root 0 Mar 25 04:50 memory lrwxrwxrwx. 1 root root 16 Mar 25 04:50 net_cls -> net_cls,net_prio drwxr-xr-x. 2 root root 0 Mar 25 04:50 net_cls,net_prio lrwxrwxrwx. 1 root root 16 Mar 25 04:50 net_prio -> net_cls,net_prio drwxr-xr-x. 2 root root 0 Mar 25 04:50 perf_event drwxr-xr-x. 5 root root 0 Mar 25 04:50 pids drwxr-xr-x. 5 root root 0 Mar 25 04:50 systemd 可以看到目录中的内容是比命令查看到的多,是因为有几个软链接文件 # 以下三个都属于cpu,cpuacct cpu -> cpu,cpuacct cpuacct -> cpu,cpuacct cpu,cpuacct # 以下三个都属于net_cls,net_prio net_cls -> net_cls,net_prio net_prio -> net_cls,net_prio net_cls,net_prio Subsystem可以控制的内容分别代表什么
注意:到现在为止,还没有可以对容器硬盘大小进行限制的工具,只能限制硬盘的读写频率 cgroup的工作原理查看cgroup中的CPU控制中的tasks文件,存放了对文件中的进程的cpu的控制,如果要添加某个进程对cpu的控制,将进程的pid加入tasks文件即可,包括其他的硬件资源控制也是如此 [root@localhost ~]# cat /sys/fs/cgroup/cpu/tasks 1 2 4 5 6 7 8 9 ... 68469 68508 68526 68567 在生产环境中,由于在内核中,所以它是自动增加的 cgroup真正的工作原理就是hook钩子,cgroup的实现本质上是给系统进程挂上钩子实现的,当task进程运行的过程中,设计到某个资源是,就会触发钩子上附带的subsystem子系统进行资源检测,最终根据资源类别的不同使用对应的技术进行资源限制和优先级分配。 钩子是怎么实现的 简单来说,linux中管理task进程的数据结构,在cgroup的每个task设置一个关键词,将关键词都指向钩子,叫做指针。 一个task只对应一个指针结构时,一个指针结构可以被多个task进行使用 当一个指针一旦读取到唯一指针数据的内容,task就会被触发,就可以进行资源控制 在实际的使用过程中,用户需要使用mount来挂载cgroup控制组 在目录中可以看到,比如httpd程序,pid号为69060 [root@localhost ~]# yum -y install httpd^C [root@localhost ~]# systemctl start httpd^C [root@localhost ~]# netstat -anput | grep 80 tcp6 0 0 :::80 :::* LISTEN 69060/httpd 查看它pid号目录中的mounts文件,存放了大量的关于cgroup的挂载 可以看到每一个cgoup后面的目录,如 [root@localhost ~]# cat /proc/69060/mounts rootfs / rootfs rw 0 0 /dev/mapper/centos-root / xfs rw,seclabel,relatime,attr2,inode64,noquota 0 0 devtmpfs /dev devtmpfs rw,seclabel,nosuid,size=914476k,nr_inodes=228619,mode=755 0 0 tmpfs /dev/shm tmpfs rw,seclabel,nosuid,nodev 0 0 devpts /dev/pts devpts rw,seclabel,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 mqueue /dev/mqueue mqueue rw,seclabel,relatime 0 0 hugetlbfs /dev/hugepages hugetlbfs rw,seclabel,relatime 0 0 ... cgroup /sys/fs/cgroup/systemd cgroup rw,seclabel,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0 cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,seclabel,nosuid,nodev,noexec,relatime,net_prio,net_cls 0 0 cgroup /sys/fs/cgroup/freezer cgroup rw,seclabel,nosuid,nodev,noexec,relatime,freezer 0 0 cgroup /sys/fs/cgroup/hugetlb cgroup rw,seclabel,nosuid,nodev,noexec,relatime,hugetlb 0 0 cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0 cgroup /sys/fs/cgroup/cpuset cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpuset 0 0 cgroup /sys/fs/cgroup/devices cgroup rw,seclabel,nosuid,nodev,noexec,relatime,devices 0 0 cgroup /sys/fs/cgroup/memory cgroup rw,seclabel,nosuid,nodev,noexec,relatime,memory 0 0 cgroup /sys/fs/cgroup/blkio cgroup rw,seclabel,nosuid,nodev,noexec,relatime,blkio 0 0 cgroup /sys/fs/cgroup/pids cgroup rw,seclabel,nosuid,nodev,noexec,relatime,pids 0 0 cgroup /sys/fs/cgroup/perf_event cgroup rw,seclabel,nosuid,nodev,noexec,relatime,perf_event 0 0 ... 这就是通过mount控制cgroup的,所有的程序都是这样的,子系统上所有的系统都把文件mount上以后,就可以像操作系统一样操作cgroup和层级树进行管理,包括权限管理、子文件系统,除了cgroup文件系统以外,内核中没有为cgroup的访问提供添加其他任何的操作,想要去操作cgroup,就必须使用mount挂到某一个cgroup控制组内才行。 资源控制操作我们需要知道每一个硬件资源的具体怎么去控制的操作 如: cgroup组中的cpu目录里具体的每一项的具体的含义,都是对cpu具体的控制的细节 [root@localhost ~]# cd /sys/fs/cgroup/cpu [root@localhost cpu]# ls cgroup.clone_children cpuacct.stat cpu.cfs_quota_us cpu.stat system.slice cgroup.event_control cpuacct.usage cpu.rt_period_us machine.slice tasks cgroup.procs cpuacct.usage_percpu cpu.rt_runtime_us notify_on_release user.slice cgroup.sane_behavior cpu.cfs_period_us cpu.shares release_agent 这些具体的使用方法会在下一篇文章中来逐个去解释用法 Docker命令行限制内容-c/--cpu-shares:限制cpu优先级 -m/--memory:限制内存的使用容量 --memory-swap:限制内存+swap的大小 --blkil-weight bps/iops --device-read-bps --device-write-bps --device-read-iops --device-write-iops cgroup目录结构如下
到此这篇关于Docker核心原理之 Cgroup详解的文章就介绍到这了,更多相关Docker核心原理内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论