Kubernetes 之limit和request

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes 之limit和request相关的知识,希望对你有一定的参考价值。

参考技术A 容器可以使用资源的最大值,设置为0表示使用资源无上限。

对于每一个资源,container可以指定具体的资源需求(requests)和闲置(Limits),request 申请范围是0 到node节点的最大配置,而Limit 申请范围是requests到无限,即 0 <= Requests <= Node Allocatable,Request <= Limits <= Infinity。
对于CPU,如果POD中服务使用CPU 超过设置的Limits,pod 不会被Kill 掉,但是会被闲置。如果没有设置Limits,pod可以使用全部空闲的CPU 资源。
对于内存,当一个POD 使用内存超过了设置的Limits,POD 中container 的进程会被kernel 因OOM 而kill掉。当container 因为OOM被kill时,系统倾向于在其原所在的机器上重启该container或其他节点上重新重建一个POD

Kubelet提供QoS服务质量管理,支持系统级别的OOM控制。在Kubernetes中,pod的QoS级别包括:Guaranteed, Burstable与 Best-Effort

pod中的所有容器都必须对cpu和memory同时设置limits,如果有一个容器要设置requests,那么所有容器都要设置,并设置参数同limits一致,那么这个pod的QoS就是Guaranteed级别。
注:如果一个容器只指明limit而未设定request,则request的值等于limit值。

如果对于全部的resources来说requests与limits均未设置,该pod的QoS即为Best-Effort

Kubernetes根据资源能否伸缩进行分类,划分为可压缩资源和不可以压缩资源2种。
CPU资源是目前支持的一种可压缩资源,而内存资源和磁盘资源为目前所支持的不可压缩资源。

3种QoS优先级从有低到高(从左向右):

Best-Effort pods -> Burstable pods -> Guaranteed pods

在Kubernetes中有一种DaemonSet类型pod,此类pod可以常驻在某个Node上运行,由该Node上kubelet服务直接管理而无需api server介入。静态pod也无需关联任何RC,完全由kubelet服务来监控,当kubelet发现静态pod停止时,kubelet会重新启动静态pod。

当kubernetes集群中某个节点上可用资源比较小时,kubernetes提供了资源回收策略保证被调度到该节点pod服务正常运行。当节点上的内存或者CPU资源耗尽时,可能会造成该节点上正在运行的pod服务不稳定。Kubernetes通过kubelet来进行回收策略控制,保证节点上pod在节点资源比较小时可以稳定运行。

在压缩资源部分已经提到CPU属于可压缩资源,当pod使用超过其设置的limits值时,pod中的进程会被限制使用cpu,但不会被kill。

Kubernetes通过cgroup给pod设置QoS级别,当资源不足时先kill优先级低的pod,在实际使用过程中,通过OOM分数值来实现,OOM分数值从0-1000。

OOM分数值根据OOM_ADJ参数计算得出,对于Guaranteed级别的pod,OOM_ADJ参数设置成了-998,对于BestEffort级别的pod,OOM_ADJ参数设置成了1000,对于Burstable级别的POD,OOM_ADJ参数取值从2到999。对于kubernetes保留资源,比如kubelet,docker,OOM_ADJ参数设置成了-999,表示不会被OOM kill掉。OOM_ADJ参数设置的越大,通过OOM_ADJ参数计算出来OOM分数越高,表明该pod优先级就越低,当出现资源竞争时会越早被kill掉,对于OOM_ADJ参数是-999的表示kubernetes永远不会因为OOM而被kill掉。
QoS pods被kill掉的场景与顺序

如果资源充足,可将QoS pods类型均设置为Guaranteed。用计算资源换业务性能和稳定性,减少排查问题时间和成本。
如果想更好的提高资源利用率,业务服务可以设置为Guaranteed,而其他服务根据重要程度可分别设置为Burstable或Best-Effort,例如filebeat。

kubernetes-pod资源需求和资源限制

一、如果requests与limits相等,则为指定固定大小。也可不指定limits为无上限,但cpu不足1核心时,最多只能跑满一个核心。

apiVersion: v1
kind: Pod
metadata:
name: stress-pod
spec:
containers:
- name: stress
image: ikubernetes/stress-ng
command: ["/usr/bin/stress-ng", "-c 1", "-m 1", "--metrics-brief"]
resources:
requests: #下阈值,最小阈值
memory: "128Mi"
cpu: "200m"
limits: #上阈值,最大阈值
memory: "512Mi"
cpu: "400m"
#测试
kubectl exec stress-pod -- top

二、Pod的资源优先级

QoS Class:服务质量类别,代表了Pod的资源被优先满足的类别
Guaranteed:Pod内的每个容器都分别设定了CPU和Memroy资源需求和资源限制,CPU的需求与限制相等,而且Memory的需求与限制也相等;
Bustable:中间层
BestEffort:未为任何一个容器设定任何需求或限制;

三、pod 安全上下文、探针、sidecar、资源汇总示例

apiVersion: v1
kind: Pod
metadata:
name: all-in-one
namespace: default
spec:
initContainers:
- name: iptables-init
image: ikubernetes/admin-box:latest
imagePullPolicy: IfNotPresent
command: [/bin/sh,-c]
args: [iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80]
securityContext:
capabilities:
add:
- NET_ADMIN
containers:
- name: sidecar-proxy
image: envoyproxy/envoy-alpine:v1.13.1
command: [/bin/sh,-c]
args: [sleep 3 && envoy -c /etc/envoy/envoy.yaml]
lifecycle:
postStart:
exec:
command: [/bin/sh,-c,wget -O /etc/envoy/envoy.yaml http://ilinux.io/envoy.yaml]
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
- name: demo
image: ikubernetes/demoapp:v1.0
imagePullPolicy: IfNotPresent
env:
- name: PORT
value: 8080
livenessProbe:
httpGet:
path: /livez
port: 8080
initialDelaySeconds: 5
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 15
securityContext:
runAsUser: 1001
runAsGroup: 1001
resources:
requests:
cpu: 0.5
memory: "64Mi"
limits:
cpu: 2
memory: "1024Mi"
securityContext:
supplementalGroups: [1002, 1003]
fsGroup: 2000

以上是关于Kubernetes 之limit和request的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes 内存管理及调度

Kubernetes CPU管理及调度

kubernetes-pod资源需求和资源限制

Kubernetes学习总结—— Kubernetes Pod 资源管理 和 Pod 服务质量

资源画像,让容器资源规格的填写不再纠结

k8s 资源管理