一、cgroup有什么用?

你可以把它想象成一个资源管理器

cgroup 的全称是 control groups,即“控制组”。它的主要目的是对一组进程进行资源分配、限制、控制和统计

在没有 cgroup 之前,Linux 系统上的所有进程在资源使用(CPU、内存等)上是“平等”的,它们会相互竞争。这可能导致某个进程耗尽系统资源,从而导致其他重要进程无法运行,甚至整个系统崩溃。

这个cgroup有点像windows系统里的进程管理器一样。

cgroup 通过将进程分组,然后为这些组设置资源限制,完美地解决了资源限制(CPU、内存、I/O)、优先级分配、资源统计、进程控制等问题。

一个简单的比喻:
想象一个宿舍楼(整个服务器)里住着很多学生(进程)。如果没有管理,某些学生可能会通宵开大功率电器(耗尽资源),导致整栋楼跳闸。cgroup 就像是给每个宿舍(进程组)安装了独立的电表(统计)和限流器(限制),规定每个宿舍每月最多只能用 100 度电(资源限制),并且优先保证学习宿舍的供电(优先级)。这样,即使有宿舍用电超标,也不会影响其他宿舍的正常用电。

最典型的应用场景:容器技术
Docker、Kubernetes 等容器技术的底层核心依赖就是 cgroup(和 namespace)。cgroup 负责资源限制,确保容器不会耗尽主机资源;namespace 负责隔离,让容器拥有独立的视图。

cgroup 处于 Linux 系统的内核层,并通过 /sys/fs/cgroup/ 目录下的虚拟文件系统向用户空间提供管理接口。它对资源的控制非常直接和强大,成为了现代云计算和容器化技术的基石。

二、k8s中cgroup的用途

Kubelet和底层容器运行时都需要对接 cgroup 来强制执行为Pod和容器管理资源, 这包括为容器化工作负载配置 CPU/内存请求和限制。

cgroup的版本:

Linux 中有两个 cgroup 版本:cgroup v1 和 cgroup v2。

cgroup v2 是 Linux cgroup API 的下一个版本。cgroup v2 提供了一个具有增强资源管理能力的统一控制系统。

识别 Linux 节点上的 cgroup 版本

cgroup 版本取决于正在使用的 Linux 发行版和操作系统上配置的默认 cgroup 版本。 要检查你的发行版使用的是哪个 cgroup 版本,请在该节点上运行下面命令:

stat -fc %T /sys/fs/cgroup/

对于 cgroup v2,输出为 cgroup2fs。
对于 cgroup v1,输出为 tmpfs。

三、CRI(容器运行时接口)的用途

容器运行时接口(CRI):CRI 是一个插件接口,它使 kubelet 能够使用各种容器运行时,无需重新编译集群组件。
你需要在集群中的每个节点上都有一个可以正常工作的容器运行时, 这样 kubelet 能启动 Pod 及其容器。


容器运行时接口(CRI)是 在 kubelet 与容器运行时之间通信的主要协议。
Kubernetes 容器运行时接口(CRI)定义了在节点组件 kubelet 和容器运行时之间通信的主要 gRPC 协议。

当通过 gRPC 连接到容器运行时,kubelet 将充当客户端。运行时和镜像服务端点必须在容器运行时中可用, 可以使用 --container-runtime-endpoint 命令行标志在 kubelet 中单独配置。

对于 Kubernetes v1.26 及更高版本, kubelet 要求容器运行时必须支持 v1 版本的 CRI API。 如果容器运行时不支持 v1 API,kubelet 将不会注册该节点。

四、cgroup和CRI在k8s中的比喻

核心比喻:K8s 就像一个现代化的监狱系统

要理解 k8s 管理容器的两大基石(cgroup 和 CRI),我们可以把它想象成管理一座监狱:

  • K8s 管理者: 监狱长

  • 容器: 一个个囚犯

  • Pod: 关押囚犯的牢房

  • cgroup: 牢房的物理限制(空间大小、伙食配额)

  • CRI: 监狱长和狱警之间的标准工作指令

在 K8s 中的作用:
当你在 K8s 的 YAML 文件里设置 resources.requests/limits 时,K8s 就是通过底层运行时(如 Docker)调用 cgroup 来给容器“画牢房”。

resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"

这相当于命令:给这个容器分配一个最小 64Mi 内存、0.25核CPU的保障,但最大不能超过 128Mi 内存和 0.5核CPU。

简单流程:

K8s 调度器 --(通过 CRI 接口)--> 容器运行时(如 containerd) --(调用 Linux 内核的 cgroup 功能)--> 最终实现容器的资源限制

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐