Kubernetes Qos之Requests和Limits的注意项及记录

使用Kubernetes去创建Deployment, StatefulSet和DaemonSet等controller,或直接创建pod时,可设置内部容器的RequestsLimits,这里有不少地方需要注意,以下作记录和总结。

  • Requests用于pod的调度, kube scheduller在一系列条件筛选后(taints 和 affinity等),当然也有predicate预选和priority等过滤过程, 最后使用round robin算法将pod调度到满足Requests资源要求的Node上。

  • Limits 用于限制pod的资源使用量。

  • pod包含多个container,则该pod的调度和资源限制分别由podcontainerRequests总量和Limits总量来决定。

  • Limits的值不能低于Requests的值,否则apiserver会报错。

  • Limits中,CPUMemory某一项超过kubernetes集群内最大节点配置,则该pod将永远不会被调度到Node上。除非一些云服务商会配置vm伸缩策略去实时增加vmkubernetes集群上,如GKE。

  • 除非部署的app使用多线程模型,能利用多cpu核操作,否则建议使用1核或以下配置,并配合多实例使用。

  • 当某container对CPU的使用量超过Limits时,由于CPU是可压缩资源,kubernetes会限制该container 的CPU使用量, 导致container的性能下降, 但contianer不会退出或停止。可使用liveness health check 对container进行健康检查。

  • 当某containerMemory的使用量超过Limits时, kubernetes不能限制Memory的使用,但是会让container停止,若该container对应的pod是由deployment来控制的话,则会使得pod不断地重启。系统倾向于在其原所在的机器上重启该container

  • 当某节点内所有的containersLimits总量超过该节点的可用资源capacity时,这时候kubernetes进入overcommitted 状态:

    • 节点的Memory使用量用满时,kubernetes会启动算法去删除超出Request申请量的container。若存在多个这样的container, 则根据priorityRequest的超出量来决定。
    • 按照Qos的规范,删除的顺序为Best-Effort pods -> Burstable pods -> Guaranteed pods。源码kubernetes\pkg\kubelet\qos\policy.go
    • 节点的cpu使用量用满时,kubernetes压缩各containercpu使用量,同时会确保各container能使用其在Requests指定的使用量。
  • DaemonSet不适合创建BestEffort 类型的Pods,而通常应该为Guaranteed类型Pods更为恰当。因为当节点资源紧张时,BestEffort类型的Pods会被优先驱散,但是由于DaemonSet 的特性, Pod在驱散后仍会在原节点启动。

  • 可以通过设置ResourceQuotas对象来限制命名空间下的所有containerRequestsLimits的总量。

  • 可以通过设置LimitRanges来限制(或提供默认值)每一个containerRequestsLimits

  • 关于kube scheduller的调度原理及其源码分析,参见此文章足矣。

  • 关于RequestsLimits的底层实现机制:
    Kubernetes Qos之Requests和Limits的注意项及记录_第1张图片

  • pod被删除的过程,过程分为若干阶段:

    1. pod 首先进入默认的30s grace period,可通过podterminationGracePeriodSeconds调整grace period的大小。
    2. pod.state = Terminating, service对应的endpoint会被清理,pod 不再接收访问流量。此过程是滚动式的,保证服务的可用性。此时pod内的container运行不会受影响。
    3. kubernetes 同时执行preStop Hook 指定的指令。若app中已有逻辑捕获SIGTERM信号(在golang开发的web service的场景中,程序中利用signal库实现SIGTERM信号的捕获并实施一些列的回收释放操作(数据库连接池回收,日志服务回收等,同时调用net/http中的Shutdown方法,使得web service同样能够gracefully shut down),则可不指定preStop Hook
    4. SIGTERM 信号同时传输到pod内的containerpid1的进程。
    5. 若在terminationGracePeriodSeconds未执行完preStop Hookapp捕获SIGTERM信号后的清理逻辑,SIGKILL则会发送到container。同时kubernetes会清理所有container所涉及到的Object。此后不能从apiserver查询到该pod
Reference:

https://cloud.google.com/blog/products/gcp
https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
https://medium.com/@betz.mark/understanding-resource-limits-in-kubernetes-cpu-time-9eff74d3161b
https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/

你可能感兴趣的:(Docker,Kubernetes)