在Kubernetes中,Pod是最小的调度单元,所以跟资源和调度相关的属性都是Pod对象的字段,而其中最重要的就是CPU和内存。如下所示:
---
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
spec:
containers:
- name: myweb
image: wordpress
imagePullPolicy: IfNotPresent
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
其中resources就是资源限制部分。 注:由于一个Pod里可以定义多个Containers,而每个资源限制都是配置在各自的Container,所以Pod的整体配置资源是所有Containers的总和。
在Kubernetes中,CPU这样的资源被称为"可压缩资源",所谓可压缩资源就是当可用资源不足的时候,Pod只会"饥饿",不会退出。而向Memory这样的资源被称为"不可压缩资源",所谓的不可压缩资源就是当资源不足的时候Pod只会OOM。
其中CPU的设置单位是CPU的个数,比如CPU=1就表示这个Pod的CPU限额是1个CPU,而到底是1个CPU核心、是1个vCPU还是1个CPU超线程,这要取决于宿主机上CPU实现方式,而Kunernetes只需要保证该Pod能够使用到1个CPU的使用能力。
Kubernetes允许将CPU的限额设置位分数,比如上面我们设置的CPU.limits的值为500m,而所谓的500m就是500milliCPU,也就是0.5个CPU,这样,这个Pod就会被分到一个CPU一半的计算能力。所以我们可以直接把配置写成cpu=0.5,不过官方推荐500m的写法,这是Kubernetes内部的CPU计算方式。
在Kubernetes中,内存资源的单位是bytes,支持使用Ei,Pi,Ti,Gi,Mi,Ki的方式作为bytes的值,其中需要注意Mi和M的区别(1Mi=10241024,1M=10001000)。
Kubernetes中Pod的CPU和内存的资源限制,实际上分为requests和limits两种情况。
spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory
spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory
这两者的区别如下:
Kubernetes中支持三种QoS模型。其分类是基于requests和limits的不同配置。
当Pod里的每一个Containers都设置了requests和limits,并且其值都相等的时候,这种Pod就属于Guaranteed类别,如下:
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
注意,当这Pod仅设置limits,没有设置requests的时候,系统默认为它分配与limits相等的requests值,也就会被划分为Guaranteed类别。
而当这个Pod不满足Guaranteed条件,但至少有一个Contaienrs设置了requests,那么这个Pod就会被划分为Burstable类别。如下:
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-2
namespace: qos-example
spec:
containers:
- name: qos-demo-2-ctr
image: nginx
resources:
limits
memory: "200Mi"
requests:
memory: "100Mi"
如果这个Pod既没有设置requests值,也没有设置limits的值的时候,那么它的QoS类别就是BestEffort类别。
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: nginx
而QoS划分的主要场景就是当宿主机资源紧张的时候,kubelet对资源进行Eviction时需要用到。目前Kubernetes设置的默认Eviction的阈值如下:
memory.available<100Mi
nodefs.available<10%
nodefs.inodesFree<5%
imagefs.available<15%
上述条件可以在kubelet中设置:
kubelet --eviction-hard=imagefs.available<10%,memory.available<500Mi,nodefs.available<5%,nodefs.inodesFree<5% --eviction-soft=imagefs.available<30%,nodefs.available<10% --eviction-soft-grace-period=imagefs.available=2m,nodefs.available=2m --eviction-max-pod-grace-period=600
Kubernetes中的Eviction分为Soft Eviction和Hard Eviction两种模式。
当宿主机的Eviction阈值达到后,就会进入MemoryPressure或者DiskPressure状态,从而避免新的Pod调度到上面去。而当Eviction发生时,kubelet删除Pod的先后顺序如下:
cpuset,就是把容器绑定到某个CPU核上,减少CPU的上下文切换。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "200Mi"
cpu: "2"