无感知导致的问题
当咱们在K8s中Deployments配置资源限度和预留的时候,比方设置最大内存为500M。然而宿主机的总内存为8G,这时候Pod启动后会超出内存限度,被Deployments杀掉。但为了保护设置的正本数量又创立新的,如此重复。
起因是默认状况JVM默认最大堆空间为零碎总内存的1/4,在容器中没有感知到集群为Pod设置的资源限度,而是按宿主机的内存算的,所以最终超过限度内存。
解决方案
解决思路有两种:
- 一种是按资源限度算好,在 Java 启动参数中设置堆内存大小,保障不超限度
- 另一种是让JVM感知到容器资源限度,按这个值来分配内存
Java SE 8u131向后 和 JDK 9 都有参数反对:如下
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
然而如果资源限度默认调配1/4有点节约,因为个别一个Pod就跑这一个次要过程,所以能够改下这个默认值,如下:
# 2 代表1/2-XX:MaxRAMFraction=2
这样配置并不代表就是资源限度的1/2,因为除了堆内存还有其余堆外内存须要空间,所以理论值要远小于1/2。网上有人在测试环境设置1,代表100%,然而我试过之后还是超过资源限度了,所以选了2,理论须要依据状况决定。
参考连贯
Java SE support for Docker CPU and memory limits
测试例子