资源类型
Kubernetes 里,Pod 是最小的原子调度单位。这也就意味着,所有跟调度和资源管理相关的属性都应该是属于 Pod 对象的字段。
在k8s中,像CPU这样的资源被称为“可压缩资源”,即资源不足的时候会饥饿但是不会退出。而内存这样的资源被称为“不可压缩资源”,即资源不足的话Pod就会被内核kill掉。
k8s中Pod的内存和CPU资源还要分为requests和limits两种情况。
- 调度的时候按照requests。
- 真正设置cgroups的时候按照limits。 也就是调度的时候按需使用资源,避免浪费,但是其可以使用的最大资源还是按照limits来的。用户在提交 Pod 时,可以声明一个相对较小的 requests 值供调度器使用,而 Kubernetes 真正设置给容器 Cgroups 的,则是相对较大的 limits 值。
QoS
根据limit和request的设置方式的不同,k8s会将Pod划分至不同的QoS级别当中。
Guarantee
当limits和request都被设置,并且两者的值相同的时候,这个Pod就属于Guarantee类别。但是需要注意,当设置了limits而没有设置request的时候,k8s会自动为其设置于limits相同的requests,所以可以这样认为。只要每一个容器都设置了limits或者同时设置了相同的limits和requests,这个Pod就是Guarantee级别的。如下:
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"Burstable级别
首先不满足Guarantee级别,但是至少有一个容器设置了requests,那么就是Burstable级别的。例如下面的Pod,limits和requests设置并不相同
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级别
即没有设置limits,也没有设置requests,那么这个Pod就是BestEffort级别。
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: nginx资源回收
上面介绍的三种QoS级别,就是k8s在资源紧张的时候进行Eviction(资源回收)会用到的。 当宿主机上的不可压缩资源紧张的时候就可能触发Eviction,例如内存,磁盘空间,容器运行时镜像存储空间等等。
例如,k8s的默认Eviction默认阈值:
memory.available<100Mi
nodefs.available<10%
nodefs.inodesFree<5%
imagefs.available<15%当然触发条件也是可以配置的。
Eviction分为Soft和Hard两种模式。它们的区别就在于,Soft模式允许设置优雅时间,就是触发之后等待这段时间再进行Eviction。而Hard模式则是在达到阈值之后立即就执行了。
当宿主机的 Eviction 阈值达到后,就会进入 MemoryPressure 或者 DiskPressure 状态,从而避免新的 Pod 被调度到这台宿主机上。
是前面介绍的三种QoS其实就是Eviction时候的优先级。最先被回收的就是BestEffort级别的资源,然后是Burstable,最后才是Guarantee级别。可以这样理解,对Pod的资源限制越多,说明越希望这个Pod能够保证运行,所以越晚被回收。
==DaemonSet的Pod强烈推荐设置为Guarantee,不然就算被回收也会被立即创建出来,没有意义==。
设置cpuset
容器可以通过设置cpuset绑定在固定的cpu核上,这样就避免了进城上下文的切换,大大提高了容器里应用的性能。
同样的,设置cpuset也是生产环境里部署在线类型的Pod的时候非常常用的方式。
设置的方式也非常简单,就是Pod要求是Guarantee级别的,如下:
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "200Mi"
cpu: "2"这样这个Pod就会被绑定到2个固定的CPU核上,具体是哪两个核是由kubelet分配的。