只要节点有足够的内存资源,那容器就可以使用超过其申请的内存,但是不允许容器使用超过其限制的 资源。如果容器分配了超过限制的内存,这个容器将会被优先结束。如果容器持续使用超过限制的内存, 这个容器就会被终结。如果一个结束的容器允许重启,kubelet就会重启他,但是会出现其他类型的运行错误。
腾讯认为张阳认为 (再limit 和request比例悬殊 增长超出node特殊情况下):
1. 如果Pod的实际使用内存,超过了 Node 的实际内存,肯定会发生驱逐的,有个优先级:先驱逐未设置 request/limit 的pod,再驱逐 request/limit 不相等的pod,最后驱逐 request/limit 相等的pod。
2. 避免的话有几个可以考虑:设置合理的 request 防止在调度层面的不均匀、使用 TKE 的 DynamicScheduler、DeScheduler 插件优化调度策略,让 kube-scheduler 按照真实负载进行调度。
参考:
1. DynamicScheduler:https://cloud.tencent.com/document/product/457/50843
2. DeScheduler:https://cloud.tencent.com/document/product/457/50921腾讯
简单来说,
request影响的是k8s的调度,也就是说k8s会保证container所request的资源,在调度时会考虑node是否满足request的条件。
limit则是实际运行时k8s的限制,防止container无限制的占用node的资源。显然的,由于调度时更多的考虑了request而不是limit,那么必然会出现某个node上container的limit总和超过该node资源的情况,此时,k8s针对cpu和memory会由不同的处理。
对于cpu,k8s认为cpu是可压缩的,在应用达到limit时,k8s会减少该容器的调度时间,并不会杀死应用。
对于memory,k8s认为memory是无法压缩的,此时k8s会杀死占用资源超过其request的应用(1.9版本之后的版本)。首当其冲的是没有指定request的container,然后是使用资源超过其request更多的container。同等情况下优先级更低的container更容易被杀死。
https://www.cnblogs.com/xuliang666/p/11137128.html
设置系统内核参数:
1 2 3 |
|
它是 内存分配策略
可选值:0、1、2。
设置overcommit_memory = 0.是为了避免系统发生OOM自动杀死进程.
解释:什么是Overcommit和OOM
Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做 Overcommit。当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。
当oom-killer发生时,linux会选择杀死哪些进程?选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该 函数会计算每个进程的点数(0~1000)。点数越高,这个进程越有可能被杀死。每个进程的点数跟oom_score_adj有关,而且 oom_score_adj可以被设置(-1000最低,1000最高)。
vm.swappiness = 0 就是限制使用交换分区.应该kubernetes不建议使用交换分区,而且一般是关闭交换分区的.
cat /var/lib/kubelet/config.yaml
默认参数
1 2 3 4 5 6 |
|
内存限制优化:
1 2 3 4 5 |
|
这里自行百度了解 Kubernetes Eviction Manager工作机制
实在不行 我简单复制粘贴一点内容吧...哭.......
首先,我们来谈一下kubelet通过OOM Killer来回收资源的缺点:
我们再来看看Kubelet Eviction有何不同:
下面,我们具体来研究一下Kubelet Eviction Policy的工作机制。
就是requests和limits参数设置内存,cpu.按自己需求设置即可.
默认是不限制资源
Kubernetes集群随着应用的迭代,会产生很多无用的镜像和容器,因此需要定时清理,分布在每个节点的Kubelet有GC(垃圾收集)的职责,当集群中有断定为垃圾的镜像或容器,那么kubelet会清除掉相关镜像或容器。容器GC间隔为1分钟,镜像GC间隔为5分钟。而这在某些情况下会产生问题,如:私有离线部署环境中,如果某个node节点相关的镜像被清理了,当在这个启动相关容器就会失败,由于是离线,那么拉取镜像也会失败。
解决办法:
# 排查参考文章:
https://blog.csdn.net/fly910905/article/details/90179225
# 理解Linux oom
https://blog.csdn.net/run_for_belief/article/details/83446344
# jvm oom 八种原因和排查
https://blog.csdn.net/fly910905/article/details/90179225
# 理解 java oom
https://www.cnblogs.com/bhlsheji/p/5330045.html
省略比較小的区域,能够总结JVM占用的内存:
JVM内存 ≈ Java永久代 + Java堆(新生代和老年代) + 线程栈+ Java NIO