Linux Cgroup

image-20200824162039070

Cgroup(Control Groups) 是 Linux kernel 的一项功能:它是在一个系统中运行的层级制进程组,可对其进行资源分配(如 CPU 时间、系统内存、网络带宽或者这些资源的组合)。通过使用 cgroup,系统管理员在分配、排序、拒绝、管理和监控系统资源等方面,可以进行精细化控制。硬件资源可以在应用程序和用户间智能分配,从而增加整体效率。

cgroup 是容器技术(如 Docker 和 Kubernetes)基础的一部分,它使得将多个容器运行在同一台机器上时能有效隔离和控制资源。

1. 基本功能

cgroup 提供了对以下资源的控制:

  • CPU:限制某些进程使用的 CPU 资源。
  • 内存:设置内存使用上限,避免进程耗尽系统内存。
  • 磁盘 I/O:控制某些进程的磁盘读取和写入速度。
  • 网络带宽:限制进程的网络传输速度。

2. cgroup 版本

  • cgroup v1:最初版本,资源控制分为多个子系统(如 cpu, memory, blkio 等)。
  • cgroup v2:改进版,统一了多个资源的管理方式,简化了配置和使用。

3. cgroup 的目录结构

在文件系统中,cgroup 通过虚拟文件系统暴露出来,可以通过 /sys/fs/cgroup/ 目录来访问。每个资源控制器都有一个对应的目录,例如 cpu, memory, blkio 等。

  • /sys/fs/cgroup/: cgroup 的主挂载点。
  • /sys/fs/cgroup/cpu/: CPU 控制器的挂载点。
  • /sys/fs/cgroup/memory/: 内存控制器的挂载点。

每个 cgroup 都会有一个目录,在该目录下存在多个文件,通过这些文件来控制和监控资源使用。

4. 常见的 cgroup 操作工具

  • cgcreate:创建一个新的 cgroup。
  • cgset:设置 cgroup 的资源限制。
  • cgexec:在某个 cgroup 中执行命令。
  • cgdelete:删除一个 cgroup。

这些工具通常属于 cgroup-tools 包。

5. 示例:cgroup 的使用

5.1. 创建一个 cgroup

首先,确保系统支持 cgroup 并安装了 cgroup-tools 包。

sudo apt install cgroup-tools

如果是amazon linux,需要使用以下方式:

sudo yum install libcgroup 
sudo yum install libcgroup-tools
# 这将安装与 cgroup 相关的一些基本工具,如 cgcreate, cgexec, cgdelete 等。

创建一个新的 cgroup(例如 mygroup):

sudo cgcreate -g memory,cpu:/mygroup

这会在 /sys/fs/cgroup/memory/mygroup//sys/fs/cgroup/cpu/mygroup/ 目录下创建对应的 cgroup。

image-20240916164220823

5.2. 限制内存使用

mygroup 设置内存限制,例如 500MB:

sudo cgset -r memory.limit_in_bytes=500M mygroup

5.3. 运行命令并应用资源限制

使用 cgexec 命令将进程放入 mygroup 并执行命令:

sudo yum install stress
sudo cgexec -g memory,cpu:/mygroup stress --vm-bytes 600M --vm-keep -m 1

这里使用 stress 工具进行压力测试,尝试分配 600MB 内存。如果超过了 500MB 的限制,进程会被杀死。

kongpingfan:~/ $ cat /sys/fs/cgroup/memory/mygroup/memory.usage_in_bytes
524111872

image-20240916164919628

5.4. 限制 CPU 使用

mygroup 的 CPU 使用限制为最多 50%:

sudo cgset -r cpu.cfs_quota_us=50000 mygroup
sudo cgset -r cpu.cfs_period_us=100000 mygroup

这表示在 100,000 微秒(100 毫秒)的周期内,进程最多可以使用 50,000 微秒的 CPU 时间,即 50%。

5.5. 查看 cgroup 统计信息

查看内存使用情况:

cat /sys/fs/cgroup/memory/mygroup/memory.usage_in_bytes

image-20240916164846129

查看 CPU 使用情况:

cat /sys/fs/cgroup/cpu/mygroup/cpuacct.usage

5.6. 删除 cgroup

删除之前创建的 cgroup:

sudo cgdelete -g memory,cpu:/mygroup

6. 实际应用场景

  • 容器化技术:如 Docker、Kubernetes 使用 cgroup 来隔离和控制容器资源。
  • 资源限制:在共享服务器上,使用 cgroup 限制某些用户或进程的资源使用,避免过度消耗系统资源。
  • 性能调优:通过 cgroup 对资源进行分配,提高系统整体性能和稳定性。

Kubernetes 中的 cgroup 使用

Kubernetes 使用 cgroup 来管理集群中各个 Pod 和容器的资源分配。Kubernetes 的资源管理涉及以下几个方面:

  1. 资源请求与限制

    • 请求(Requests):定义了容器在正常运行时所需的最低资源量。Kubernetes 使用这些信息来调度 Pod 到具有足够资源的节点上。
    • 限制(Limits):定义了容器能够使用的最大资源量。如果容器超出这个限制,Kubernetes 会限制其资源使用。
  2. CPU 限制

    • Kubernetes 支持通过资源限制来配置容器的 CPU 使用。可以在 Pod 的 resources 字段中设置 CPU 请求和限制。例如:

      resources:
        requests:
          cpu: "500m"
        limits:
          cpu: "1"
      

      在这个示例中,容器请求 0.5 个 CPU 核心,限制为 1 个 CPU 核心。

  3. 内存限制

    • 类似于 CPU 限制,Kubernetes 也允许设置内存的请求和限制。例如:

      resources:
        requests:
          memory: "512Mi"
        limits:
          memory: "1Gi"
      

      在这个示例中,容器请求 512 MiB 的内存,限制为 1 GiB 的内存。

  4. QoS(服务质量)类

    • Kubernetes 根据资源请求和限制的配置自动为 Pod 分配 QoS 类别,包括 Guaranteed、Burstable 和 BestEffort。这些类别会影响 Pod 在资源紧张时的优先级和处理方式。

cgroup 和资源管理的工作流程

  1. 容器启动:当 Docker 启动容器时,它会根据传递的参数和配置文件设置 cgroup 的参数。Kubernetes 在调度 Pod 时会根据配置文件中的请求和限制来设置 cgroup。
  2. 资源限制:cgroup 会限制容器在运行过程中可以使用的 CPU 和内存。如果容器尝试使用超出限制的资源,cgroup 会限制其资源使用,从而避免对系统的负面影响。
  3. 监控与调整:系统管理员可以使用工具(如 docker statskubectl top)来监控容器和 Pod 的资源使用情况。cgroup 提供的实时数据可以帮助管理员调整资源配置以优化性能。