前言
Kubernetes中的调度是将挂起的Pod绑定到节点的过程,由Kubernetes的一个称为kube-scheduler的组件执行。调度程序的决定(是否可以调度Pod或在何处调度)由其可配置策略指导,该策略由称为谓词和优先级的一组规则组成。当出现新的Pod进行调度时,调度程序的决定会受到其对Kubernetes集群的看法的影响。由于Kubernetes集群非常动态,并且其状态会随着时间而变化,因此出于各种原因,可能希望将已经运行的Pod移动到其他一些节点
- 一些节点利用率低下或过度使用。
- 原始的调度决策不再成立,因为将污点或标签添加到节点或从节点删除,节点/节点亲和力要求不再满足。
- 一些节点发生故障,并且其pod移至其他节点。
- 新节点将添加到群集。
因此,可能在群集中不太理想的节点上安排了多个Pod。Descheduler根据其政策找到可以移动的node并将其逐出。请注意,在当前的实现中,descheduler不会安排被驱逐的node的替换,而是依赖于默认的安排器。
部署方式
官方支持两种方式进行部署 Job 和CronJob
kubectl create -f kubernetes/base/rbac.yaml
kubectl create -f kubernetes/base/configmap.yaml
kubectl create -f kubernetes/job/job.yaml
kubectl create -f kubernetes/base/rbac.yaml
kubectl create -f kubernetes/base/configmap.yaml
kubectl create -f kubernetes/cronjob/cronjob.yaml
策略
目前 Descheduler 支持8大策略,默认情况下均已开启下面逐一介绍
RemoveDuplicates
该策略确保只有一个Pod与在同一节点上运行的副本集(RS),复制控制器(RC),部署或作业相关联。如果有更多的Pod,则将这些重复的Pod逐出,以更好地在群集中扩展Pod。如果某些节点由于任何原因而崩溃,并且它们上的Pod移至其他节点,导致多个与RS或RC关联的Pod(例如,在同一节点上运行),则可能发生此问题。一旦发生故障的节点再次准备就绪,便可以启用此策略以驱逐这些重复的Pod。
当前该策略提供了下列参数
参数
Name | Type |
---|---|
excludeOwnerKinds |
list(string) |
namespaces |
(see namespace filtering) |
thresholdPriority |
int (see priority filtering) |
thresholdPriorityClassName |
string (see priority filtering) |
例子
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemoveDuplicates":
enabled: true
params:
removeDuplicates:
excludeOwnerKinds:
- "ReplicaSet"
LowNodeUtilization
该策略查找未充分利用的节点,并从其他节点驱逐 Pod,以便 kube-scheudler 重新将它们调度到未充分利用的节点上。该策略的参数可以通过字段 nodeResourceUtilizationThresholds 进行配置。
节点的利用率不足可以通过配置 thresholds 阈值参数来确定,可以通过 CPU、内存和 Pod 数量的百分比进行配置。如果节点的使用率均低于所有阈值,则认为该节点未充分利用。
此外,还有一个可配置的阈值 targetThresholds,该阈值用于计算可从中驱逐 Pod 的那些潜在节点,对于所有节点 thresholds 和 targetThresholds 之间的阈值被认为是合理使用的,不考虑驱逐。targetThresholds 阈值也可以针对 CPU、内存和 Pod 数量进行配置。thresholds 和 targetThresholds 可以根据你的集群需求进行动态调整。
参数
Name | Type |
---|---|
thresholds |
map(string:int) |
targetThresholds |
map(string:int) |
numberOfNodes |
int |
thresholdPriority |
int (see priority filtering) |
thresholdPriorityClassName |
string (see priority filtering) |
例子
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"LowNodeUtilization":
enabled: true
params:
nodeResourceUtilizationThresholds:
thresholds:
"cpu" : 20
"memory": 20
"pods": 20
targetThresholds:
"cpu" : 50
"memory": 50
"pods": 50
注意如果未指定任何资源类型,则其所有阈值均默认为100%,以避免节点从未充分利用变为过度利用。
与该LowNodeUtilization
策略相关的另一个参数称为numberOfNodes
。仅当未充分利用的节点数大于配置的值时,才可以配置此参数以激活策略。这在大型群集中很有用,其中一些节点可能会频繁使用或短期使用不足。默认情况下,numberOfNodes
设置为零。
RemovePodsViolatingInterPodAntiAffinity
此策略可确保从节点中删除违反了脚间抗亲和性的node。例如,如果一个节点上有podA,并且podB和podC(在同一节点上运行)具有禁止它们在同一节点上运行的反关联性规则,则podA将被从该节点驱逐,以便podB和podC可以跑。当podB和podC的反关联性规则已在节点上运行时,如果它们创建了反关联性规则,则可能会发生此问题
参数
Name | Type |
---|---|
thresholdPriority |
int (see priority filtering) |
thresholdPriorityClassName |
string (see priority filtering) |
namespaces |
(see namespace filtering) |
例子
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingInterPodAntiAffinity":
enabled: true
RemovePodsViolatingNodeAffinity
该策略确保 最终将所有违反节点亲缘关系的node 从节点中删除。节点相似性规则允许Pod指定 requiredDuringSchedulingIgnoredDuringExecution
类型,该类型告诉调度程序在调度Pod时尊重节点相似性,而kubelet忽略节点随时间变化而不再尊重相似性的情况。启用后,该策略requiredDuringSchedulingRequiredDuringExecution
将用作kubelet的临时实现并逐出该kubelet,不再考虑节点亲和力。
例如,在节点A上调度了podA,该Pod满足了调度时的节点亲缘性规则requiredDuringSchedulingIgnoredDuringExecution
。随着时间的流逝,nodeA停止满足该规则。当执行该策略并且存在另一个可用的满足节点亲缘关系规则的节点时,podA被从nodeA中逐出。
参数
Name | Type |
---|---|
nodeAffinityType |
list(string) |
thresholdPriority |
int (see priority filtering) |
thresholdPriorityClassName |
string (see priority filtering) |
namespaces |
(see namespace filtering) |
例子
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingNodeAffinity":
enabled: true
params:
nodeAffinityType:
- "requiredDuringSchedulingIgnoredDuringExecution"
RemovePodsViolatingNodeTaints
此策略可确保删除节点上违反NoSchedule污点的node。例如,存在具有容忍度的pod“ podA”,以容忍key=value:NoSchedule
在受污染节点上计划并运行的污染。如果节点的污点随后被更新/删除,则污点将不再由其容器的容忍度所满足,并将被逐出。
参数
Name | Type |
---|---|
thresholdPriority |
int (see priority filtering) |
thresholdPriorityClassName |
string (see priority filtering) |
namespaces |
(see namespace filtering) |
例子
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingNodeTaints":
enabled: true
RemovePodsViolatingTopologySpreadConstraint
该策略确保 从节点驱逐违反拓扑扩展约束的node。具体而言,它尝试逐出将拓扑域平衡到每个约束的内所需的最小Pod数maxSkew
。此策略至少需要k8s 1.18
版。
参数
Name | Type |
---|---|
thresholdPriority |
int (see priority filtering) |
thresholdPriorityClassName |
string (see priority filtering) |
namespaces |
(see namespace filtering) |
例子
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingTopologySpreadConstraint":
enabled: true
RemovePodsHavingTooManyRestarts
此策略确保从节点中删除重启次数过多的Pod。例如,具有EBS / PD的Pod无法将卷/磁盘附加到实例,则应该将该Pod重新安排到其他节点。它的参数包括podRestartThreshold,它是应将Pod逐出的重新启动次数,以及includingInitContainers,它确定在计算中是否应考虑初始化容器的重新启动。
参数
Name | Type |
---|---|
podRestartThreshold |
int |
includingInitContainers |
bool |
thresholdPriority |
int (see priority filtering) |
thresholdPriorityClassName |
string (see priority filtering) |
namespaces |
(see namespace filtering) |
例子
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsHavingTooManyRestarts":
enabled: true
params:
podsHavingTooManyRestarts:
podRestartThreshold: 100
includingInitContainers: true
PodLifeTime
此策略驱逐早于的podmaxPodLifeTimeSeconds。
您还可以指定podStatusPhases到only具体逐出豆荚StatusPhases,目前该参数仅限于Running和Pending
参数
Name | Type |
---|---|
maxPodLifeTimeSeconds |
int |
podStatusPhases |
list(string) |
thresholdPriority |
int (see priority filtering) |
thresholdPriorityClassName |
string (see priority filtering) |
namespaces |
(see namespace filtering) |
例子
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"PodLifeTime":
enabled: true
params:
podLifeTime:
maxPodLifeTimeSeconds: 86400
podStatusPhases:
- "Pending"
测试
这里部署,我们采用了Job的方式进行直接创建上面的3个资源对象即可,运行成功后我们可以通Descheduler 的 Job 任务的日志(截取了部分):可以看到Descheduler 已经按照我们的预期策略开始进行驱除调度了
kubectl logs descheduler-job-9dkq8 -n kube-system
I1125 00:59:53.756563 1 node.go:45] node lister returned empty list, now fetch directly
I1125 00:59:53.773093 1 duplicates.go:73] Processing node: "ga-k8s-xs1"
I1125 00:59:53.827292 1 duplicates.go:73] Processing node: "ga-k8s-xs10"
.....
.....
I1125 00:59:58.009104 1 lownodeutilization.go:197] Node "ga-k8s-xs13" is under utilized with usage: api.ResourceThresholds{"cpu":28.958333333333332, "memory":25.20574008276515, "pods":40}
I1125 00:59:58.009331 1 lownodeutilization.go:203] Node "ga-k8s-xs5" is appropriately utilized with usage: api.ResourceThresholds{"cpu":75.41666666666667, "memory":55.74897885562279, "pods":40.90909090909091}
I1125 00:59:58.011555 1 lownodeutilization.go:127] Total number of nodes above target utilization: 6
I1125 00:59:58.011590 1 lownodeutilization.go:244] Total capacity to be moved: CPU:6125, Mem:2.88490815488e+10, Pods:22
I1125 00:59:58.011612 1 lownodeutilization.go:245] ********Number of pods evicted from each node:***********
I1125 00:59:58.011628 1 lownodeutilization.go:252] evicting pods from node "ga-k8s-xs8" with usage: api.ResourceThresholds{"cpu":87.91666666666667, "memory":72.50633481772661, "pods":26.363636363636363}
I1125 00:59:58.011863 1 lownodeutilization.go:255] allPods:29, nonRemovablePods:28, removablePods:1
I1125 00:59:58.011884 1 lownodeutilization.go:262] evicting pods based on priority, if they have same priority, they'll be evicted based on QoS tiers
I1125 00:59:58.121775 1 evictions.go:117] Evicted pod: "apigate-656784588c-s5wzw" in namespace "kube-matomo" (LowNodeUtilization)
I1125 00:59:58.121962 1 lownodeutilization.go:302] Evicted pod: "apigate-656784588c-s5wzw"
I1125 00:59:58.122033 1 lownodeutilization.go:315] updated node usage: api.ResourceThresholds{"cpu":83.75, "memory":70.51473082888613, "pods":25.454545454545453}
I1125 00:59:58.122070 1 lownodeutilization.go:267] 1 pods evicted from node "hzxs-qa1-ga-k8s-xs8"
I1125 01:00:00.512397 1 lownodeutilization.go:315] updated node usage: api.ResourceThresholds{"cpu":91.25000000000001, "memory":49.65068744179323, "pods":35.45454545454547}
.....
......
I1125 01:00:11.472646 1 lownodeutilization.go:139] Total number of pods evicted: 22
网友评论