资源管理
在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
这两者的区别如下:
- 在调度的时候,kube-scheduler会安requests的值进行计算;
- 在设置CGroups的时候,kubelet会安limits的值来进行设置;
QoS模型
Kubernetes中支持三种QoS模型。其分类是基于requests和limits的不同配置。
Guaranteed
当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类别。
Burstable
而当这个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"
BestEffort
如果这个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两种模式。
- Soft Eviction允许设置优雅等待时间,如上设置imagefs.available=2m,允许在Imagefs不足阈值达到2分钟之后才进行Eviction;
- Hard Eviction在达到阈值就进行Eviction;
当宿主机的Eviction阈值达到后,就会进入MemoryPressure或者DiskPressure状态,从而避免新的Pod调度到上面去。而当Eviction发生时,kubelet删除Pod的先后顺序如下:
- BestEffort 类型的Pod;
- Burstable类别并且发生”饥饿”的资源使用量已经超出了requests的Pod;
- Guaranteed类别并且只有当Guaranteed类别的Pod的资源使用量超过了其limits限制,或者宿主机本身处于Memory Pressure状态时,Guaranteed才会被选中被Eviction;
cpuset
cpuset,就是把容器绑定到某个CPU核上,减少CPU的上下文切换。
- Pod必须是Guaranteed类型;
- 只需要将Pod的CPU资源的requests和limits设置为同一个相等的数值; ```yaml
spec: containers:
- name: nginx
image: nginx
resources:
limits:
requests:memory: "200Mi"
cpu: "2"
```memory: "200Mi"
cpu: "2"