K8s pod priority
Opened this issue · 0 comments
Wang-Kai commented
K8s pod 可以配置优先级,高优先级的任务可以被 scheduler 优先调度。
为 pod 设置调度优先级
为 pod 设置优先级,标准的做法是先创建 PriorityClass(简称 pc),pc 核心有几个配置:
value
优先级值,int32 类型(可以为负数),值越大优先级越高preemptionPolicy
抢占策略,"PreemptLowerPriority" & "Never" 二选一,前者将抢占低优先级 pod,后者不做抢占,仅相对于低优先级 pod,在 scheduler 的调度队列里排在前面globalDefault
声明是否是默认的 priorityclass
创建完 pc 后,在 pod.spec.priorityClassName
配置即可,默认的 Priority admission controller 会根据 spec.priorityClassName
去获取其 value & preemptionPolicy 填写到 pod.spec.Priority & pod.spec.preemptionPolicy。
对于未声明 spec.priorityClassName 的 pod,如果集群内有 globalDefault=true
的 pc,admission controller 会将该 pc 作为默认配置。如果集群内有多个 pc 都标记为 globalDefault
,会取其中优先级最低的 pc 予以设置。
遇到过的问题
1)开启了 priority admission 后,就不能随意配置 po.spec.priority
admission plugin 会根据 PriorityClassName 去获取对于的 pc 配置,如果没填则此时 priority value 就是 0。此时如果自定义了 pod.spec.priority,pod.Spec.Priority != nil && *pod.Spec.Priority != priority
条件成立就会报错。
if len(pod.Spec.PriorityClassName) == 0 {
var err error
var pcName string
pcName, priority, preemptionPolicy, err = p.getDefaultPriority()
if err != nil {
return fmt.Errorf("failed to get default priority class: %v", err)
}
pod.Spec.PriorityClassName = pcName
} else {
// Try resolving the priority class name.
pc, err := p.lister.Get(pod.Spec.PriorityClassName)
if err != nil {
if errors.IsNotFound(err) {
return admission.NewForbidden(a, fmt.Errorf("no PriorityClass with name %v was found", pod.Spec.PriorityClassName))
}
return fmt.Errorf("failed to get PriorityClass with name %s: %v", pod.Spec.PriorityClassName, err)
}
priority = pc.Value
preemptionPolicy = pc.PreemptionPolicy
}
// if the pod contained a priority that differs from the one computed from the priority class, error
if pod.Spec.Priority != nil && *pod.Spec.Priority != priority {
return admission.NewForbidden(a, fmt.Errorf("the integer value of priority (%d) must not be provided in pod spec; priority admission controller computed %d from the given PriorityClass name", *pod.Spec.Priority, priority))
}