AKS项目中Defender Pods因cgroup v2变更导致内存指标读取失败问题分析
AKS Azure Kubernetes Service 项目地址: https://gitcode.com/gh_mirrors/ak/AKS
问题背景
在Azure Kubernetes Service(AKS)环境中,当集群从Kubernetes 1.27版本升级到1.30版本后,Microsoft Defender相关的Pod组件出现了内存指标读取失败的问题。具体表现为Defender Collector和Publisher两个DaemonSet组件持续输出错误日志,无法正确获取容器的内存使用情况。
问题现象
Defender Collector组件日志中频繁出现以下错误信息:
Failed to get max memory usage with error: open /sys/fs/cgroup/memory.peak: no such file or directory
Failed to get memory usage with error: open /sys/fs/cgroup/memory.current: no such file or directory
同时Defender Publisher组件也报告了类似的错误:
Failed to get max memory usage with error: open /sys/fs/cgroup/memory.peak: no such file or directory
根本原因分析
这个问题源于Kubernetes 1.30版本默认启用了cgroup v2作为其控制组实现。与cgroup v1相比,v2版本在内存统计接口上做了重大变更:
- 文件路径变化:cgroup v1使用
memory.stat
等文件,而v2使用memory.current
和memory.peak
等新文件 - 统计方式变化:v2版本采用了更统一和简化的统计接口
- 层次结构变化:v2采用了单一层次结构,不同于v1的多层次结构
Defender组件的原始代码实现是基于cgroup v1的接口规范编写的,当集群升级到Kubernetes 1.30后,由于cgroup v2的启用,原有的内存统计文件路径不再存在,导致组件无法正确读取内存使用指标。
影响范围
该问题主要影响以下环境配置:
- 运行Kubernetes 1.30及以上版本的AKS集群
- 使用AKSUbuntu-2204gen2containerd节点镜像
- 内核版本为5.15.0-1073-azure
- Defender Collector版本1.0.110和Publisher版本1.0.148
解决方案
Microsoft Defender团队已经发布了修复版本,主要改进包括:
- 增加了对cgroup v2接口的支持
- 实现了自动检测cgroup版本的功能
- 根据检测到的cgroup版本选择正确的统计文件路径
- 统一了内存统计数据的获取方式
用户只需将Defender组件升级到最新版本即可解决此问题。从问题报告者的反馈来看,更新后的版本已经能够正常工作。
技术启示
这个案例为我们提供了几个重要的技术启示:
- 容器运行时兼容性:在Kubernetes升级过程中,不仅要关注API版本变化,还需要注意底层运行时环境的变化
- cgroup版本迁移:从v1到v2的过渡需要应用程序做出相应调整,特别是在资源统计和限制方面
- 监控组件适配:安全监控类组件通常需要直接与底层系统交互,对系统变更更为敏感
- 向后兼容设计:关键系统组件应当考虑同时支持新旧版本接口,确保平滑过渡
最佳实践建议
对于需要在Kubernetes环境中部署类似监控/安全组件的开发者,建议:
- 在组件中实现cgroup版本自动检测功能
- 同时支持v1和v2两种接口规范
- 增加版本兼容性测试环节
- 密切跟踪Kubernetes发行说明中的重大变更
- 建立完善的错误处理和回退机制
通过这个案例,我们可以看到Kubernetes生态系统的持续演进对周边工具链带来的影响,也体现了云原生技术栈中各组件间紧密的耦合关系。
AKS Azure Kubernetes Service 项目地址: https://gitcode.com/gh_mirrors/ak/AKS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考