k8s基于Descheduler的二次调度

前言

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容