《重识云原生系列》专题索引:
- 第一章——不谋全局不足以谋一域
- 第二章计算第1节——计算虚拟化技术总述
- 第二章计算第2节——主流虚拟化技术之VMare ESXi
- 第二章计算第3节——主流虚拟化技术之Xen
- 第二章计算第4节——主流虚拟化技术之KVM
- 第二章计算第5节——商用云主机方案
- 第二章计算第6节——裸金属方案
- 第三章云存储第1节——分布式云存储总述
- 第三章云存储第2节——SPDK方案综述
- 第三章云存储第3节——Ceph统一存储方案
- 第三章云存储第4节——OpenStack Swift 对象存储方案
- 第三章云存储第5节——商用分布式云存储方案
- 第四章云网络第一节——云网络技术发展简述
- 第四章云网络4.2节——相关基础知识准备
- 第四章云网络4.3节——重要网络协议
- 第四章云网络4.3.1节——路由技术简述
- 第四章云网络4.3.2节——VLAN技术
- 第四章云网络4.3.3节——RIP协议
- 第四章云网络4.3.4节——OSPF协议
- 第四章云网络4.3.5节——EIGRP协议
- 第四章云网络4.3.6节——IS-IS协议
- 第四章云网络4.3.7节——BGP协议
- 第四章云网络4.3.7.2节——BGP协议概述
- 第四章云网络4.3.7.3节——BGP协议实现原理
- 第四章云网络4.3.7.4节——高级特性
- 第四章云网络4.3.7.5节——实操
- 第四章云网络4.3.7.6节——MP-BGP协议
- 第四章云网络4.3.8节——策略路由
- 第四章云网络4.3.9节——Graceful Restart(平滑重启)技术
- 第四章云网络4.3.10节——VXLAN技术
- 第四章云网络4.3.10.2节——VXLAN Overlay网络方案设计
- 第四章云网络4.3.10.3节——VXLAN隧道机制
- 第四章云网络4.3.10.4节——VXLAN报文转发过程
- 第四章云网络4.3.10.5节——VXlan组网架构
- 第四章云网络4.3.10.6节——VXLAN应用部署方案
- 第四章云网络4.4节——Spine-Leaf网络架构
- 第四章云网络4.5节——大二层网络
- 第四章云网络4.6节——Underlay 和 Overlay概念
- 第四章云网络4.7.1节——网络虚拟化与卸载加速技术的演进简述
- 第四章云网络4.7.2节——virtio网络半虚拟化简介
- 第四章云网络4.7.3节——Vhost-net方案
- 第四章云网络4.7.4节vhost-user方案——virtio的DPDK卸载方案
- 第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现
- 第四章云网络4.7.6节——virtio-blk存储虚拟化方案
- 第四章云网络4.7.8节——SR-IOV方案
- 第四章云网络4.7.9节——NFV
- 第四章云网络4.8.1节——SDN总述
- 第四章云网络4.8.2.1节——OpenFlow概述
- 第四章云网络4.8.2.2节——OpenFlow协议详解
- 第四章云网络4.8.2.3节——OpenFlow运行机制
- 第四章云网络4.8.3.1节——Open vSwitch简介
- 第四章云网络4.8.3.2节——Open vSwitch工作原理详解
- 第四章云网络4.8.4节——OpenStack与SDN的集成
- 第四章云网络4.8.5节——OpenDayLight
- 第四章云网络4.8.6节——Dragonflow
-
第四章云网络4.9.1节——网络卸载加速技术综述
-
第四章云网络4.9.2节——传统网络卸载技术
-
第四章云网络4.9.3.1节——DPDK技术综述
-
第四章云网络4.9.3.2节——DPDK原理详解
-
第四章云网络4.9.4.1节——智能网卡SmartNIC方案综述
-
第四章云网络4.9.4.2节——智能网卡实现
-
第六章容器6.1.1节——容器综述
-
第六章容器6.1.2节——容器安装部署
-
第六章容器6.1.3节——Docker常用命令
-
第六章容器6.1.4节——Docker核心技术LXC
-
第六章容器6.1.5节——Docker核心技术Namespace
-
第六章容器6.1.6节—— Docker核心技术Chroot
-
第六章容器6.1.7.1节——Docker核心技术cgroups综述
-
第六章容器6.1.7.2节——cgroups原理剖析
-
第六章容器6.1.7.3节——cgroups数据结构剖析
-
第六章容器6.1.7.4节——cgroups使用
-
第六章容器6.1.8节——Docker核心技术UnionFS
-
第六章容器6.1.9节——Docker镜像技术剖析
-
第六章容器6.1.10节——DockerFile解析
-
第六章容器6.1.11节——docker-compose容器编排
-
第六章容器6.1.12节——Docker网络模型设计
-
第六章容器6.2.1节——Kubernetes概述
-
第六章容器6.2.2节——K8S架构剖析
-
第六章容器6.3.1节——K8S核心组件总述
-
第六章容器6.3.2节——API Server组件
-
第六章容器6.3.3节——Kube-Scheduler使用篇
-
第六章容器6.3.4节——etcd组件
-
第六章容器6.3.5节——Controller Manager概述
-
第六章容器6.3.6节——kubelet组件
-
第六章容器6.3.7节——命令行工具kubectl
-
第六章容器6.3.8节——kube-proxy
-
第六章容器6.4.1节——K8S资源对象总览
-
第六章容器6.4.2.1节——pod详解
-
第六章容器6.4.2.2节——Pod使用(上)
-
第六章容器6.4.2.3节——Pod使用(下)
-
第六章容器6.4.3节——ReplicationController
-
第六章容器6.4.4节——ReplicaSet组件
-
第六章容器基础6.4.5.1节——Deployment概述
-
第六章容器基础6.4.5.2节——Deployment配置详细说明
-
第六章容器基础6.4.5.3节——Deployment实现原理解析
-
第六章容器基础6.4.6节——Daemonset
-
第六章容器基础6.4.7节——Job
-
第六章容器基础6.4.8节——CronJob
1. cgroups概述
1.1 为什么需要cgroup
在Linux里,一直以来就有对进程进行分组的概念和需求,比如session group, progress group等,后来随着人们对这方面的需求越来越多,比如需要追踪一组进程的内存和IO使用情况等,于是出现了cgroup,用来统一将进程进行分组,并在分组的基础上对进程进行监控和资源控制管理等。
1.2 cgroups简介
cgroups全称是control groups,是 Linux 内核的一个功能,用来限制、控制与分离一个进程组的资源(如CPU、内存、磁盘输入输出等)。它是由 Google 的两位工程师进行开发的,自 2008 年 1 月正式发布的 Linux 内核 v2.6.24 开始提供此能力。cgroups 到目前为止,有两个大版本, cgroup v1 和 v2 。cgroup 主要限制的资源是、CPU、内存、网络、磁盘 I/O。当我们将可用系统资源按特定百分比分配给 cgroup 时,剩余的资源可供系统上的其他 cgroup 或其他进程使用。
cgroup 的作用基本上就是控制一个进程或一组进程可以访问或使用给定关键资源(CPU、内存、网络和磁盘 I/O)的量。一个容器中通常运行了多个进程,并且您需要对这些进程实施统一控制,因此 cgroup 是容器的关键组件,为容器虚拟化提供了最基本的保证,是构建docker一系列虚拟化的管理工具。Kubernetes 环境使用cgroup 在 pod 级别上部署资源请求和限制以及对应的 QoS 类。
下图说明了当您将特定比例的可用系统资源分配给一个 cgroup(在本例中,为cgroup‑1)后,剩余资源是如何在系统上其他 cgroup(以及各个进程)之间进行分配的:
cgroup 资源分配及剩余可用资源示例图
1.3 cgroups基本概念
cgroups主要由task、cgroup、subsystem及hierarchy构成:
- task:在cgroups中,task就是系统的一个进程。
- control group(简写:cgroup):控制族群就是按照某种标准划分的进程,包含一个或多个子系统。Cgroups 中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也可从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用 cgroups 以控制族群为单位分配的资源,同时受到 cgroups 以控制族群为单位设定的限制;
- hierarchy(层级树):控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性;hierarchy由一系列cgroup以一个树状结构排列而成,每个hierarchy通过绑定对应的subsystem进行资源调度;hierarchy中的cgroup节点可以包含零或多个子节点,子节点继承父节点的属性;整个系统可以有多个hierarchy。
- subsystem:Cgroups中的subsystem就是一个资源调度控制器(Resource Controller),比如CPU子系统可以控制CPU时间分配,内存子系统可以限制cgroup内存使用量;子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。但是资源调度控制器这个说法也不完全准确,因为有时我们将进程分组只是为了做一些监控,观察一下他们的状态,比如perf_event subsystem。到目前为止,Linux支持12种subsystem,比如限制CPU的使用时间,限制使用的内存,统计CPU的使用情况,冻结和恢复一组进程等。
1.3.1 相互关系
- 每次在系统中创建新层级时,该系统中的所有任务都是那个层级的默认 cgroup(我们称之为 root cgroup,此 cgroup 在创建层级时自动创建,后面在该层级中创建的 cgroup 都是此 cgroup 的后代)的初始成员;
- 一个子系统最多只能附加到一个层级;
- 一个层级可以附加多个子系统;
- 一个任务可以是多个 cgroup 的成员,但是这些 cgroup 必须在不同的层级;
- 系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 的成员。然后可根据需要将该子任务移动到不同的 cgroup 中,但开始时它总是继承其父任务的 cgroup。
如图所示,CPU 和 Memory 两个子系统有自己独立的层级系统,而又通过 Task Group 取得关联关系
1.3.2 cgroups子系统
cgroups 为每种可以精细化控制的资源定义了一个子系统,典型的子系统如下:
- cpu 子系统: 主要限制进程cpu的使用率(也可以理解为限制分配给cpu的core,最终限制是cpu 利用率的限制;比如一共32core 分配4core ,那这个进程cpu 最大占用率 = 12.5%,所以一个进程可以申请< 1core,因为最后是转换成比率来控制的;
- cpu 子系统,主要限制进程的 cpu 使用率。
- cpuacct 子系统:统计每个进程cpu 使用率的报告,如果达到预定的上限,可以采取一定的措施;
- cpuset 子系统:可以为进程分配单独的cpu节点或者mem节点,可以理解为为进程分配指定的额cpu占有率,就是精细化控制cpu资源;
- memery 子系统:可以限制进程memery 最大的使用量;
- blkio 子系统:可以限制进程访问的块设备io;
- device 子系统:可以控制访问的设备;
- net_cls 子系统:标记cgroups 中的网络数据包,然后可以使用tc模块(traffice control) 系统对数据包进行控制;比如namespace NET 的可以通过这个系统让namespace 内进程可以独立进行网络通信,功能类似于自己单独的网卡、单独的带宽;
- net_prio子系统:这个子系统用来设计网络流量的优先级
- freezer 子系统,可以stop或者start cgroups 管理的进程,就是监控进程的状态,如果设置了一直是start状态,就去确定环境是否是ok,如果ok就启动服务;
- ns子系统: 可以控制cgroup的进程访问不同的namespace;这个配合namespace的功能实现容器的隔离效果;
- hugetlb子系统:这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统。
这里每一个子系统都需要跟内核的其他模块配合来完成资源的控制,比如对cpu资源的控制,需要内核的进程调度模块根据cpu子系统的配置来完成;内存资源的限制需要内核的内存模块根据memery子系统的配置来完成。
1.3.3 如何查看当前系统支持哪些subsystem
可以通过查看/proc/cgroups(since Linux 2.6.24)知道当前系统支持哪些subsystem,下面是一个例子:
从左到右,字段的含义分别是:
- subsystem的名字
- subsystem所关联到的cgroup树的ID,如果多个subsystem关联到同一颗cgroup树,那么他们的这个字段将一样,比如这里的cpu和cpuacct就一样,表示他们绑定到了同一颗树。如果出现下面的情况,这个字段将为0:
-
- 当前subsystem没有和任何cgroup树绑定
- 当前subsystem已经和cgroup v2的树绑定
- 当前subsystem没有被内核开启
- subsystem所关联的cgroup树中进程组的个数,也即树上节点的个数
- 1表示开启,0表示没有被开启(可以通过设置内核的启动参数“cgroup_disable”来控制subsystem的开启).
1.4 cgroups提供的功能
- 限制进程组可以使用的资源(Resource limiting ):比如memory子系统可以为进程组设定一个memory使用上限,进程组使用的内存达到限额再申请内存,就会出发OOM(out of memory)
- 进程组的优先级控制(Prioritization ):比如可以使用cpu子系统为某个进程组分配cpu share
- 统计进程组使用的资源量(Accounting ):比如使用cpuacct子系统记录某个进程组使用的cpu时间
- 进程组隔离(Isolation):比如使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间
- 进程组控制(Control):比如使用freezer子系统可以将进程组挂起和恢复
参考链接
彻底搞懂容器技术的基石: cgroup
linux 容器(LXC) 第4章 cgroups_caoshuming_500的博客-CSDN博客
Cgroup原理及使用 - zhrx - 博客园
Linux 基础:cgroup 原理与实现_CGroup_层级_控制
【docker 底层知识】cgroup 原理分析_张忠琳的博客-CSDN博客_cgroup
CGroup的原理和使用_书笑生的博客-CSDN博客_cgroup原理
Docker核心原理之 Cgroup详解
Linux Cgroups详解(二) - lisperl - 博客园
Linux Cgroup系列(04):限制cgroup的内存使用(subsystem之memory)
Linux Cgroup系列(04):限制cgroup的内存使用(subsystem之memory) - SegmentFault 思否
Linux Cgroup系列(01):Cgroup概述
Linux Cgroup系列(01):Cgroup概述 - SegmentFault 思否
深入理解 Linux Cgroup 系列(一):基本概念
深入理解 Linux Cgroup 系列(一):基本概念 - SegmentFault 思否
深入理解 Linux Cgroup 系列(二):玩转 CPU
深入理解 Linux Cgroup 系列(二):玩转 CPU - SegmentFault 思否
深入理解 Linux Cgroup 系列(三):内存 - SegmentFault 思否