ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

youki 的 libcgroups crate:基于 Rust 的 Linux cgroups 统一操作库深度解析

youki 的 libcgroups crate:基于 Rust 的 Linux cgroups 统一操作库深度解析 容器运行时云原生【免费下载链接】youkiA container runtime written in Rust项目地址https://gitcode.com/gh_mirrors/yo/youki点击查看免费下载导读libcgroups 是 Rust 容器运行时 youki 中专门负责 Linux cgroups控制组功能的子 crate为读写 cgroups 文件提供统一、易用的接口并内置了多套表示 cgroups 数据的数据结构。它在 youki 项目中扮演着资源管理底层引擎的角色无论是限制 CPU、内存、I/O还是冻结/恢复进程、统计资源用量最终都要经由它落到/sys/fs/cgroup下的内核接口文件上。读完本文你将掌握 libcgroups 的模块划分、CgroupManager抽象接口、v1/v2/systemd 三种管理器的选型逻辑、统计数据结构以及如何在自己的 Rust 项目中以依赖方式使用它。libcgroups 是什么libcgroups 是 youki 的 Cargo 工作区workspace中的子 crate 之一定义在 crates/libcgroups/Cargo.toml包名为libcgroups版本 0.7.0许可协议为 Apache-2.0要求 Rust 1.85.0 及以上edition 2024。它的定位非常明确集中封装与 Linux cgroups 交互的所有逻辑向上为 youki 主程序提供能力向下屏蔽 cgroups v1/v2 与 systemd 托管之间的差异。从入口文件 crates/libcgroups/src/lib.rs 可以看到crate 对外暴露的模块恰好与官方文档描述一致模块职责common与 cgroup 版本无关的通用功能读写文件、探测系统 cgroup 布局、管理器工厂函数、公共 traitstatscgroups 统计数据的数据结构定义与解析工具函数systemd与 systemd 交互DBus 通信、systemd 托管 cgroup仅在启用systemdfeature 时生效test_manager供测试使用的假管理器TestManagerv1cgroups v1 专属功能与 v1 管理器仅在启用v1feature 时生效v2cgroups v2 专属功能、v2 管理器与 BPF 设备控制器仅在启用v2feature 时生效需要特别注意的是模块的条件编译v1、v2、systemd都是 feature gate。默认 feature 为[v1, v2, systemd]见 crates/libcgroups/Cargo.toml当某个 feature 未启用时lib.rs 会用stub目录下的占位实现如 crates/libcgroups/src/stub/systemd/mod.rs、crates/libcgroups/src/stub/v1/mod.rs、crates/libcgroups/src/stub/v2/mod.rs替换真实模块这样可以在编译期裁剪不需要的功能。此外还有一个cgroupsv2_devicesfeature启用后才会编译 v2 的 BPF 设备控制器依赖rbpf、libbpf-sys、errno、libc、nix/dir。common 模块所有 cgroup 的通用地基common 模块 承载的是与具体 cgroup 版本无关的通用逻辑是整个 crate 最核心的抽象层。traitCgroupManager统一的管理器接口CgroupManager是 v1/v2/systemd 三类管理器共同实现的抽象接口其定义位于 crates/libcgroups/src/common.rs。它通过关联类型type Error让每种管理器携带各自的错误类型并定义了六个操作add_task(self, pid: Pid)把指定 PID 的任务加入 cgroupapply(self, controller_opt: ControllerOpt)应用资源限制CPU、内存、I/O、PID 上限等remove(self)删除 cgroup实现中会先杀掉其中的进程freeze(self, state: FreezerState)设置 freezer cgroup 状态冻结/解冻stats(self) - Stats获取 cgroup 统计信息get_all_pids(self) - VecPid获取 cgroup 内所有 PID。为了让上层调用方不必关心具体是哪种管理器common 中还提供了AnyCgroupManager枚举Systemd/V1/V2三个变体以及对应的AnyManagerError并统一为AnyCgroupManager实现了CgroupManagertrait内部通过 match 分派到具体管理器见 crates/libcgroups/src/common.rs。这意味着 youki 主程序只需要拿到一个AnyCgroupManager就能完成所有 cgroup 操作而无需关心底层是 v1 还是 v2。apply接收的ControllerOpt定义于 crates/libcgroups/src/common.rs包含四个字段resources: LinuxResources来自 OCI runtime spec 的 Linux 资源约束oci-speccrate 的LinuxResources类型是资源限制的数据来源disable_oom_killer: bool是否关闭 OOM killeroom_score_adj: Optioni32为容器设置oom_score_adj可选freezer_state: OptionFreezerState传递给 freezer 控制器的冻结状态可选。FreezerState枚举crates/libcgroups/src/common.rs有三个取值Undefined任务状态未定义、Frozen任务被挂起、Thawed任务恢复执行。此外AnyCgroupManager还提供了一个with_rootless(rootless: bool)方法用于标记根lessrootless环境。从实现看它只对 v2 管理器生效见 crates/libcgroups/src/common.rs在 rootless / 容器嵌套场景下cgroup 层级往往是只读的v2 管理器会把EROFS、EACCES这类权限错误降级为日志记录而不是直接失败对应实现见 crates/libcgroups/src/v2/manager.rs。文件读写工具函数common 模块提供了三个最基础的文件操作函数它们内部统一把std::io::Error包装为带路径信息的WrappedIoError方便排查是哪个 cgroup 文件操作失败write_cgroup_file_str(path, data: str)向 cgroup 文件写入字符串数据crates/libcgroups/src/common.rs。注意它使用OpenOptions以create(false)、truncate(false)打开文件即不创建、不截断仅以写入模式打开已存在的 cgroup 接口文件后write_allwrite_cgroup_file(path, data: T)泛型版本内部先to_string()再调用前者crates/libcgroups/src/common.rs常见的用法是传入Pid、i64等实现了ToString的值read_cgroup_file(path) - String读取 cgroup 文件的全部内容crates/libcgroups/src/common.rs。cgroup 布局探测与管理器工厂get_cgroup_setup_with_root(root_path)用于检测系统当前的 cgroup 布局返回CgroupSetup枚举定义于 crates/libcgroups/src/common.rs共有三种取值Unified纯 cgroup v2 系统Legacy纯 cgroup v1 系统Hybrid以 cgroup v1 为主另挂载了一个不绑定任何控制器的统一v2层级资源控制只能通过 v1 层级完成。检测逻辑见 crates/libcgroups/src/common.rs基于statfs系统调用若指定根路径的文件系统类型是CGROUP2_SUPER_MAGIC则为 Unified若是TMPFS_MAGIC则继续检查该路径下是否存在挂载了 cgroup2 的unified子目录存在为 Hybrid否则为 Legacy。get_cgroup_setup()是它的便捷版本默认使用根路径/sys/fs/cgroup对应常量DEFAULT_CGROUP_ROOT见 crates/libcgroups/src/common.rs。create_cgroup_manager_with_root(root_path, config)是管理器工厂函数先探测 cgroup 布局再按需创建对应管理器见 crates/libcgroups/src/common.rs当布局为Legacy或Hybrid时 → 创建 v1 管理器当布局为Unified时若cgroup_path是绝对路径或未开启 systemd cgroup!config.systemd_cgroup→ 创建 v2 管理器否则创建 systemd 管理器前提是系统确实以 systemd 启动否则返回SystemdNotAvailable错误。create_cgroup_manager(config)等价于传入默认根路径的版本。两者的config都是CgroupConfigcrates/libcgroups/src/common.rs包含三个字段cgroup_pathcgroup 相对路径、systemd_cgroup是否使用 systemd 托管、container_name容器名systemd unit 命名用。其他通用工具get_all_pids(path)递归遍历 cgroup 目录树读取每个子目录的cgroup.procs文件汇总所有 PIDcrates/libcgroups/src/common.rsv2 管理器的get_all_pids即复用它PathBufExt::join_safely安全拼接路径对绝对路径会先剥掉开头的/再拼接到根路径下防止路径逃逸crates/libcgroups/src/common.rsdelete_with_retry(path, retries, limit_backoff)带重试与指数退避的目录删除重试间隔从 10ms 起步超过limit_backoff后封顶crates/libcgroups/src/common.rsdefault_allow_devices()/default_devices()在启用cgroupsv2_devices或v1feature 时提供设备 cgroup 的默认允许列表如/dev/console、/dev/pts、tun/tap 等与默认设备节点列表如/dev/null、/dev/zero、/dev/random等crates/libcgroups/src/common.rsWrapIoResulttrait把std::io::Result转换为带路径上下文的WrappedIoError是上面所有错误包装的基础设施。stats 模块cgroups 统计数据模型stats 模块 定义了 cgroups 统计信息的全部数据结构并通过StatsProvidertrait 抽象了从 cgroup 路径读取统计的行为v1/v2 各自实现。Stats顶层结构与各统计子结构Stats是汇总结构crates/libcgroups/src/stats.rs实现了Serialize可直接序列化为 JSON 输出youki 的stats/events命令正是依赖它。它由以下子结构组成CpuStatsCPU 统计。含usage: CpuUsageusage_total总 CPU 时间、usage_user用户态时间、usage_kernel内核态时间、以及按核细分的per_core_usage_total/user/kernel三个向量与throttling: CpuThrottlingperiods已过去的周期数、throttled_periods被节流的周期数、throttled_time被节流的总时长以及psiCPU 的 Pressure Stall InformationMemoryStats内存统计。含memory、memswap、kernel、kernel_tcp四组MemoryData每组含usage当前用量、max_usage历史峰值、fail_count触顶次数、limit上限外加cache页缓存字节数、hierarchy是否启用层级记账、stats各类内存细分统计的 map和psiPidStatsPID 统计。current为当前活跃 PID 数limit为允许的 PID 数上限0 表示无限制。对应的读取函数pid_stats会读取pids.current与pids.max两个文件其中pids.max为字符串max时表示不限crates/libcgroups/src/stats.rsBlkioStats块 I/O 统计。包含service_bytes传输字节数、servicedI/O 操作次数、time设备访问时间、sectors扇区数、service_time、wait_time、queued、merged等每个都是VecBlkioDeviceStatBlkioDeviceStat含major/minor设备号、可选的op_type操作类型与value统计值crates/libcgroups/src/stats.rsHugeTlbStatsHugeTLB 大页统计含usage、max_usage、fail_count。注意Stats.hugetlb的类型是HashMapString, HugeTlbStats以页面大小如2MB为 key因为系统可能同时支持多种大页尺寸。PSIStats与PSIData用于承载内核的 Pressure Stall Informationsome表示部分任务因资源短缺被延迟的壁钟时间占比full表示全部任务被延迟的占比avg10/avg60/avg300分别为 10 秒、60 秒、300 秒滑动平均crates/libcgroups/src/stats.rs。统计解析工具函数supported_page_size/supported_page_sizes扫描/sys/kernel/mm/hugepages目录把形如hugepages-2048kB的目录名解析为2MB这样的可读尺寸2^20KB 以上折算为 GB2^10以上折算为 MB返回系统支持的巨页尺寸列表crates/libcgroups/src/stats.rsparse_single_value读取只含单个数值的 cgroup 文件并解析为u64遇到max时返回u64::MAXcrates/libcgroups/src/stats.rsparse_flat_keyed_data解析键 值扁平键值对格式的文件如key1 1\nkey2 2返回HashMapString, u64每行必须恰好两个字段否则报错crates/libcgroups/src/stats.rsparse_nested_keyed_data解析键 子键值 ...嵌套键值格式的文件返回HashMapString, VecString要求首字段后的每个字段都包含crates/libcgroups/src/stats.rsparse_device_number解析形如8:0的major:minor设备号返回(u64, u64)元组多于或少于两个冒号分隔段都会报错crates/libcgroups/src/stats.rspsi_stats解析 PSI 文件cpu.pressure/memory.pressure/io.pressure读取some与full两行并解析avg10、avg60、avg300字段crates/libcgroups/src/stats.rs。这些解析函数在 crates/libcgroups/src/stats.rs 中有完整的单元测试覆盖包括有效值、非法值、扁平/嵌套格式互相误用的边界场景可作为理解格式约定的直接参考。systemd 模块systemd 托管模式下的管理器当容器配置了 systemd cgroup 且系统以 systemd 启动时youki 通过 systemd 模块 与 systemd 交互来管理 cgroup。booted探测booted()通过检查/run/systemd/system是否为目录来判断系统是否由 systemd 启动crates/libcgroups/src/systemd/mod.rs。系统未以 systemd 启动时工厂函数create_systemd_cgroup_manager会直接返回SystemdNotAvailable错误见 crates/libcgroups/src/common.rs。controller_type可用的控制器枚举controller_type子模块提供ControllerType枚举用于表示系统上可用的 cgroup 控制器systemd 管理器在应用资源限制时会据此匹配到具体的控制器实现cpu、cpuset、memory、pids、io、unified 等。managersystemd 的 cgroup 管理器Manager结构体定义于 crates/libcgroups/src/systemd/manager.rs是 systemd 模式下的核心管理器字段包括root_pathcgroup 层级根路径如/sys/fs/cgroupcgroups_path相对根路径的 cgroup 路径rootful 容器形如/system.slice/youki-id.scoperootless 容器形如/user.slice/user-1000/user1000.service/youki-id.scopefull_path根路径与 cgroup 路径拼接后的完整路径destructured_path: CgroupsPath按 OCI runtime spec 中[slice]:[prefix]:[name]形式如system.slice:youki:id拆解出的 cgroup 路径。CgroupsPath::try_from解析逻辑见 crates/libcgroups/src/systemd/manager.rs冒号分隔两段时 parent 为空、三段时完整解析其他情况视为格式错误container_name/sub_cgroup/unit_name容器名、子 cgroup 名与 systemd unit 名如youki-id.scopeclient: DbusConnection与 systemd 通信的 DBus 连接fs_manager: FsManager对应 transient unit 的文件系统 cgroup 管理器复用 v2 的Managerdelegation_boundary由 systemd 管理的最后一个 cgrouprootless 场景下的委派边界cgroup_wait_timeout_duration等待指定 PID 进入 cgroup 的超时时间常量PROCESS_IN_CGROUP_TIMEOUT_DURATION为 5 秒见 crates/libcgroups/src/systemd/manager.rs。该Manager同样实现了CgroupManagertrait因此可用于标准 cgroup 操作。DBus 连接支持重连常量CONNECT_MAX_RETRIES 7、基础退避CONNECT_BASE_DELAY_MS 100并带约 12.5% 的抖动见 crates/libcgroups/src/systemd/manager.rs。dbus_nativerootless 模式的 DBus 实现dbus_native子模块是 DBus 连接的原生native实现不依赖外部dbus库而是自己实现消息序列化、代理与客户端对应 crates/libcgroups/src/systemd/dbus_native 下的client.rs、dbus.rs、message.rs、proxy.rs、serialize.rs、utils.rs。它主要用于 rootless 模式下与 systemd 通信工厂函数会根据is_true_root()检查geteuid是否 root 且/proc/self/uid_map中是否包含 4294967295 即 65534 的 uid 映射决定使用 system bus 还是 user bus见 crates/libcgroups/src/common.rs 与 crates/libcgroups/src/common.rs。另外systemd模块还导出了一个recast!宏crates/libcgroups/src/systemd/mod.rs用于把一个已序列化的值按指定类型重新反序列化属于内部工具性质。test_manager 模块测试用假管理器test_manager模块提供TestManager结构体crates/libcgroups/src/test_manager.rs同样实现了CgroupManager但错误类型为Infallible不可能失败。它专供 cgroup 相关的单元测试使用行为如下add_task把传入的 PID 记录到内部RefCellVecPid可通过get_add_task_args()取出断言apply仅把apply_called标记置为true由于ControllerOpt携带生命周期无法存储参数本身源码注释有明确说明可通过apply_called()查询remove、freeze、stats、get_all_pids均unimplemented!()即只有被测试代码真正调用的方法才需要实现。这种记录调用、不真正操作 cgroup的设计让测试可以在不接触真实 cgroup 文件系统的前提下验证上层逻辑例如 libcontainer 是否正确调用了管理器的add_task与apply。v1 与 v2 模块两种 cgroup 版本的分治实现v1 与 v2 两个模块分别承载 cgroups v1 与 v2 的专属功能各自暴露对应的管理器并提供版本相关的工具函数get_mount_pointsv1 与 v2 都有、get_subsystem_mount_pointsv1 专属、get_available_controllersv2 专属。v1 管理器多子系统并行挂载cgroups v1 的特点是每个子系统subsystem独立挂载因此 v1 管理器 内部用subsystems: HashMapCtrlType, PathBuf保存子系统类型 → 挂载点路径的映射。Manager::new会遍历全部CONTROLLERS对每个子系统调用get_subsystem_path通过util::get_subsystem_mount_point找到挂载点再从/proc/self/cgroup经 pathrs 打开中查找包含该控制器的条目拼接出子系统路径系统不支持的子系统仅记录 warning 而不报错crates/libcgroups/src/v1/manager.rs。v1 支持非常完整的控制器清单从 crates/libcgroups/src/v1/manager.rs 可见包括Cpu、CpuAcct、CpuSet、Devices、HugeTlb、Memory、Pids、PerfEvent、Blkio、NetworkPriority、NetworkClassifier、Freezer。apply时先通过get_required_controllers依据ControllerOpt判断哪些控制器真正需要处理若某控制器在系统上不可用则返回CGroupRequired错误crates/libcgroups/src/v1/manager.rs。add_task则是遍历所有可用子系统把 PID 写入每个子系统的cgroup.procscrates/libcgroups/src/v1/manager.rs。v2 管理器统一层级上的完整生命周期cgroups v2 只有一个统一层级v2 管理器 的结构更简洁Manager { root_path, cgroup_path, full_path, rootless }表示管理位于{root_path}/{cgroup_path}的 cgroup且不持有该 cgroup 的所有权见 crates/libcgroups/src/v2/manager.rs。add_task的完整流程体现了 v2 的操作模式crates/libcgroups/src/v2/manager.rs若full_path已存在直接attach_pid写入cgroup.procs否则调用create_unified_cgroupcrates/libcgroups/src/v2/manager.rs先通过get_available_controllers读取{root}/cgroup.controllers拿到可用控制器将其以controller形式写入cgroup.subtree_control启用best-effort失败仅记录日志随后沿cgroup_path逐级创建目录权限设为 0o755除最后一级外的每一级都启用子树控制器——因为若最后一级也启用subtree_control会触发内部进程约束internal process constraint导致后续写cgroup.procs时报 EBUSY对应注释见 crates/libcgroups/src/v2/manager.rs最后把 PID 写入cgroup.procs。在 rootless 模式下目录创建与 PID 写入遇到的EROFS/EACCES错误都会被降级处理记录 debug 日志后返回Ok让进程留在父 cgroup 中对应is_permission_error与两处降级分支见 crates/libcgroups/src/v2/manager.rs、crates/libcgroups/src/v2/manager.rs、crates/libcgroups/src/v2/manager.rs。apply遍历CONTROLLER_TYPEScpu、cpuset、hugetlb、io、memory、pids逐一应用限制启用cgroupsv2_devicesfeature 时还会额外调用Devices::apply处理设备限制最后通过Unified::apply处理 OCI spec 中unified字段指定的任意cgroup.*键值对crates/libcgroups/src/v2/manager.rs。remove时若存在cgroup.kill文件则写入1一次性杀掉全部进程否则遍历cgroup.procs逐个发SIGKILL最后用delete_with_retry带重试删除目录crates/libcgroups/src/v2/manager.rs。v2 的工具函数集中在 crates/libcgroups/src/v2/util.rsget_unified_mount_point解析/proc/self/mountinfo找出fs_type cgroup2的挂载点crates/libcgroups/src/v2/util.rsget_available_controllers读取{root_path}/cgroup.controllers把cpu、cpuset、hugetlb、io、memory、pids映射为ControllerType未知控制器仅告警crates/libcgroups/src/v2/util.rs。v2 devices 子模块基于 BPF 的设备控制器v2 模块还包含devices子模块crates/libcgroups/src/v2/devices/mod.rs它基于eBPF实现 cgroup v2 的设备访问控制因为 v2 不再有 v1 那样的devices.allow伪文件必须用BPF_PROG_TYPE_CGROUP_DEVICE程序挂载到 cgroup 上。该子模块由bpf、controller、emulator、program组成并通过pub use controller::Devices对外暴露Devices控制器。核心能力在 crates/libcgroups/src/v2/devices/bpf.rsload(license, insns)通过libbpf_sys::bpf_prog_load加载 cgroup device 类型的 BPF 程序类型BPF_PROG_TYPE_CGROUP_DEVICE加载前会尝试提升RLIMIT_MEMLOCKquery(cgroup_fd)通过bpf_prog_query查询某 cgroup 上已挂载的 BPF 程序返回ProgramInfo { id, fd }列表类型BPF_CGROUP_DEVICE支持BPF_F_ALLOW_MULTI多程序模式还提供 attach挂载到 cgroup与 detach卸载操作。program子模块负责 BPF 指令bpf_insn的构造emulator则用于在加载前模拟执行 BPF 程序以验证其行为。整个设备控制器的代码路径仅在cgroupsv2_devicesfeature 下编译。版本与 feature 矩阵如何裁剪 libcgroupslibcgroups 的构建行为完全由 feature 控制在 crates/libcgroups/Cargo.toml 中定义如下Feature说明default [v1, v2, systemd]默认同时启用 v1、v2、systemd 三种管理器v1启用 cgroups v1 支持未启用时使用stub/v1占位v2启用 cgroups v2 支持未启用时使用stub/v2占位systemd启用 systemd 托管支持依赖v2、nix/socket、nix/uiocgroupsv2_devices启用 v2 的 BPF 设备控制器依赖rbpf、libbpf-sys、errno、libc、nix/dir编译期裁剪是 stub 模块存在的意义以 crates/libcgroups/src/lib.rs 中#[cfg(feature systemd)]为例启用时编译真实的 systemd 模块未启用时则编译 crates/libcgroups/src/stub/systemd/mod.rs 占位实现create_systemd_cgroup_manager也会退化为返回NotEnabled错误见 crates/libcgroups/src/common.rs从而在静态链接等对体积敏感的场景下剔除不需要的代码。在自己项目中使用 libcgroupsyouki 官方文档明确说明工作区中的各子 crate 可以独立作为第三方依赖使用详见 docs/src/user/crates.md 与 docs/src/user/basic_usage.md。要在自己的 Rust 项目中引入 libcgroups只需在Cargo.toml中加入[dependencies] libcgroups { path path/to/youki/crates/libcgroups }更常见的做法是直接依赖发布到 crates.io 的版本如需全部功能可使用默认 features。拿到依赖后典型的使用方式如下use std::path::Path; use libcgroups::common::{ CgroupConfig, CgroupManager, create_cgroup_manager_with_root, }; use nix::unistd::Pid; // 1. 探测系统 cgroup 布局并创建对应的管理器 let config CgroupConfig { cgroup_path: my-cgroup.into(), systemd_cgroup: false, container_name: my-container.into(), }; let manager create_cgroup_manager_with_root(Some(Path::new(/sys/fs/cgroup)), config)?; // 2. 把当前进程加入该 cgroup manager.add_task(Pid::this())?; // 3. 应用资源限制resources 来自 OCI spec 的 LinuxResources // manager.apply(controller_opt)?; // 4. 获取统计信息 let stats manager.stats()?; println!(cpu usage: {}, stats.cpu.usage.usage_total); // 5. 获取 cgroup 内所有 PID let pids manager.get_all_pids()?;如果你只想做纯 cgroup 文件读写也可以绕过管理器直接使用 common 层use libcgroups::common::{read_cgroup_file, write_cgroup_file}; use libcgroups::stats::{parse_single_value, supported_page_sizes}; let path /sys/fs/cgroup/memory.current; let value parse_single_value(Path::new(path))?; // 读取单值文件 let sizes supported_page_sizes()?; // 查询系统支持的巨页尺寸与 youki 主程序的协作关系libcgroups 的定位是纯底层库youki 主程序youki与 libcontainerlibcontainer在容器生命周期中通过它完成资源管理创建容器时调用create_cgroup_manager获得管理器进程 fork 后add_task把容器进程放入 cgroup解析 OCI spec 的linux.resources后构造ControllerOpt调用apply暂停/恢复容器时通过freeze驱动 freezer查询资源时调用stats。从仓库目录结构看对应的集成测试覆盖了 cgroup 各维度的端到端行为例如 tests/contest/src/tests/cgroups含 cpu 的 v2 测试、memory、pids 等、tests/contest/src/tests/updatecpu/cpuset/pids_limit/blkio 的动态更新测试以及 tests/contest/src/tests/devices 的设备限制测试均可作为理解 libcgroups 实际用法的补充样例。小结libcgroups 通过common 通用抽象 v1/v2/systemd 版本分治 stats 数据模型的三层设计把 Linux cgroups 的复杂细节收敛为一个统一接口。核心要点回顾CgroupManagertrait 定义六种标准操作AnyCgroupManager枚举让上层代码无需关心具体版本get_cgroup_setup系列函数基于文件系统类型探测 Unified/Legacy/Hybrid 布局create_cgroup_manager系列工厂按布局自动选型v1 按子系统多挂载点管理v2 在统一层级上完成启用控制器 → 建目录 → 写 procs的完整流程并支持 rootless 降级systemd 管理器通过 DBusrootless 场景用原生dbus_native实现创建 transient unit 并托管 cgroupStats及配套解析函数覆盖 CPU、内存、PID、块 I/O、HugeTLB 与 PSI 等维度可直接序列化为 JSON 输出。对于想要深入容器资源管理实现的开发者直接从 crates/libcgroups/src/common.rs 与 crates/libcgroups/src/stats.rs 开始阅读是最快的路径而 crates/libcgroups/src/v2/manager.rs 与 crates/libcgroups/src/v1/manager.rs 则分别展示了两种 cgroup 版本管理器的完整实现细节。赞分享容器运行时云原生【免费下载链接】youkiA container runtime written in Rust项目地址https://gitcode.com/gh_mirrors/yo/youki点击查看免费下载相关推荐Rust 模块系统实战基于 rust-by-practice 的 crate-module 模块练习全解析Rust 模块系统实战基于 rust by practice 的 crate module 模块练习全解析 本文档以 rust by practice 仓库文档教程示例工程LiteLLM Rust 工作区深度解析四 Crate 架构、messages() 调用链与 Python 互操作设计LiteLLM Rust 工作区深度解析四 Crate 架构、messages 调用链与 Python 互操作设计 LiteLLM 的 Rust 实现以 li后端API网关LLM 网关大模型人工智能rCore基于Rust的开源操作系统项目rCore基于Rust的开源操作系统项目 rCore 是一个用 Rust 语言编写的开源操作系统项目。该项目旨在打造一个兼容 Linux 的简单、高效的操作系上一篇SpacetimeDB 实时聊天应用 AI 基准评测GPT 5.2 一次生成 24/24 满分的 8 大实时功能深度解析下一篇深入解读 OpenTelemetry Go Logs SDK 实验特性通过 OTEL_GO_X_OBSERVABILITY 开启 SDK 自身可观测性创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表