Docker② —— Cgroups详解

embedded/2024/11/15 4:35:44/

1. 概述

  • Cgroups 的全称是control groups,cgroups为每种可以控制的资源定义了一个子系统。
  • Cgroups分为三个部分:
    • cgroup 本身:对进程进行分组
    • hierarchy:将 cgroup 形成树形结构
    • subsystem:真正起到限制作用的部组件
      • cpu 子系统:主要限制进程的 cpu 使用率。
      • cpuacct 子系统:可以统计 cgroups 中的进程的 cpu 使用报告。
      • cpuset 子系统:可以为 cgroups 中的进程分配单独的 cpu 节点或者内存节点。
      • memory 子系统:可以限制进程的 memory 使用量。
      • blkio 子系统:可以限制进程的块设备 io。
      • devices 子系统:可以控制进程能够访问某些设备。
      • net_cls 子系统:可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制。
      • freezer 子系统:可以挂起或者恢复 cgroups 中的进程。
      • ns 子系统:可以使不同 cgroups 下面的进程使用不同的 namespace。
  • 这里面每一个子系统都需要与内核的其他模块配合来完成资源的控制,比如对 cpu 资源的限制是通过进程调度模块根据 cpu 子系统的配置来完成的;对内存资源的限制则是内存模块根据 memory 子系统的配置来完成的,而对网络数据包的控制则需要 Traffic Control 子系统来配合完成。

2. Cgroups 层级结构(Hierarchy)

  • 内核使用 cgroup 结构体来表示一个 control group 对某一个或者某几个 cgroups 子系统的资源限制。
  • cgroup 结构体可以组织成一颗树的形式,每一棵cgroup 结构体组成的树称之为一个 cgroups 层级结构。
  • cgroups层级结构可以 attach 一个或者几个 cgroups 子系统,当前层级结构可以对其 attach 的 cgroups 子系统进行资源的限制。
  • 每一个 cgroups 子系统只能被 attach 到一个 cpu 层级结构中。

在这里插入图片描述

  • 上图表示两个cgroups层级结构,每一个层级结构中是一颗树形结构,树的每一个节点是一个 cgroup 结构体(比如cpu_cgrp, memory_cgrp)。
    • 第一个 cgroups 层级结构 attach 了 cpu 子系统和 cpuacct 子系统, 当前 cgroups 层级结构中的 cgroup 结构体就可以对 cpu 的资源进行限制,并且对进程的 cpu 使用情况进行统计。
    • 第二个 cgroups 层级结构 attach 了 memory 子系统,当前 cgroups 层级结构中的 cgroup 结构体就可以对 memory 的资源进行限制。
  • 在每一个 cgroups 层级结构中,每一个节点(cgroup 结构体)可以设置对资源不同的限制权重。比如上图中 cgrp1 组中的进程可以使用60%的 cpu 时间片,而 cgrp2 组中的进程可以使用20%的 cpu 时间片。

3. 进程与 Cgroups 层级结构的联系

  • 在创建了 cgroups 层级结构中的节点(cgroup 结构体)之后,可以把进程加入到某一个节点的控制任务列表中,一个节点的控制列表中的所有进程都会受到当前节点的资源限制。
  • 同时某一个进程也可以被加入到不同的 cgroups 层级结构的节点中,因为不同的 cgroups 层级结构可以负责不同的系统资源。所以说进程和 cgroup 结构体是一个多对多的关系。

在这里插入图片描述

  • P代表一个进程。每一个进程的描述符中有一个指针指向了一个辅助数据结构css_set(cgroups subsystem set)。 指向某一个css_set的进程会被加入到当前css_set的进程链表中。一个进程只能隶属于一个css_set,一个css_set可以包含多个进程,隶属于同一css_set的进程受到同一个css_set所关联的资源限制。
  • ”M×N Linkage”说明的是css_set通过辅助数据结构可以与 cgroups 节点进行多对多的关联。但是 cgroups 的实现不允许css_set同时关联同一个cgroups层级结构下多个节点。 这是因为 cgroups 对同一种资源不允许有多个限制配置。
  • 一个css_set关联多个 cgroups 层级结构的节点时,表明需要对当前css_set下的进程进行多种资源的控制。而一个 cgroups 节点关联多个css_set时,表明多个css_set下的进程列表受到同一份资源的相同限制。

4. Cgroups文件系统

  • Linux内核通过 VFS (Virtual File System)把具体文件系统的细节隐藏起来,给用户态进程提供一个统一的文件系统 API 接口。 Cgroups 也是通过 VFS 把功能暴露给用户态的,cgroups 与 VFS 之间的衔接部分称之为 Cgroups 文件系统。
  • VFS 通用文件模型中包含以下四种元数据结构:
    • 超级块对象(superblock object),用于存放已经注册的文件系统的信息。
      • 比如ext2,ext3等这些基础的磁盘文件系统,还有用于读写socket的socket文件系统,以及当前的用于读写cgroups配置信息的 cgroups 文件系统等。
    • 索引节点对象(inode object),用于存放具体文件的信息。
      • 对于一般的磁盘文件系统而言,inode 节点中一般会存放文件在硬盘中的存储块等信息;
      • 对于socket文件系统,inode会存放socket的相关属性;
      • 对于cgroups这样的特殊文件系统,inode会存放与 cgroup 节点相关的属性信息。这里面比较重要的一个部分是一个叫做 inode_operations 的结构体,这个结构体定义了在具体文件系统中创建文件,删除文件等的具体实现。
    • 文件对象(file object),一个文件对象表示进程内打开的一个文件,文件对象是存放在进程的文件描述符表里面的。同样这个文件中比较重要的部分是一个叫 file_operations 的结构体,这个结构体描述了具体的文件系统的读写实现。当进程在某一个文件描述符上调用读写操作时,实际调用的是 file_operations 中定义的方法。
      • 对于普通的磁盘文件系统,file_operations 中定义的就是普通的块设备读写操作;
      • 对于socket文件系统,file_operations 中定义的就是 socket 对应的 send/recv 等操作;
      • 对于cgroups这样的特殊文件系统,file_operations 中定义的就是操作 cgroup 结构体等具体的实现。
    • 目录项对象(dentry object),在每个文件系统中,内核在查找某一个路径中的文件时,会为内核路径上的每一个分量都生成一个目录项对象,通过目录项对象能够找到对应的 inode 对象,目录项对象一般会被缓存,从而提高内核查找速度。

dockerCgroups_54">5. docker是怎么使用Cgroups的

  • Docker 在实现不同的 Container 之间资源隔离和控制的时候,是可以创建比较复杂的 cgroups 节点和配置文件来完成的。然后对于同一个 Container 中的进程,可以把这些进程 PID 添加到同一组 cgroups 子节点中已达到对这些进程进行同样的资源限制。
  • 如何实现:
    • 为每个容器创建一个子Cgroup
    • 根据 docker run 时提供的参数调整 Cgroup 中的配置
    • 容器被停止或删除时同步删除对应子 Cgroup
  • 具体实例:
    • 第一步,启动一个容器,用-m来设置内存参数为128M
      • 该命令执行后 docker 会在 memory cgroup 上(也就是 /sys/fs/cgroup/memory 路径下)创建一个叫 docker 的子 cgroup,即/sys/fs/cgroup/memory/docker/
      • 在这里插入图片描述
      • 内部除了 cgroup 相关的文件外,还有很多目录,使用容器 ID 作为目录名,其中每个目录即对应一个容器。其中,da82f9e...这个目录名称和容器 ID 一致,说明 docker 是为每个容器创建了一个子 cgroup 来单独限制。
      • 查看里面的配置可以发现,memory.limit_in_bytes 中配置的值为 134217728,转换一下134217728/1024/1024=128M, 刚好就是我们指定的 128M
    • 第二步,停止该容器(不是删除容器),再次查看cgroup情况,发现目录已经被删除,说明容器对应的子 cgroup 也同步被回收
    • 第三步,把停止的容器start,再次查看Cgroup情况,可以发现同名目录又被创建出来了

http://www.ppmy.cn/embedded/17271.html

相关文章

Redis入门到通关之数据结构解析-ZipList

文章目录 ☃️概述☃️ZipListEntry☃️Encoding编码☃️ZipList的连锁更新问题☃️总结 欢迎来到 请回答1024 的博客 🍓🍓🍓欢迎来到 请回答1024的博客 关于博主: 我是 请回答1024,一个追求数学与计算的边界、时间与…

Java23种设计模式-行为型模式之模板方法模式

模板方法模式(Template Method Pattern)在超类中定义了一个算法的骨架,将一些步骤延迟到子类中实现。模板方法模式使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。 基本组成: Abstract (抽…

python网络爬虫爬取需要的数据

要爬取网站的数据,你可以使用 Python 的 requests 库来发送 HTTP 请求,并使用 BeautifulSoup 库来解析返回的 HTML 内容。但是,在此之前,你需要检查该网站的 robots.txt 文件,以确认是否允许爬虫抓取特定页面的数据。 …

BERT(Bidirectional Encoder Representations from Transformers)

BERT(Bidirectional Encoder Representations from Transformers)在深度学习中指的是一种基于Transformer架构的预训练模型,特别用于自然语言处理(NLP)任务。BERT是由Google的研究团队在2018年提出的,并且迅…

Linux查看僵尸进程

1、查看系统是否有僵尸进程 使用Top命令查找,当zombie前的数量不为0时,即系统内存在相应数量的僵尸进程。 2、定位僵尸进程 使用命令ps -A -ostat,ppid,pid,cmd |grep -e ‘^[Zz]’定位僵尸进程以及该僵尸进程的父进程。 3、杀死僵尸进程 使用Kill -…

Scrapy爬虫框架入门(豆瓣电影Top 250)

文章目录 Scrapy 官网Scrapy 文档GithubScrapy 简介项目结构爬虫实现XPath 教程创建 Scrapy 项目配置用户代理网页 dom 元素 IP 代理池IP代理池作用配置IP代理池申请IP代理池 Scrapy 官网 https://scrapy.org/ Scrapy 文档 https://docs.scrapy.org/en/latest/ Github htt…

大数据分析:使用Spark和Hadoop的实用指南

Apache Spark 和 Apache Hadoop 是两个在大数据生态系统中非常流行的框架。Hadoop 主要用于数据存储和处理大规模数据集的批处理作业,而 Spark 是一个强大的计算框架,提供了更快的计算速度和更高效的数据处理能力。这里提供一个实用指南,帮助…

【剪映专业版】11音频的全流程剪辑操作

视频课程:B站有知公开课【剪映电脑版教程】 1.音乐素材 可能包含人声,音乐素材普遍比较长,几十秒到几分钟。要点击倒三角才会出现分类。 点击下载箭头下载素材;点击加号将素材增加到轨道;时间指示器在哪个地方&#…