办公助手、代码执行服务等 Agent 工作负载,在等待用户输入、模型响应或外部工具结果时,可能仍保留较多暂时不访问的内存。为这些工作负载开启内存压缩,可以减少冷内存页占用,为同一节点上的其他任务留出空间。
本文以一组常驻办公 Agent 为例,介绍如何选择节点和工作负载、开启压缩、对比效果,并在需要时恢复原配置。先选择少量实例试用,观察完整的“执行任务—等待—再次执行”过程,再决定是否扩大范围。
适用场景
场景 | 使用建议 |
办公 Agent 长时间在线,请求之间有明显空闲期 | 优先选取少量实例,观察等待期间的内存节约量和再次响应的耗时。 |
代码执行环境加载依赖后,大量数据暂时不再访问 | 用真实项目运行验证,观察任务恢复执行时的延迟。 |
批量任务持续高强度访问内存 | 先评估 CPU 和内存压力;压缩收益可能较小。 |
对尾延迟敏感,或 CPU 已持续饱和 | 先做独立对照测试,避免直接全量启用。 |
内存压缩需要消耗 CPU,效果取决于内存内容和访问模式。它不会自动修改 Pod 的资源申请和限制,也不替代节点扩容、应用内存优化或工作区持久化。不要因为观察到一次内存下降,就立即调低所有实例的 memory request 或 limit。
开始前准备
本文使用 TKE 原生节点的 QoSAgent 能力。目标节点须为支持该能力的原生节点,QoSAgent 须为 1.1.5 或以上版本,所有业务容器均须设置 memory limit。节点镜像和内核要求请按 TKE 内存压缩使用说明 检查,不能只根据内核版本号较大判断兼容性。
准备好以下信息:
目标集群的 Kubernetes 访问配置,配置方式请参见 通过 Kubernetes API 访问 Agent 集群。
一组可用于小范围验证的 Agent 实例及其声明式部署配置。
一台满足条件的目标节点,以及修改组件、节点标签和 QoS 策略的权限。
业务基线:同等请求量下的内存、CPU、任务成功率和响应耗时。
确认当前连接的集群,再查看节点和工作负载。下文所有大写占位符都需要替换为实际值。
kubectl config current-contextkubectl get nodes -o widekubectl -n REPLACE_WITH_NAMESPACE get deployment REPLACE_WITH_DEPLOYMENT -o yamlkubectl -n REPLACE_WITH_NAMESPACE get pods -o wide
保存业务的原始部署配置,后续回退使用这份配置。不要修改生产服务的唯一实例来做第一次试验。
步骤一:开启组件能力
组件安装后,先查看集群中已有的策略,确认是否有其他业务正在使用:
kubectl get crd nodeqoss.ensurance.crane.io podqoss.ensurance.crane.iokubectl get nodeqoss.ensurance.crane.io -o yamlkubectl get podqoss.ensurance.crane.io -A -o yaml
下文使用
agc-memory-demo=enabled 作为本次验证的专用标签。若该标签已被其他策略使用,请换成未使用的标签,并同步修改所有示例。不要让多个相互冲突的策略选中同一节点或 Pod。步骤二:选择节点
QoSAgent 安装时会创建
compress-node 策略。先备份,再编辑其节点选择条件;如果已有业务使用该策略,应保留原有作用范围,先安排独立节点验证。不要直接覆盖已有策略。kubectl get nodeqoss.ensurance.crane.io compress-node -o yaml > compress-node.before.yamlkubectl edit nodeqoss.ensurance.crane.io compress-node
对于尚未服务其他业务的验证策略,将以下字段设为:
spec:selector:matchLabels:agc-memory-demo: enabledmemoryCompression:enable: true
给已确认满足条件的节点添加标签:
kubectl label node REPLACE_WITH_NODE agc-memory-demo=enabledkubectl get nodes -l agc-memory-demo=enabled -o widekubectl get node REPLACE_WITH_NODE -o jsonpath='{.metadata.annotations.gocrane\\.io/memory-compression}{"\\n"}'
节点注解用于检查策略处理结果。还应在节点上按官方使用说明检查 ZRAM 初始化状态;只有标签匹配,并不代表压缩已生效。
步骤三:选择 Agent 工作负载
先用下面的命令确认 PodQOS 的资源作用域和字段。若
NAMESPACED 为 true,应在业务命名空间中管理策略;否则使用集群级资源。不要把策略误建到无关命名空间。kubectl api-resources --api-group=ensurance.crane.iokubectl explain podqos.spec --api-version=ensurance.crane.io/v1alpha1
apiVersion: ensurance.crane.io/v1alpha1kind: PodQOSmetadata:name: agc-memory-demospec:labelSelector:matchLabels:agc-memory-demo: enabledresourceQOS:memoryQOS:memoryCompression:compressionLevel: 1enable: true
对于命名空间级资源,下列命令追加
-n REPLACE_WITH_NAMESPACE;集群级资源直接执行:kubectl apply --dry-run=server -f agc-memory-podqos.yamlkubectl apply -f agc-memory-podqos.yaml
在测试用 Deployment 的原有配置中,向 Pod 模板合并以下字段,保留原来的镜像、RuntimeClass、资源限制、存储、身份和其他调度约束。这只是合并片段,不是可单独创建的 Deployment:
spec:template:metadata:labels:agc-memory-demo: enabledspec:nodeSelector:agc-memory-demo: enabled
Pod 标签用来选择压缩对象,nodeSelector 用来让测试实例落到已开启能力的节点。二者都需要配置。若已有调度约束与测试节点冲突,先解决冲突,再更新工作负载。
将修改后的完整配置保存为
agent-memory-demo.yaml,提交并等待更新:kubectl apply --dry-run=server -f agent-memory-demo.yamlkubectl apply -f agent-memory-demo.yamlkubectl -n REPLACE_WITH_NAMESPACE rollout status deployment/REPLACE_WITH_DEPLOYMENT --timeout=180skubectl -n REPLACE_WITH_NAMESPACE get pods -l agc-memory-demo=enabled -o wide
更新 Pod 模板会触发实例替换。等待新实例就绪后,再继续发送测试请求。
步骤四:验证生效和业务收益
检查配置是否生效
选择一个新实例,检查其压缩注解和事件:
kubectl -n REPLACE_WITH_NAMESPACE get pod REPLACE_WITH_POD -o jsonpath='{.metadata.annotations.gocrane\\.io/memory-compression}{"\\n"}'kubectl -n REPLACE_WITH_NAMESPACE describe pod REPLACE_WITH_POD
确认 Pod 实际落在目标节点,再检查 QoSAgent 的处理结果。注解存在只是配置检查的一部分,实际节约量需要结合监控观察。
执行同一组 Agent 任务
1. 在未开启压缩的基线实例上,执行一组代表性任务,例如读取业务资料并整理摘要,记录成功率、响应时间、CPU 和内存。
2. 在启用压缩的实例上,用相同镜像、资源配置、输入和并发重复任务。
3. 让两组实例经历相同的等待时段,然后再次提交任务,重点比较从空闲恢复后的首次响应和任务完成时间。
4. 重复多个业务周期,同时覆盖繁忙时段。记录模型与外部工具耗时,避免把外部服务波动误认为压缩开销。
对比项 | 未开启压缩 | 开启压缩 | 判断方法 |
Pod 内存节约量 | 记录基线 | 记录压缩前后字节数之差 | 收益是否持续,是否来自目标实例 |
节点可用内存 | 同等负载记录 | 同等负载记录 | 是否增加实际可用空间 |
CPU 使用量 | 平均值及峰值 | 平均值及峰值 | 是否仍有处理请求的余量 |
空闲后的首次响应 | P50、P95 | P50、P95 | 是否满足业务目标 |
任务完成时间与成功率 | 按任务记录 | 按任务记录 | 是否出现慢任务或失败增加 |
OOM、重启及资源等待 | 按观察窗口记录 | 同时长记录 | 是否出现新的稳定性问题 |
QoSAgent 提供 Pod、节点的压缩及资源压力指标,可按 TKE 压缩监控 接入 Prometheus。重点观察内存节约量、CPU、PSI、缺页、OOM 和业务耗时。节点 ZRAM 的总使用量不能直接当成某个 Agent 的收益;
kubectl top 的单次结果也不能独立证明压缩有效。内存节约量按同一对象、同一时刻的“压缩前字节数减去压缩后字节数”计算。该值反映压缩数据的差额,不等于可以立即增开的实例容量。只有业务表现和资源余量都满足要求后,才逐步增加实例密度。
关闭压缩与恢复配置
发现响应变慢、CPU 压力升高或任务失败增加时,停止扩大范围,先减少测试并发,为内存恢复预留空间。
1. 编辑本次创建的
agc-memory-demo PodQOS,将 spec.resourceQOS.memoryQOS.memoryCompression.enable 改为 false,按原作用域应用,观察组件处理结果。2. 将测试 Deployment 恢复为试验前保存的声明式配置,移除本次新增的 Pod 标签和 nodeSelector,等待滚动更新及业务检查通过。保留原本已有的其他配置。
3. 确认不再有业务依赖本次测试策略后,删除本次创建的 PodQOS。命名空间级资源需带原命名空间参数。
kubectl delete podqoss.ensurance.crane.io agc-memory-demo
4. 若仅为本次测试修改过
compress-node,通过编辑恢复此前的选择条件和开关;不要删除组件自带策略。随后移除本次新增的节点标签:kubectl label node REPLACE_WITH_NODE agc-memory-demo-
5. 再次确认业务响应、节点内存和组件状态恢复正常。其他业务仍在使用 QoSAgent 时,保留组件及其配置。
不要在内存紧张时直接执行
swapoff 或卸载 ZRAM,也不要把删除策略等同于所有已压缩页面立即恢复。常见问题
现象 | 排查方法 |
找不到 NodeQOS 或 PodQOS | 检查 QoSAgent 安装、版本和 CRD 是否存在。 |
节点已打标签,业务仍无压缩信息 | 检查节点兼容性、组件开关、两个策略的选择器、Pod 实际节点及所有容器的 memory limit。 |
工作负载更新后 Pending | 查看 Pod 事件,检查节点标签、可分配资源、污点及已有亲和性约束。 |
注解已有,但节约量不明显 | 检查监控采集、观察时长和真实冷内存量;持续访问的热数据通常不适合靠压缩减少占用。 |
内存下降但响应变慢 | 对比 CPU、PSI 和任务恢复延迟,先关闭测试对象的压缩,再评估是否继续使用。 |
Cube 沙箱无法验证生效 | 保留原 RuntimeClass,核对运行时兼容性及沙箱对应的内存统计,不能仅凭节点 ZRAM 有数据下结论。 |