k8s_PaaS/原理及源码解析/Kubernetes调度机制.md
2020-04-15 22:54:49 +08:00

4.4 KiB
Raw Blame History

Kubernetes调度机制

Kubernetes的资源模型与资源管理

所有跟调度和资源管理相关的属性都是属于 Pod 对象的字段,其中最重要的部分,就是 Pod 的 CPU 和内存配置,如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

在Kubernetes 中:

  • CPU称为 “可压缩资源” 可压缩资源不足时Pod只会“饥饿”不会退出
  • 内存称为“不可压缩资源”不可压缩资源不足时Pod会因为OOMOut-Of-Memory被内核杀掉
  • Pod 可以由多个 Container 组成,所以 CPU 和内存资源的限额,是要配置在每个 Container 的定义上的而Pod整体资源配置就由这些 Container 的配置值累加得到

limits 和 requests 的区别很简单在调度的时候kube-scheduler 只会按照 requests 的值进行计算。而在真正设置 Cgroups 限制的时候kubelet 则会按照 limits 的值来进行设置。

requests+limits 的做法其实是Borg的思想实际场景中大多数作业使用到的资源其实远小宇它所请求的资源限额基于这种假设用户可以声明一个相对小的requests值供调度器使用而Kubernetes 真正设置给容器 Cgroups 的,则是相对较大的 limits 值。

QoS 模型:

三个级别,衔接上面

  • **Guaranteed**Pod 里的每一个 Container 都同时设置了 requests 和 limits并且 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"
  • **Burstable**当 Pod 不满足 Guaranteed 的条件,但至少有一个 Container 设置了 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 对 Pod 进行 Eviction即资源回收时需要用到的。**当Eviction发生时kubelet 具体会挑 Pod 进行删除操作,按如下级别:

BestEffort < Burstable < Guaranteed

并且Kubernetes 会保证只有当 Guaranteed 类别的 Pod 的资源使用量超过了其 limits 的限制,或者宿主机本身正处于 Memory Pressure 状态时Guaranteed 的 Pod 才可能被选中进行 Eviction 操作。

cpuset 的设置

一个实际生产中非常有用的特性,衔接上面

在使用容器时,可以通过设置 cpuset 把容器绑定到某个 CPU 的核上,而不是像 cpushare 那样共享 CPU 的计算能力这样CPU之间进行上下文切换的次数大大减少容器里应用的性能会得到大幅提升

实现方法:

  • Pod 必须是 Guaranteed 的 QoS 类型
  • 将 Pod 的 CPU 资源的 requests 和 limits 设置为同一个相等的整数值

如下例子:

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "2"
      requests:
        memory: "200Mi"
        cpu: "2"

这样该Pod就会绑定在2个独占的CPU核上具体是哪两个CPU由kubelet 分配

基于上面的情况建议将DaemonSet亦或者类似的的 Pod 都设置为 Guaranteed 的 QoS 类型,否则一旦被资源紧张被回收,又立即会在宿主机上重建出来,这样资源回收的动作就没有意义了