admin管理员组文章数量:1648695
文章目录
- 背景
- Schedule Critical Pod
背景
Kubernetes 核心组件(如 API 服务器、调度器、控制器管理器)在控制平面节点上运行。 但是插件必须在常规集群节点上运行。 其中一些插件对于功能完备的集群至关重要,例如 Heapster、DNS 和 UI。 如果关键插件被逐出(手动或作为升级等其他操作的副作用)或者变成挂起状态,集群可能会停止正常工作。 关键插件进入挂起状态的例子有:集群利用率过高;被逐出的关键插件 Pod 释放了空间,但该空间被之前悬决的 Pod 占用;由于其它原因导致节点上可用资源的总量发生变化。
注意:
把某个 Pod 标记为关键 Pod 并不意味着完全避免该 Pod 被逐出;它只能防止该 Pod 变成永久不可用。 被标记为关键性的静态 Pod 不会被逐出。但是,被标记为关键性的非静态 Pod 总是会被重新调度。
要将 Pod 标记为关键性(critical),设置 Pod 的 priorityClassName 为 system-cluster-critical 或者 system-node-critical。 system-node-critical 是最高级别的可用性优先级,甚至比 system-cluster-critical 更高。
标识一个Pod为Critical Pod :
规则1:
- Enable Feature Gate ExperimentalCriticaPodAnnotation
- 必须隶属于kube-system namespace;
- 必须加上Annotation scheduler.alpha.kubernetes.io/critical-pod=“”
规则2:
- Enable Feature Gate ExperimentalCriticaPodAnnotation, PodPriority
- Pod的Priority不为空,且不小于2 * 10^9;
- system-node-critical priority = 10^9 + 1000;
- system-cluster-critical priority = 10^9;
满足规则1或规则2之一,就认为该Pod为Critical Pod;
Schedule Critical Pod
在default scheduler进行pod调度的predicate阶段,会注册GeneralPredicates为default predicates之一,并没有判断critical Pod使用EssentialPredicates来对critical Pod进行predicate process。这意味着什么呢?
我们看看GeneralPredicates和EssentialPredicates的关系就知道了。GeneralPredicates中,先调用noncriticalPredicates,再调用EssentialPredicates。因此如果你给Deployment/StatefulSet等(DeamonSet除外)标识为Critical,那么在scheduler调度时,仍然走GeneralPredicates的流程,会调用noncriticalPredicates,而你却希望它直接走EssentialPredicates。
// GeneralPredicates checks whether noncriticalPredicates and EssentialPredicates pass. noncriticalPredicates are the predicates
// that only non-critical pods need and EssentialPredicates are the predicates that all pods, including critical pods, need
func GeneralPredicates(pod *v1.Pod, meta algorithm.PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) {
var predicateFails []algorithm.PredicateFailureReason
fit, reasons, err := noncriticalPredicates(pod, meta, nodeInfo)
if err != nil {
return false, predicateFails, err
}
if !fit {
predicateFails = append(predicateFails, reasons...)
}
fit, reasons, err = EssentialPredicates(pod, meta, nodeInfo)
if err != nil {
return false, predicateFails, err
}
if !fit {
predicateFails = append(predicateFails, reasons...)
}
return len(predicateFails) == 0, predicateFails, nil
}
noncriticalPredicates原意是想对non-critical pod做的额外predicate逻辑,这个逻辑就是PodFitsResources检查。
pkg/scheduler/algorithm/predicates/predicates.go:1076
// noncriticalPredicates are the predicates that only non-critical pods need
func noncriticalPredicates(pod *v1.Pod, meta algorithm.PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) {
var predicateFails []algorithm.PredicateFailureReason
fit, reasons, err := PodFitsResources(pod, meta, nodeInfo)
if err != nil {
return false, predicateFails, err
}
if !fit {
predicateFails = append(predicateFails, reasons...)
}
return len(predicateFails) == 0, predicateFails, nil
}
PodFitsResources就做以下检查资源是否满足要求:
- Allowed Pod Number;
- CPU;
- Memory;
- EphemeralStorage;
- Extended Resources;
也就是说,如果你给Deployment/StatefulSet等(DeamonSet除外)标识为Critical,那么对应的Pod调度时仍然会检查Allowed Pod Number, CPU, Memory, EphemeralStorage,Extended Resources是否足够,如果不满足则会触发预选失败,并且在Preempt阶段也只是根据对应的PriorityClass进行正常的抢占逻辑,并没有针对Critical Pod进行特殊处理,因此最终可能会因为找不到满足资源要求的Node,导致该Critical Pod调度失败,一直处于Pending状态。
而用户设置Critical Pod是不想因为资源不足导致调度失败的。那如果我就是想使用Deployment/StatefulSet等(DeamonSet除外)标识为Critical Pod来部署关键服务呢?有以下两个办法:
按照前面提到的规则2,给Pod设置system-cluster-critical或system-node-critical Priority Class,这样就会在scheduler正常的Preempt流程中抢占到资源完成调度。
按照前面提到的规则1,并且修改GeneralPredicates 的代码如下,检测是否为Critical Pod,如果是,则不执行noncriticalPredicates逻辑,也就是说predicate阶段不对Allowed Pod Number, CPU, Memory, EphemeralStorage,Extended Resources资源进行检查。
func GeneralPredicates(pod *v1.Pod, meta algorithm.PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) {
var predicateFails, resons []algorithm.PredicateFailureReason
var fit bool
var err error
// **Modify**: check whether the pod is a Critical Pod, don't invoke noncriticalPredicates if false.
isCriticalPod := utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalCriticalPodAnnotation) &&
kubelettypes.IsCriticalPod(newPod)
if !isCriticalPod {
fit, reasons, err = noncriticalPredicates(pod, meta, nodeInfo)
if err != nil {
return false, predicateFails, err
}
}
if !fit {
predicateFails = append(predicateFails, reasons...)
}
fit, reasons, err = EssentialPredicates(pod, meta, nodeInfo)
if err != nil {
return false, predicateFails, err
}
if !fit {
predicateFails = append(predicateFails, reasons...)
}
return len(predicateFails) == 0, predicateFails, nil
}
方法1,其实Kubernetes在Admission Priority检查时已经帮你做了。
// admitPod makes sure a new pod does not set spec.Priority field. It also makes sure that the PriorityClassName exists if it is provided and resolves the pod priority from the PriorityClassName.
func (p *priorityPlugin) admitPod(a admission.Attributes) error {
...
if utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
var priority int32
if len(pod.Spec.PriorityClassName) == 0 &&
utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalCriticalPodAnnotation) &&
kubelettypes.IsCritical(a.GetNamespace(), pod.Annotations) {
pod.Spec.PriorityClassName = scheduling.SystemClusterCritical
}
...
}
在Admission时候会对Pod的Priority进行检查,如果发现您已经:
- Enable PriorityClass Feature Gate;
- Enable ExperimentalCriticalPodAnnotation Feature Gate;
- 给Pod添加了ExperimentalCriticalPodAnnotation;
- 部署在kube-system namespace;
- 没有手动设置自定义PriorityClass;
那么,Admisson Priority阶段会自动给Pod添加SystemClusterCritical(system-cluster-critical) PriorityClass;
最佳实践
通过上面的分析,给出如下最佳实践:在Kubernetes集群中,通过非DeamonSet方式(比如Deployment、RS等)部署关键服务时,为了在集群资源不足时仍能保证抢占调度成功,请确保如下事宜:
- Enable PriorityClass Feature Gate;
- Enable ExperimentalCriticalPodAnnotation Feature Gate;
- 给Pod添加了ExperimentalCriticalPodAnnotation;
- 部署在kube-system namespace;
- 千万不要手动设置自定义PriorityClass;
版权声明:本文标题:critical Pod 的调度保证 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1726268951a1063580.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论