Docker 与 K8S学习笔记(二十五)—— Pod的各种调度策略(下)

时间:2022-10-23 17:06:11

在实际应用中,我们往往需要提高Kubernetes集群的资源利用率,即允许集群中所有负载所需的资源总量超过集群所提供的资源量,这个时候,当资源不足时,系统可以选择释放一些不重要的负载,保障最重要的负载能够运行,这就是我们今天要学习的优先级抢占调度策略

 

要使用优先级抢占,需要做以下两件事:

  • 定义PriorityClass;

  • 在Pod配置中声明PriorityClassName并设置为上面所定义的PriorityClass。

1、定义PriorityClass

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: priority-class-demo
value: 100000
globalDefault: false
description: "This is a demo priority class."

这里我们需要注意,PriorityClass不属于任何命名空间,在上面这个例子中,我们定义了一个叫做priority-cass-demo的PrioriryClass,其优先级为100000,这个值越大,优先级越高,而超出10亿的值,其实是被Kubernetes保留下来分配给系统 Pod使用的。显然,这样做就是为了保证系统 Pod 不会被业务Pod抢占掉。我们设置globalDefault为false意味着,创建这个PriorityClass之后,所创建的Pod的默认优先级都是100000。我们创建此PriorityClass:

[root@kubevm1 workspace]# kubectl apply -f priority_class.yml
priorityclass.scheduling.k8s.io/priority-class-demo created

2、为Pod指定PriorityClass

我们修改nginx的deployment,在其中pod配置中增加PriorityClassName的设置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      priorityClassName: priority-class-demo
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

当 Pod 拥有了优先级之后,高优先级的 Pod 就可能会比低优先级的 Pod 提前出队,从而尽早完成调度过程。但如果由于集群负载较大,一个高优先级Pod调度失败时,调度器的抢占能力就会被触发。此时调度器就会试图从当前集群里寻找一个Node,使得当这个Node上的一个或者多个低优先级 Pod 被删除后,待调度的高优先级 Pod 就可以被调度到这个节点上。当然在实际操作过程中,如果恰好此时又出现了一个优先级更高的Pod,调度器就会优先调度这个更高优先级的Pod,然后在重新调度之前等待的次高优先级Pod。

大家可以看出来,这个抢占能力其实对于服务性Pod影响不大,但对于执行批处理任务的Pod来说是一个灾难,这有可能导致Job没有执行完任务就被驱逐,从而导致部分任务没有被执行完成。为了避免这个问题,PriorityClass增加了一个属性preemptionPolicy,这个属性默认值为PreemptLowerPriority,即抢占资源,当我们设置为Never时,则不会抢占资源,而是默默排队,等待被调度。

以上就是优先级抢占调度的执行过程,其实我们不难看出,这个调度策略有可能会增加系统复杂性,以及部署在集群上的业务系统的稳定性,所以如果出现资源不足的情况,最好优先考虑扩容方案,实在不行在考虑优先级抢占调度。