- 云原生
- 虚拟化
- 存储
- 后端
- 高可用
【免费下载链接】harvester
Open source hyperconverged infrastructure (HCI) software
导读
本文以 Harvester 开源仓库中的增强设计文档 enhancements/20220823-node-manager-support-ksm.md 为核心,系统讲解 Harvester 如何在节点上启用内核同页合并(Kernel Samepage Merging,KSM)以降低集群内存占用,并给出完整的 Ksmtuned 控制器设计方案——包括三种运行模式(stop/run/prune)、三种配置模式(standard/high/customized)、Ksmtuned 自定义资源(CR)的完整 YAML 示例、各参数语义、控制器行为与可落地的测试计划。读完本文,你将掌握:KSM 在 Harvester 中的整体架构、如何通过 UI/API 替代逐节点命令行配置、thresCoef等关键参数如何影响 ksmd 的扫描与合并行为,以及如何验证 KSM 是否按预期运行。
一、背景与动机:为什么 Harvester 需要 KSM
KSM(Kernel Samepage Merging)是 Linux 内核提供的内存去重机制,它允许内核将内容相同的物理内存页合并为共享页,从而显著降低运行大量相似工作负载(例如多个运行相同操作系统镜像的虚拟机)时的内存消耗。在 Harvester 这类超融合基础设施(HCI)中,节点上往往同时运行多个 KVM 虚拟机,内存是稀缺资源,启用 KSM 可以有效提升内存使用效率。
该增强方案的核心目标(Goals)包括:
- 配置方式现代化:从 UI 或 API 配置 Ksmtuned,替代登录每台节点使用命令行手工配置的运维方式,降低操作复杂度和安全风险;
- 可观测性:监控节点 ksmd 进程的 CPU 利用率,暴露给 Prometheus 抓取;
- 工程化落地:将 Ksmtuned 脚本转换为 Go 程序并补充单元测试,计划直接集成进 Harvester 的 ISO 发布物中。
方案原计划在 GA 版本 1.1.0 中首次交付,API 层面不引入额外变更。当前仓库中与 KSM 相关的 KubeVirt 侧能力也已存在:在 pkg/apis/harvesterhci.io/v1beta1/openapi_generated.go 中可以看到 KubeVirt 的KSMConfiguration定义,其nodeLabelSelector字段用于按节点标签过滤启用 KSM 的节点;同时 pkg/controller/master/node/condition_annotations_test.go 中出现了kubevirt.io/ksm-enabled、kubevirt.io/ksm-handler-managed注解,说明节点侧 KSM 状态会通过节点注解暴露。本方案则是在此基础上,把节点 KSM 参数的调优与管理能力以 Ksmtuned 控制器的形式沉淀为声明式配置。
二、总体设计:DaemonSet + Ksmtuned CR 的双层架构
2.1 实现总览
方案的核心是部署一个Ksmtuned controller(控制器)来管理 Harvester 各节点的 KSM 配置。其实现要点:
- 使用DaemonSet在每个节点上运行,每个节点只获取与自身相关的配置信息,天然实现"一节点一配置"的隔离;
- 控制器按配置写入 KSM 的 sysfs 接口文件(
/sys/kernel/mm/ksm/下的run、pages_to_scan等),并定时读取节点的内存使用情况; - 根据阈值计算结果启动或停止 ksmd 程序,实现"内存充足时让出 CPU、内存紧张时才合并"的自适应行为。
这种设计把原先需要运维人员逐台登录节点执行的脚本化操作,抽象为 Kubernetes 原生的声明式资源管理,与 Harvester 的"以 API/UI 管理集群"理念一致。
2.2 Ksmtuned 自定义资源(CR)
Ksmtuned CR 的 API 分组为node.harvesterhci.io/v1beta1,kind 为Ksmtuned,一个 CR 对应一个节点的 KSM 管理配置,CR 与 Node 通过ownerReferences建立归属关系。当spec.mode为standard(标准)或high(高性能)模式时,spec.ksmtunedParameters展示对应的配置参数。一个典型的 CR 如下:
apiVersion: node.harvesterhci.io/v1beta1 kind: Ksmtuned metadata: name: node1 ownerReferences: - apiVersion: v1 kind: Node name: node1 spec: ksmtunedParameters: boost: 0 decay: 0 maxPages: 100 minPages: 100 sleepMsec: 20 mergeAcrossNodes: 0 mode: standard/high/customized run: stop/run/prune thresCoef: 20 status: fullScans: 17 ksmdPhase: Stopped/Running/Pruned shared: 171264 sharing: 1368772 stableNodeChains: 12 stableNodeDups: 538 unshared: 545943 volatile: 10909其中status字段直接反映内核 KSM 的运行状态与统计信息(fullScans、shared、sharing、stableNodeChains、stableNodeDups、unshared、volatile),以及当前 ksmd 的阶段(ksmdPhase:Stopped/Running/Pruned),让管理员无需进入节点即可掌握 KSM 的实时合并效果。
三、三种运行模式与三种配置模式
3.1 运行模式(spec.run)
用户故事中明确了三种运行选项,覆盖 KSM 生命周期的管理:
| 运行模式 | 行为 | 适用场景 |
|---|---|---|
| stop | 停止 Ksmtuned 与 KSM,但已存在的共享内存页继续保留 | 临时关闭合并,避免影响 VM 内存访问性能 |
| run | 运行 Ksmtuned,按配置驱动 KSM 工作 | 日常默认运行态 |
| prune | 停止 Ksmtuned 并清理(prune)KSM 共享内存页 | 需要彻底回收共享页、恢复独立内存布局时 |
需要特别说明:当spec.run为stop时,只是"挂起"ksmtuned,虚拟机仍可继续使用已有的共享内存页,因此不会引发 VM 内存内容丢失;只有prune才会真正清理共享页(见下文示例中的 status 归零)。
3.2 配置模式(spec.mode)
方案提供三种配置模式,决定 ksmd 对 CPU 资源的占用策略与扫描合并效率:
Standard(标准模式,默认):控制节点的 ksmd 大约占用单个 CPU 的 20%,参数如下:
boost: 0 decay: 0 minPages: 100 maxPages: 100 sleepMsec: 20由于boost与decay均为 0,每次扫描的页数恒定在 100 页,CPU 占用平稳可控,适合默认部署场景。
High Performance(高性能模式):节点 ksmd 占用单个 CPU 的 20%~100%,扫描与合并效率更高,参数如下:
boost: 200 decay: 50 minPages: 100 maxPages: 10000 sleepMsec: 20该模式下boost与decay非零,扫描页数会随内存压力动态在 100~10000 页之间调整,内存越紧张扫描越激进,从而更快完成合并。
Customized(自定义模式):完全由用户自定义参数,以达成期望的性能与 CPU 占用平衡。当spec.mode为customized时,必须自行配置spec.ksmtunedParameters。
四、Ksmtuned 参数语义详解
Ksmtuned.spec中的每个参数都直接影响内核 KSM 的行为,理解其语义是调优的关键:
- run:
stop/run/prune,停止/运行 Ksmtuned 或清理共享页; - mode:
standard/high/customized,三种配置模式; - thresCoef:空闲内存阈值(百分比)。当可用内存低于设定百分比时 KSM 启动,否则停止。这是 KSM 自适应的核心开关;
- mergeAcrossNodes:指定是否允许合并来自不同 NUMA 节点的内存页(0 为不允许,1 为允许),对多路服务器上的跨 NUMA 合并行为有直接影响;
- ksmtunedParameters.boost:当可用内存低于阈值时,每次扫描页数的增量,用于"增压"加速合并;
- ksmtunedParameters.decay:当可用内存高于阈值时,每次扫描页数的减量,用于"减压"让出 CPU;
- ksmtunedParameters.maxPages:每次扫描的最大页数上限;
- ksmtunedParameters.minPages:每次扫描的最小页数,即首次运行的初始配置值;
- ksmtunedParameters.sleepMsec:每次调整配置的时间间隔基准,两次扫描的实际间隔由公式
sleepMsec * 16 * 1024 * 1024 / total memory计算得出(单位毫秒),即根据节点总内存动态换算扫描间隔。
设计文档中特别指出:由于 KSM 运行在单一模式下,大内存设备可能长时间占用 CPU。为解决此问题,ksmtuned 脚本通过阈值机制(thresCoef)让 KSM 仅在空闲内存低于一定百分比时运行,从而在内存充裕时避免无谓的 CPU 消耗——这正是thresCoef与boost/decay配合实现的自适应调节链路。
五、各运行状态的 CR 配置实例
5.1 自动创建的标准模式 CR
Ksmtuned 控制器会检查节点的 Ksmtuned CR 是否存在;若不存在,则自动为该节点创建一个mode 为 standard、thresCoef 为 20、状态为 stop的 CR(默认配置,避免新节点因启用 KSM 引入意外开销)。对应 CR 形态:
spec: run: run mode: customized thresCoef: 20 ksmtuneddParameters: boost: 300 decay: 50 maxPages: 2000 minPages: 100 sleepMsec: 20(注:上面展示的是自定义模式示例,即mode: customized时需要显式给出全部ksmtunedParameters,此处boost: 300、maxPages: 2000演示了比标准模式更激进的合并策略。)
5.2 run=stop:挂起 KSM、保留共享页
apiVersion: harvesterhci.io/v1beta1 kind: Ksmtuned metadata: name: harvester-master spec: ksmtunedParameters: boost: 0 decay: 0 maxPages: 100 minPages: 100 sleepMsec: 20 mergeAcrossNodes: 0 mode: standard run: stop thresCoef: 20 status: sharing: 17299179 shared: 312514 unshared: 2334736 volatile: 65571 fullScans: 14102 stableNodeChains: 30 stableNodeDups: 56249 ksmdPhase: Stopped可以看到run: stop后,ksmdPhase变为Stopped,但sharing(共享节省的内存)仍保留在 17299179,证明已合并的页面未被破坏。
5.3 run=prune:停止并清理共享页
apiVersion: harvesterhci.io/v1beta1 kind: Ksmtuned metadata: name: harvester-master spec: ksmtunedParameters: boost: 0 decay: 0 maxPages: 100 minPages: 100 sleepMsec: 20 mergeAcrossNodes: 0 mode: standard run: prune thresCoef: 20 status: sharing: 0 shared: 0 unshared: 0 volatile: 0 fullScans: 0 stableNodeChains: 0 stableNodeDups: 0 ksmdPhase: Prunedrun: prune后所有合并统计全部归零,ksmdPhase为Pruned,表明共享内存页已被彻底清理,系统回到未合并的初始状态。
5.4 通过 status 观测 KSM 内核指标
Ksmtuned CR 的status用于展示内核 KSM daemon 的 sysfs 指标与 ksmd 阶段。控制器会持续将以下内核统计同步进 CR:
apiVersion: harvesterhci.io/v1beta1 kind: Ksmtuned metadata: name: harvester-master spec: ... status: sharing: 17299179 shared: 312514 unshared: 2334736 volatile: 65571 fullScans: 14102 stableNodeChains: 30 stableNodeDups: 56249 ksmdPhase: Stopped/Running/Pruned这些字段与/sys/kernel/mm/ksm/下同名指标一一对应:sharing为共享页节省的字节数、shared为共享页数、fullScans为完成的扫描次数、stableNodeDups/stableNodeChains为稳定树的去重计数、volatile为易变页数、unshared为取消共享的页数。将内核状态提升为 CR 的 status,使得 Grafana/Prometheus 与 UI 可以统一从 API 读取,无需再进入节点查看/sys文件。
六、控制器行为设计
6.1 Node Controller(节点控制器)
- 自动创建:同步 Node 时,若该节点的 Ksmtuned CR 不存在,则自动为其创建,默认mode 为 standard、thresCoef 为 20、run 状态为 stop;
- 随节点清理:Node 被删除时,同步删除该节点的 Ksmtuned CR,避免残留配置造成状态漂移。
6.2 Ksmtuned Controller(Ksmtuned 控制器)
- 配置驱动运行:Ksmtuned CR 被创建/更新时,运行状态适配预定义(standard/high)或自定义(customized)配置;否则停止运行程序;
- 删除即终止:Ksmtuned CR 被删除时,终止对应的 ksmtuned 程序,确保声明式配置与实际进程状态一致。
6.3 监控指标(Metrics)
- 暴露ksmd 程序的 CPU 利用率指标,供 Prometheus 抓取;对应设计文档中的目标"Monitor node ksmd CPU utilization",并关联到 Harvester 的监控看板(见下节 UI 体验)。
七、用户体验:UI 展示与配置入口
在 UI 层面,方案规划了两处入口:
- 节点级配置:KSM 配置将在Hosts → info/edit → KSM页面展示与配置。管理员无需登录节点执行命令行,即可针对每个节点选择运行模式(stop/run/prune)与配置模式(standard/high/customized),并直接编辑
thresCoef、boost、decay等参数; - 集群级观测:在 Dashboard 页面的Cluster Metrics(集群指标)中增加ksmd 利用率 Top10图表,直观展示各节点 ksmd 的 CPU 占用排名,配合第 6.3 节的 Prometheus 指标形成"配置—运行—观测"闭环。
八、测试计划:如何验证 KSM 按预期运行
设计文档给出了可直接落地的验证方法,核心思路是利用/sys/kernel/mm/ksm/run与pages_to_scan两个内核接口观察 KSM 行为:
- 验证 thresCoef 阈值逻辑:设置
thresCoef: 20后,当可用内存总量低于 总内存 × 0.2 时,执行cat /sys/kernel/mm/ksm/run应输出1(KSM 开启);反之(内存充足)应输出0(KSM 关闭); - 观察扫描页数动态变化:使用
watch -n1 grep . /sys/kernel/mm/ksm/*持续观察pages_to_scan的变化,即可验证boost、decay、maxPages、minPages配置是否生效——内存紧张时pages_to_scan应随 boost 递增,内存充裕时应随 decay 递减,且不超出[minPages, maxPages]区间。
完整的测试步骤如下:
- 准备一台内存充足的节点,并预先创建大量虚拟机(制造可合并的内存页);
- 检查自动为该节点创建的 Ksmtuned CR(应默认 standard/thresCoef=20/stop);
- 按测试预期调整该节点 Ksmtuned 中
thresCoef的百分比; - 按测试预期调整
boost/decay/maxPages/minPages的值; - 检查 Ksmtuned CR 的
status,或登录系统(读取/sys/kernel/mm/ksm/*)观察实际运行情况,两者应相互印证。
九、升级策略与工程落地
设计文档明确该功能无独立的升级策略(Upgrade strategy: No),即它作为节点管理能力随 ISO 发行版整体交付,不需要额外的数据迁移或版本兼容处理。工程层面,方案要求把原本的 Ksmtuned 脚本改写成 Go 程序并补充单元测试,使其作为守护进程随 DaemonSet 在每节点运行——这既提升了程序健壮性,也使其能够复用 Harvester 现有的 clientset、controller-runtime 等基础设施。
值得说明的是:截至当前仓库快照,Ksmtuned CR 的 Go 类型尚未出现在 pkg/apis/harvesterhci.io/v1beta1 中(该目录目前包含 addon、backup、image、upgrade 等类型),也未见其 OpenAPI 定义进入 api/openapi-spec/swagger.json;与之相邻的 KubeVirt 侧 KSM 能力(KSMConfiguration.nodeLabelSelector)已存在于 openapi_generated.go。可以推断,本方案当前以设计文档形态沉淀在 enhancements/20220823-node-manager-support-ksm.md 中,具体 CRD 与控制器代码的落库位置可能位于配套的 node-manager 实现中。读者若要在自己的 Harvester 环境评估该能力,应以上述设计文档描述的 CR 结构与参数语义为准。
十、小结
Harvester 的 KSM 支持方案通过"DaemonSet 逐节点守护 + Ksmtuned CR 声明式配置 + 控制器自动编排 + Prometheus 可观测"四层设计,将 Linux 内核的 KSM 能力转化为 HCI 集群中可配置、可观测、可验证的运维资产:三种运行模式覆盖 KSM 的启停与清理,三种配置模式覆盖从保守到激进的 CPU/内存权衡,thresCoef阈值机制则确保 KSM 只在内存压力下才消耗 CPU。对大规模部署 Harvester 并希望压榨内存利用率的团队而言,这套方案是降低节点内存成本、提升虚拟机密度的一条现实路径。
- 云原生
- 虚拟化
- 存储
- 后端
- 高可用
【免费下载链接】harvester
Open source hyperconverged infrastructure (HCI) software
相关推荐
终极指南:深入理解os-tutorial内存去重与KSM合并机制
终极指南:深入理解os tutorial内存去重与KSM合并机制 内存管理是操作系统开发中的核心技术,而 内存去重 和 KSM合并机制 更是提升系统性能的关键。
示例工程Velero node-agent 并发控制设计:VGDP 并发实例的全局与按节点配额机制
Velero node agent 并发控制设计:VGDP 并发实例的全局与按节点配额机制 导读 本文围绕 Velero 仓库中 node agent 并发能力
云原生灾备存储后端Slicer 参数节点包装器支持类型全解析:从内置类型到 parameterPack 自定义聚合
Slicer 参数节点包装器支持类型全解析:从内置类型到 parameterPack 自定义聚合 导读 Slicer 的 parameterNodeWrappe
医疗健康图像处理数据可视化桌面应用3D渲染
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考