Kubernetes按需容器部署:低频次Java应用内存优化方案咨询
问题解答与方案建议
问题1:Kubernetes是否存在可降低内存占用的内置解决方案?
Kubernetes本身没有内置全链路的「请求到达自动启动、超时自动休眠容器」能力,但有几个原生特性可以组合使用降低闲置内存消耗:
- 基础资源配置:给低频应用设置远低于实际运行峰值的
requests.memory,利用K8s的调度超售机制减少节点预留内存的浪费,只要控制好超售比例,就不会影响正常运行的业务 - HPA缩零能力:K8s 1.23及以上版本开启
HPAScaleToZero特性门控后,可以配置HPA基于请求QPS指标自动扩缩容,当应用长时间没有请求时自动把副本数缩到0,有请求时再自动扩容,和你提到的第一类方案逻辑基本一致 - cgroup级容器冻结:Kubelet底层基于cgroup支持暂停容器的所有进程,冻结后几乎不占内存,但没有原生的自动触发逻辑,需要自行开发控制器实现超时冻结、请求到达解冻的逻辑
问题2:提出的第3类方案是否为合理的可行方案?
是非常成熟可行的落地方案,尤其适合内部使用的低频应用场景,优势非常突出:
- 实现成本极低:不需要修改K8s底层配置,也不需要改造任何业务应用,只需要做一个简单的内部应用导航页,后台调用K8s APIServer执行
kubectl scale之类的指令调整副本数即可,开发量很小 - 逻辑稳定可控:用户主动选择启动应用的逻辑没有歧义,不会出现误判请求导致的错误启动,也可以很方便的叠加权限校验、启动状态提示、超时自动缩容等配套功能
- 兼容性强:不管你的Java应用是用什么框架开发的,都可以适配这套逻辑,不需要做任何业务改造
唯一需要注意的是要提前给用户做好提示,Java应用冷启动一般需要几秒到几十秒不等,启动过程中设置加载提示页,避免用户误以为访问失败。
额外优化方案推荐
处理过同类内部低频应用场景,除了你提到的三类方案之外,还有几个可选项可以参考:
- 冷启动优化:如果选第三套方案,可以给Java应用开启AppCDS(应用类数据共享)、或者用GraalVM编译原生镜像,能把冷启动耗时压缩到几百毫秒到几秒级别,基本感知不到等待
- Knative Serving简化实现:如果不想自己开发导航页和触发逻辑,可以直接用Knative Serving组件,它原生支持请求驱动的自动扩缩容,支持缩到0,只要应用是标准HTTP服务就能直接对接,不需要额外开发
- 状态保留方案:如果不想接受冷启动耗时,可以用CRIU(用户态检查点恢复工具)把运行中的容器状态快照存到磁盘,需要的时候几秒钟就能恢复运行状态,现在containerd等CRI运行时已经原生支持这个功能,不过需要提前测试Java应用的兼容性
- 调度层优化:把所有低频应用统一调度到专门的超售节点上,和核心业务节点物理隔离,就算超售导致节点资源不足也不会影响核心业务运行
内容的提问来源于stack exchange,提问作者Mirko
相关产品推荐
相关产品推荐

