云原生集群管理容器编排任务调度【免费下载链接】mesosApache Mesos项目地址https://gitcode.com/gh_mirrors/meso/mesos点击查看免费下载Apache Mesos 的cgroups/devicesisolator 利用 Linux cgroups v1 的 devices 控制器为 Mesos Containerizer 启动的容器提供设备级device访问控制容器内进程打开或mknod设备文件时内核会依据白名单逐一裁决未列入白名单的设备一律拒绝访问。本文基于 docs/isolators/cgroups-devices.md 并结合当前仓库源码讲解该 isolator 的启用方式、默认白名单的完整条目、白名单条目的语法与解析实现、deny之后再allow的写入策略以及通过--allowed_devices标志扩充白名单的完整 JSON 格式与底层处理链路。一、启用 cgroups/devices isolator要启用设备隔离只需在启动 Mesos agent 时把cgroups/devices追加到--isolation标志的逗号分隔列表中./mesos-agent --isolationfilesystem/linux,cgroups/devices,...--isolation仅对 Mesos Containerizer 生效。仓库自带的 mesos-mini 环境示例即启用了该 isolator见 agent_environmentMESOS_ISOLATIONfilesystem/linux,network/cni,cgroups/cpu,cgroups/mem,cgroups/blkio,cgroups/devices,disk/du,docker/runtime,volume/sandbox_path,volume/host_path,posix/rlimits,namespaces/pid,linux/capabilities从源码结构看cgroups/devices并不是一个独立的 isolator 进程而是统一由 cgroups isolator 接管isolator 注册表中cgroups/devices与cgroups/cpu、cgroups/mem等一样都映射到 cgroupsIsolatorSelector随后 CgroupsIsolatorProcess::create 将 isolator 名devices映射为 cgroups 子系统名devices内部常量CGROUP_SUBSYSTEM_DEVICES_NAME devices见 constants.hpp并执行两步动作通过cgroups::prepare(flags.cgroups_hierarchy, devices, flags.cgroups_root)准备/挂载 devices 层级。若该子系统尚未挂载会尝试挂载cgroup文件系统调用Subsystem::create创建 DevicesSubsystemProcess 对象作为该容器生命周期中 devices 子系统的处理单元。其中两个关键路径相关标志的默认值见 agent 标志文档标志默认值含义--cgroups_hierarchy/sys/fs/cgroupcgroups 层级根路径--cgroups_rootmesos所有容器 cgroup 的根目录名因此一个容器在 devices 层级上的 cgroup 路径通常为/sys/fs/cgroup/devices/mesos/containerId。内核机制devices 控制器白名单cgroups/devicesisolator 依赖 cgroups v1 的 devices 控制器内核文档。该控制器为每个 cgroup 维护一份设备白名单当容器内进程执行open()设备文件或调用mknod()时内核按白名单裁决通过devices.allow文件写入一条白名单记录即可放行通过devices.deny文件移除记录通过devices.list文件查询当前白名单。Mesos 侧封装了这三个操作见 src/linux/cgroups.cpp 中的cgroups::devices::list、cgroups::devices::allow、cgroups::devices::deny分别对应读devices.list、写devices.allow、写devices.deny。二、默认白名单条目开启该 isolator 后每个容器默认获得如下 13 条白名单条目继承自 原文档条目说明c *:* m允许通过 mknod(2) 新建字符设备b *:* m允许通过 mknod(2) 新建块设备c 5:1 rwm读写/dev/consolec 4:0 rwm读写/dev/tty0c 4:1 rwm读写/dev/tty1c 136:* rwm读写/dev/pts/*伪终端c 5:2 rwm读写/dev/ptmxc 10:200 rwm读写/dev/net/tunTUN/TAP 虚拟网络设备c 1:3 rwm读写/dev/nullc 1:5 rwm读写/dev/zeroc 1:7 rwm读写/dev/fullc 5:0 rwm读写/dev/ttyc 1:9 rwm读写/dev/urandomc 1:8 rwm读写/dev/random这些条目与 devices.cpp 中的DEFAULT_WHITELIST_ENTRIES数组一一对应isolator 在创建时逐条解析为Entry对象// src/slave/containerizer/mesos/isolators/cgroups/subsystems/devices.cpp static const char* DEFAULT_WHITELIST_ENTRIES[] { c *:* m, // Make new character devices. b *:* m, // Make new block devices. c 5:1 rwm, // /dev/console ... c 1:9 rwm, // /dev/urandom c 1:8 rwm, // /dev/random };cgroups v2 路径DeviceControllerProcess也维护了一份完全相同的默认列表见 cgroups2/controllers/devices.cpp因此两种 cgroups 版本下的默认行为保持一致。白名单条目的语法每条白名单由 4 个字段语义构成原文档定义typeaall全部类型与全部主次设备号、c字符设备、b块设备major:minor主次设备号均为整数或*通配所有accessrread(2)、wwrite(2)、mmknod(2)的任意组合。Mesos 在 Entry::parse 中实现了这一语法的解析其要点输入按空格切分为 token。若首 token 为a则等价于*:*加rwm全放行其余字段被忽略否则必须恰好是 3 个 token{b|c} major:minor [r][w][m]major、minor必须是*或无符号整数解析失败返回Error(Invalid format)权限串长度不得超过 3且只能包含r、w、m任何非法字符都视为格式错误。序列化方向Entry→ 字符串用于写devices.allow同样在 src/linux/cgroups.cpp 中实现ALL/BLOCK/CHARACTER分别输出为a/b/c缺省的major/minor输出为*权限按rwm顺序拼接。两点安全注意原文档强调白名单基于设备号major:minor与/dev目录内容的填充正交。/dev节点通常由 udev 或 devtmpfs 负责创建Mesos 只控制是否允许访问不控制节点是否存在。无论设备是否在白名单中执行mknod(2)都需要CAP_MKNOD能力。默认白名单中的c *:* m、b *:* m两条只授予 mknod 权限并不豁免能力检查。三、deny 之后再 allow源码级写入流程DevicesSubsystemProcess的生命周期钩子为prepare/recover/cleanup/isolate由上层 cgroups isolator 在容器准备、agent 恢复、容器清理等阶段统一驱动见 CgroupsIsolatorProcess::prepare。prepare是设备白名单真正生效的入口其策略见 devices.cpp先拒绝一切设备构造一条a *:* rwm全部类型、全部主次号、全部权限记录写入devices.deny再逐条放行将默认白名单 --allowed_devices配置得到的whitelistDeviceEntries依次写入devices.allow。源码注释解释了为什么要先 deny 再 allow新建的 devices cgroup 会从父 cgroup继承完整白名单默认即a *:* rwm。理论上也可以直接往devices.deny写入要移除的条目但 deny 的语义只移除白名单中显式列出的条目——当白名单只有a *:* rwm时denyb 1:3 rwm并不会改写白名单尽管访问实际会被拒绝但没有任何途径查询到这一变化。因此 Mesos 选择先 deny 掉全放行条目使白名单处于空集再显式逐条 allow从而让devices.list中可见的条目与实际控制效果完全一致、可审计。recover与cleanup本身不触碰白名单cgroup 上的条目会随 cgroup 目录销毁而消失只维护进程内部containerIds集合以记录已知容器防止重复 recover/prepare。cgroups v2 路径在 cgroups v2 层级上devices 控制通过 DeviceControllerProcess 实现。其白名单构建逻辑与 v1 完全相同同样的DEFAULT_WHITELIST_ENTRIES与flags.allowed_devices解析区别在于prepare阶段不再直接写控制文件而是委托DeviceManager完成return deviceManager-configure(cgroup, whitelistDeviceEntries, {}) .then(defer(self(), [] { ... }));DeviceManager见 device_manager.hpp结合 eBPFebpf.cpp/ebpf.hpp生成并挂载devices.bpf程序到容器的 cgroup由内核中的 BPF 程序按同样的主次设备号 权限规则裁决设备访问。因此在 v2 主机上该 isolator 同样可用但依赖内核对 cgroup eBPF 的支持。四、使用 --allowed_devices 扩充白名单原文档给出的操作方式是通过 agent 的--allowed_devices标志传入一个 JSON 对象或指向含该 JSON 的文件的路径。例如{ allowed_devices: [ { device: { path: /path/to/device }, access: { read: true, write: false, mknod: false } } ] }标志定义与 protobuf 结构该标志在 src/slave/flags.hpp 中声明为OptionDeviceWhitelist allowed_devices其标志描述含上述 JSON 示例注册于 src/slave/flags.cpp。描述中明确默认白名单包含/dev/console、/dev/tty0、/dev/tty1、/dev/pts/*、/dev/ptmx、/dev/net/tun、/dev/null、/dev/zero、/dev/full、/dev/tty、/dev/urandom、/dev/random且该标志仅在--isolation中设置了cgroups/devices时才生效。JSON 反序列化目标为 include/mesos/mesos.proto 中定义的消息message DeviceAccess { message Access { optional bool read 1; optional bool write 2; optional bool mknod 3; } required Device device 1; required Access access 2; } message DeviceWhitelist { repeated DeviceAccess allowed_devices 1; }注意device字段是required的Device按路径指定而access三个布尔均为optional——缺省语义是不授予该权限。源码如何消费该配置DevicesSubsystemProcess::create 在 isolator 创建阶段即 agent 启动、解析隔离配置时处理该标志逐条转换为 cgroups 白名单记录必须有路径device_access.device().has_path()为假则直接报错Whitelisted device has no device path provided必须至少一种权限read/write/mknod全为假则报错Could not whitelist device path without any access privileges路径 → 设备号通过os::stat::rdev(path)取dev_t通过os::stat::mode(path)判定设备类型——S_ISBLK映射为BLOCKS_ISCHR映射为CHARACTER既非块也非字符则报错Failed to determine device type。也就是说配置里写的是宿主机上真实存在的设备文件路径isolator 负责解析其主次设备号并生成形如c 7:0 rwm的精确条目minor恒为具体整数不做通配生成的Entry追加进whitelistDeviceEntries与默认列表合并后交给prepare阶段的 allow 循环写入。因此若path指向普通文件或不存在的路径agent 在创建 isolator 时就会失败并给出对应的错误信息这是排查--allowed_devices配置问题的第一站。与 linux/devices isolator 的分工cgroups/devices只解决是否允许访问容器内要真正使用设备还需要/dev下存在对应节点。Mesos 用 linux/devices isolator 解决节点填充问题它根据同样的--allowed_devices配置在容器 rootfs 中创建mknod节点由 agent 在容器外代为执行因此不需要为容器授予 mknod 访问权限。两者的典型组合为--isolation...,cgroups/devices,linux/devices,filesystem/linux,...gpu/nvidia isolator 对其的硬依赖设备白名单能力还被 GPU 隔离复用NvidiaGpuIsolatorProcess::create 在--isolation包含gpu/nvidia时会显式检查必须同时启用cgroups/devices或cgroups/all以及filesystem/linux否则报错退出。其原因是nvidia-modeset等设备访问依赖 cgroups 设备白名单放行。配置 NVIDIA GPU 隔离时这是必须同时满足的前提。五、验证与测试运行时验证容器 cgroup 准备完成后可直接查看内核维护的白名单cat /sys/fs/cgroup/devices/mesos/containerId/devices.list启用cgroups/devices后输出应为上文 13 条默认条目加上--allowed_devices解析出的条目由于先 deny 后 allow策略输出中不会出现继承自父 cgroup 的a *:* rwm所见即所得。仓库测试覆盖src/tests/containerizer/cgroups_isolator_tests.cpp集成测试在flags.isolation中显式包含cgroups/devices第 140 行附近覆盖 cgroups 容器生命周期的各子场景src/tests/containerizer/linux_devices_isolator_tests.cpp以参数化用例验证allowed_devicesJSON含/dev/loop-control、/dev/net/tun等路径及只读/只写/读写权限组合驱动节点填充与访问权限的对应关系例如test -r /dev/loop-control test ! -w /dev/loop-control断言只读条目只授予读权限。六、小结cgroups/devicesisolator 是 Mesos 容器化部署中设备安全基线的组成部分其要点可以归纳为启用--isolation追加cgroups/devices底层由统一 cgroups isolator 驱动DevicesSubsystemProcessv1或DeviceControllerProcessDeviceManager/eBPFv2默认白名单13 条内置条目覆盖控制台、伪终端、/dev/null、/dev/zero、/dev/random等基础设备及 mknod 权限定义在 devices.cpp写入策略prepare 时先deny a *:* rwm清空继承来的全放行条目再逐条allow保证devices.list与实际控制效果一致扩充白名单--allowed_devices接收DeviceWhitelistJSONisolator 通过stat将设备路径解析为精确的type major:minor access条目配置错误无路径、无权限、非设备文件会在 isolator 创建阶段直接报错配套linux/devicesisolator 负责/dev节点填充gpu/nvidiaisolator 以cgroups/devices为硬性前提mknod(2)始终额外要求CAP_MKNOD。适用前提Linux 环境且内核启用了 cgroups devices 控制器v1或 cgroup eBPF 支持v2agent 需具备 root 权限以操作 cgroup 控制文件。赞分享云原生集群管理容器编排任务调度【免费下载链接】mesosApache Mesos项目地址https://gitcode.com/gh_mirrors/meso/mesos点击查看免费下载相关推荐Apache Mesos cgroups devices 隔离器为 Mesos Containerizer 提供容器设备白名单隔离Apache Mesos cgroups devices 隔离器为 Mesos Containerizer 提供容器设备白名单隔离 cgroups/devic云原生Apache Mesos 设备隔离实战Mesos Containerizer 中 cgroups/devices 隔离器的原理与配置Apache Mesos 设备隔离实战Mesos Containerizer 中 cgroups/devices 隔离器的原理与配置 Apache Mesos集群管理任务调度后端Apache Mesos cgroups blkio 隔离器容器块设备 I/O 统计采集原理与实战Apache Mesos cgroups blkio 隔离器容器块设备 I/O 统计采集原理与实战 cgroups/blkio 是 Apache Mesos集群管理任务调度后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考