Linux Cgroup与Device Whitelist详解

第一部分:Cgroup 是什么?

CgroupControl Group 的缩写。它的核心功能是:对一组进程及其未来创建的子进程进行资源限制、隔离和统计。

你可以把它想象成一个"管理员",这个管理员可以给不同的"进程组"(比如"前端服务组"、"数据库组"、"用户A的容器组")分配固定的资源配额,防止某个组占用过多资源而影响到其他组,甚至整个系统。

Cgroup 主要管理和限制以下几类资源:

  1. CPU :限制进程组可以使用多少 CPU 时间片(cpu 子系统)或核心(cpuset 子系统)。

  2. 内存:限制进程组可以使用的最大内存量,包括物理内存和交换分区。

  3. I/O:限制进程组的磁盘读写带宽或 IOPS(每秒读写次数)。

  4. 网络 :虽然传统 Cgroup 不直接管理网络,但可以通过 net_cls 给进程组的网络包打上标签,再结合 tc 等工具进行流量控制。

  5. 设备访问 :这就是我们下面要讲的 Device Whitelist Controller 所负责的。

Cgroup 的层次结构:

Cgroup 采用树形层次结构。系统有一个根 Cgroup,下面可以创建子 Cgroup,子 Cgroup 可以继续划分。子 Cgroup 会继承父 Cgroup 的某些属性,并且其资源限制不能超过父 Cgroup。

为什么 Cgroup 如此重要?

它是现代容器技术(如 DockerLXCKubernetes)的基石之一。当你运行一个 Docker 容器时,Docker 会为这个容器创建一个或多个 Cgroup,来限制容器能使用的 CPU、内存等资源,从而实现多个容器在同一台主机上安全、隔离地运行。


第二部分:Device Whitelist Controller(设备白名单控制器)是干嘛用的?

参考链接:Device Whitelist Controller --- The Linux Kernel documentation

Device Whitelist Controller 是 Cgroup 众多子系统(或叫控制器)中的一个,它的名字通常简写为 cgroup devices 或对应的文件系统条目是 devices

它的核心功能非常简单且强大:控制一个 Cgroup 内的进程可以访问哪些设备节点。

在 Linux 中,一切皆文件,硬件设备也不例外(如 /dev/sda1/dev/kvm/dev/dri/card0 等)。默认情况下,一个进程如果有足够的文件系统权限,它就可以访问这些设备文件,从而操作底层硬件。

Device Whitelist Controller 的作用就是打破这个默认规则,实现更细粒度的设备访问控制。

它是如何工作的?------ "白名单" 机制

它遵循 "默认拒绝,显式允许" 的原则。

  1. 默认情况 :当一个 Cgroup 被创建时,如果没有进行任何配置,其内部的进程默认无法访问任何设备节点。这是一个非常严格的安全策略。

  2. 配置白名单 :系统管理员需要显式地在这个 Cgroup 的配置文件中写入规则,明确"允许" 该 Cgroup 内的进程访问哪些设备。

  3. 规则生效 :配置完成后,该 Cgroup 内的进程就只能访问规则中明确允许的设备,其他所有设备的访问都会被内核拒绝(即使进程是以 root 身份运行的)。

如何配置?

主要通过操作 Cgroup 文件系统中 devices 子系统下的几个文件:

  • devices.allow:写入允许访问的规则。

  • devices.deny:写入拒绝访问的规则(在白名单模式下较少使用)。

  • devices.list:列出当前生效的规则。

规则格式:
<type> <major>:<minor> <access>

  • <type>:

    • a:代表 All,所有类型(字符设备和块设备)。

    • c:代表 Character,字符设备。

    • b:代表 Block,块设备。

  • <major>:<minor> :设备的主设备号和次设备号。可以用 a 来表示所有设备(即 *:*)。

  • <access>:访问权限。

    • r:读权限。

    • w:写权限。

    • m:创建设备节点的权限(mknod)。

举个例子:

假设我们有一个 Cgroup 路径:/sys/fs/cgroup/devices/container_a/

  1. 查看当前规则

    bash

    复制代码
    cat /sys/fs/cgroup/devices/container_a/devices.list

    (初始状态下可能为空,意味着所有访问都被拒绝)

  2. 允许访问所有设备(通常用于特权容器,但很不安全):

    bash

    复制代码
    echo "a *:* rwm" > /sys/fs/cgroup/devices/container_a/devices.allow
  3. 更安全的做法:只允许访问空设备(/dev/null)和零设备(/dev/zero)

    bash

    复制代码
    # 首先,清除所有规则(如果需要的话,通常从一个干净的状态开始)
    # echo "a *:* rwm" > devices.deny # 这会拒绝所有,但默认就是拒绝的
    
    # 允许访问 /dev/null (字符设备,主次设备号为 1:3)
    echo "c 1:3 rwm" > /sys/fs/cgroup/devices/container_a/devices.allow
    
    # 允许访问 /dev/zero (字符设备,主次设备号为 1:5)
    echo "c 1:5 rwm" > /sys/fs/cgroup/devices/container_a/devices.allow
    
    # 现在再查看规则列表
    cat /sys/fs/cgroup/devices/container_a/devices.list

    输出会是:

    text

    复制代码
    c 1:3 rwm
    c 1:5 rwm

    现在,container_a 这个 Cgroup 里的进程只能读写 /dev/null/dev/zero,尝试访问 /dev/sda1 等设备都会失败。

总结与关系

特性 Cgroup(控制组) Device Whitelist Controller(设备白名单控制器)
角色 资源管理的框架/管理者 Cgroup 框架下的一个具体功能模块
目的 限制和隔离进程组的资源(CPU、内存、IO等) 限制和隔离进程组对设备文件的访问
关系 整体 部分(子系统)
重要性 容器技术的基石,实现资源隔离 容器安全的关键,防止容器内的进程逃逸并访问宿主机敏感硬件

简单来说:

  • Cgroup 是一个大管家,负责给不同的"家庭"(进程组)分配预算(CPU、内存等)。

  • Device Whitelist Controller 是这个大管家手下一个专门管"钥匙"的保安。它决定每个"家庭"的成员可以进入哪些"房间"(设备),其他的房间一律禁止入内。

在 Docker 等容器引擎中,当你使用 --device 参数来将宿主机设备挂载到容器内时,或者当你使用 --privileged 参数时,底层就是在操作这个 Cgroup 的 devices 子系统,来动态地修改容器的设备访问白名单。

相关推荐
A小辣椒10 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒14 小时前
TShark:基础知识
linux
AlfredZhao16 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式