Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >K8s降本增效之Descheduler篇

K8s降本增效之Descheduler篇

作者头像
zouyee
发布于 2023-02-06 02:40:48
发布于 2023-02-06 02:40:48
1.3K00
代码可运行
举报
文章被收录于专栏:Kubernetes GOKubernetes GO
运行总次数:0
代码可运行

在K8s集群治理过程中,常常会因CPU、内存等高使用率状况而形成热点,既影响了当前节点上Pod的稳定运行,也会导致节点发生故障的几率的激增,为了应对集群节热点、负载不均衡等问题,需要动态平衡各个节点之间的资源使用率,因此需要基于节点的相关监控指标,构建集群资源视图

编辑|阎锡叁

接受范围|初级

为了应对集群节点高负载、负载不均衡等问题,需要动态平衡各个节点之间的资源使用率,因此需要基于节点的相关监控指标,构建集群资源视图,从而为下述两种治理方向奠定实现基础:

  • 在 Pod 调度阶段,加入优先将 Pod 调度到资源实际使用率低的节点的节点Score插件
  • 在集群治理阶段,通过实时监控,在观测到节点资源率较高、节点故障、Pod 数量较多等情况时,可以自动干预,迁移节点上的一些 Pod 到利用率低的节点上

针对方向一,可以通过赋予Kubernetes调度器感知集群实际负载的能力,计算资源分配和实际资源利用之间的差距,优化调度策略。

针对方向二,社区给出了Descheduler方案,Descheduler 可以根据一些规则和策略配置来帮助再平衡集群状态,当前项目实现了十余种策略。

注意:Descheduler等方案存在一些与主调度策略不一致的可能性

本文将针对方向二的实现进行详细说明,原理及优化在下一篇,方向一已在前文进行了相关介绍Trimaran: 基于实际负载的K8s调度插件

需求背景

Kubernetes提供了声明式的资源模型,核心组件(调度器、kubelet和控制器)的实现能够满足QoS需求。然而,由于下述一些原因,该模型会导致集群资源使用的不均衡:

  • 用户很难准确评估应用程序的资源使用情况,因而对于Pod的资源配置,无从谈起
  • 用户可能不理解资源模型,从而直接使用Kubernetes默认调度插件(Score)(默认插件不考虑实际节点利用率值)。

虽然调度器可以依托实时资源使用情况,以调度pod,降低集群管理的成本,提高集群的利用率,但集群资源使用的情况是动态变化的,随时会出现不均衡状态,比如某些节点过热,某些节点负载过点的情况,为了能够调节负载的均衡性,可以通过Descheduler对Pod进行迁移,从而达到节点资源的某种均衡,Descheduler使用以下典型场景:

  • Pod利用率变化导致节点负载过点或者过高
  • 节点的上下线
  • 节点标签变动导致Pod的亲和性或反亲和性结果的改变
  • 节点的taint的变更

注意:本文基于commit,版本为v0.25.1。其中HighNodeUtilization、LowNodeUtilization中基于实际节点使用率的功能,尚未实现,相关issue及roadmap,目前相关开发集中在scheduler-plugins的trimaran模块

Descheduler的policy可配,包括可以启用或禁用相关策略。默认情况下,所有策略都是启用的。

policy支持所有策略的通用配置如下所示:

名称

默认值

描述

nodeSelector

nil

限定节点

evictLocalStoragePods

false

运行驱逐配置本地存储的pod

evictSystemCriticalPods

false

会驱逐系统pod,如coredns等

ignorePvcPods

false

配置是否驱逐配置PVC的pod

maxNoOfPodsToEvictPerNode

nil

每个节点驱逐的最大pod数

maxNoOfPodsToEvictPerNamespace

nil

每个ns驱逐的最大pod数

evictFailedBarePods

false

允许驱逐没有owner reference或者处于faild阶段的pod

通过policy定义,每个策略的参数均可配。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
nodeSelector: prod=dev
evictFailedBarePods: false
evictLocalStoragePods: true
evictSystemCriticalPods: true
maxNoOfPodsToEvictPerNode: 40
ignorePvcPods: false
strategies:
  ...

下图提供了大多数策略的可视化过程,以帮助区分如何配置策略。

当前支持以下几种策略:

  • RemoveDuplicates
  • LowNodeUtilization
  • HighNodeUtilization
  • RemovePodsViolatingInterPodAntiAffinity
  • RemovePodsViolatingNodeAffinity
  • RemovePodsViolatingNodeTaints
  • RemovePodsViolatingTopologySpreadConstraint
  • RemovePodsHavingTooManyRestarts
  • PodLifeTime
  • RemoveFailedPods 下文逐一介绍。

Descheduler策略

RemoveDuplicates

这个策略确保同一节点上运行一个与ReplicaSet(RS)、ReplicationController(RC)、StatefulSet或Job相关联的pod。如果存在多个,这些pod将会被驱逐,类似于kube-schduler的反亲和性、打散功能,其为了在集群中打散pod。主要为了确保一些节点发生故障时,保障业务的稳定性。

它提供了一个可选的参数,excludeOwnerKinds,它是一个OwnerRef Kinds的列表。如果一个pod的OwnerRefernce字段有这些类型,该pod将不被驱逐。需要注意的是,通过Deployment创建的pod会被考虑用这个策略驱逐。excludeOwnerKinds参数应包括ReplicaSet,以排除由Deployments创建的pod。

配置参数

Name

Type

excludeOwnerKinds

list(string)

namespaces

参看namespace filtering

thresholdPriority

int (参看 优先级过滤)

thresholdPriorityClassName

string (参看 优先级过滤)

nodeFit

bool (参看 nodeFit过滤)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemoveDuplicates":
    enabled: true
    params:
      removeDuplicates:
        excludeOwnerKinds:
        - "ReplicaSet"
LowNodeUtilization

这个策略找到利用率低(requests不是实际的利用率)的节点,将其他节点驱逐的pod,尽量在该节点重建。这个策略的参数在nodeResourceUtilizationThresholds下配置。

注意:因为当前kube-scheduler也未支持实时资源方式的调度算法,因此可能调度到其他利用率高的节点。

节点的利用率低于多少是由配置的阈值决定的。阈值支持配置cpu、内存、pod数量和扩展资源的百分比(百分比的计算方法是节点上当前请求的资源与可分配的总资源)。

如果一个节点的使用率低于所有(cpu、内存、pod数量和扩展资源)的阈值,该节点就被认定为未充分利用的节点。当前,计算节点资源利用率时只考虑了pods的请求资源(request)。

还有一个可配置的阈值,是targetThresholds,其用于计算那些潜在的节点,从那里可以驱逐pod。如果一个节点的使用量在任何(cpu、内存、pod数量或扩展资源)方面都超过了targetThreshold,那么该节点就被认为是过度利用了。任何在阈值、阈值和targetThresholds之间的节点都被认为是适当的利用,不考虑驱逐。阈值,targetThresholds,也可以用百分比来配置cpu、内存和pod的数量。

这些阈值,thresholds和targetThresholds,可以根据你的集群要求进行调整。需要注意的是,该策略将pod从过度使用的节点(使用率高于targetThresholds的节点)驱逐到使用率不足的节点(使用率低于阈值的节点),如果任何使用率不足的节点或过度使用的节点的数量为零,它将中止驱逐。

此外,该策略还接受一个useDeviationThresholds参数。如果该参数设置为"true",阈值将从所有节点的平均值中扣除,而targetThresholds将被添加到平均值。高于(或低于)该窗口的资源消耗被认为是过度使用(或使用不足)。

注意:节点资源消耗是由pod的请求和限制决定的,而不是实际使用率。选择这种方法是为了与kube-scheduler保持一致,kube-scheduler遵循相同的设计来调度pod到节点上。这意味着Kubelet(或像kubectl top这样的命令)报告的资源使用量可能与计算的消耗量不同,这是因为这些组件报告了实际的使用指标。

配置参数

Name

Type

thresholds

map(string:int)

targetThresholds

map(string:int)

numberOfNodes

int

useDeviationThresholds

bool

thresholdPriority

int 参看priority filtering章节

thresholdPriorityClassName

string 参看priority filtering章节

nodeFit

bool 参看node fit filtering章节

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

支持三种基本的资源类型:Cpu、内存和pod。如果没有指定这些资源类型中的任何一种,它的所有阈值默认为100%,以避免节点从利用不足到利用过度。支持扩展资源,例如,资源类型nvidia.com/gpu被指定GPU节点利用,如果没有配置阈值,将不被计算。thresholds或targetThresholds不能为零,它们必须配置完全相同类型的资源。资源的百分比值的有效范围是[0, 100]。阈值的百分比值不能大于同一资源的targetThresholds。还有一个与LowNodeUtilization策略相关的参数,叫做numberOfNodes。这个参数可以被配置为只有在利用率低的节点数量超过配置值时才激活该策略。这在大型集群中可能很有帮助,因为有几个节点可能经常或在短时间内利用不足。默认情况下,numberOfNodes被设置为0。

HighNodeUtilization

这个策略找到利用率低(requests不是实际的利用率)的节点,并从这些节点上驱逐pod。该策略与节点自动扩展结合使用,旨在帮助触发利用率低的节点的缩减。这个策略必须与调度器的评分策略MostAllocated一起使用。该策略的参数在nodeResourceUtilizationThresholds下配置。

节点的利用率不足由可配置的阈值决定。阈值阈值可以为cpu、内存、pod的数量和扩展资源的百分比进行配置。百分比的计算方法是节点上当前请求的资源与可分配的总资源。对于pods,这意味着节点上的pods数量占该节点设置的pod容量的一部分。

如果一个节点的使用率低于所有(cpu、内存、pod数量和扩展资源)的阈值,该节点就被认为是未充分利用的。目前,计算节点资源利用率时考虑了pods请求资源的要求。任何高于阈值的节点都被认为是适当的利用,不考虑驱逐。

阈值参数可以根据集群规模进行调整。需要注意的是,该策略从利用不足的节点(即使用率低于阈值的节点)驱逐pod,以便可以在适当利用的节点上重新创建。如果任何未充分利用的节点或适当利用的节点的数量为零,该策略将中止。

注意:节点资源消耗是由pod的请求和限制决定的,而不是实际使用。选择这种方法是为了与kube-scheduler保持一致,kube-scheduler遵循相同的设计来调度pod到节点上。这意味着Kubelet(或像kubectl top这样的命令)报告的资源使用量可能与计算的消耗量不同,这是因为这些组件报告了实际的使用指标。

配置参数

Name

Type

thresholds

map(string:int)

numberOfNodes

int

thresholdPriority

int (see priority filtering)

thresholdPriorityClassName

string (see priority filtering)

nodeFit

bool (see node fit filtering)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"HighNodeUtilization":
    enabled: true
    params:
      nodeResourceUtilizationThresholds:
        thresholds:
          "cpu" : 20
          "memory": 20
          "pods": 20

支持三种基本的资源类型:cpu、内存和pod。如果这些资源类型都没有配置,那么阈值均为100%,同时还支持扩展资源,例如,资源类型nvidia.com/gpu被指定GPU节点利用,如果没有配置阈值,将不被计算。资源的百分比值的有效范围是[0, 100]。还有一个与HighNodeUtilization策略相关的参数,叫做numberOfNodes。这个参数可以被配置为只有在利用率低的节点数量超过配置值时才激活该策略。这在大型集群中很有帮助,因为在这些集群中,有几个节点可能经常或在很短的时间内利用不足。默认情况下,numberOfNodes被设置为零。

RemovePodsViolatingInterPodAntiAffinity

该策略可确保从节点中删除违反反亲和性的pod。例如,如果某个节点上有podA,并且podB和podC(在同一节点上运行)具有禁止它们在同一节点上运行的反亲和规则,则podA将被从该节点逐出,以便podB和podC正常运行。当 podB 和 podC 已经运行在节点上后,反亲和性规则就会发现这样的问题。目前,没有与该策略关联的参数。

配置参数

Name

Type

thresholdPriority

int (see priority filtering)

thresholdPriorityClassName

string (see priority filtering)

namespaces

(see namespace filtering)

labelSelector

(see label filtering)

nodeFit

bool (see node fit filtering)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingInterPodAntiAffinity":
    enabled: true
RemovePodsViolatingNodeAffinity

这个策略确保了所有违反节点亲和性的pod最终都会从节点上被驱逐。节点亲和力规则允许pod指定requiredDuringSchedulingIgnoredDuringExecution类型,它告诉调度器在调度pod时要满足节点亲和力,但节点可能随时间变化而不再满足亲和力时,但kubelet会忽略这一变化,当启用该策略时,其作为requiredDuringSchedulingRequiredDuringExecution的临时实现,将不再满足节点亲和力的pod驱逐出该节点。

例如,在节点A上调度有podA,它在调度时满足节点亲和性规则requiredDuringSchedulingIgnoredDuringExecution。随着时间的推移,节点A不再满足该规则,当策略被触发并且有另一个满足节点亲和性规则的节点可用时,podA被从节点A驱逐。

配置参数

Name

Type

nodeAffinityType

list(string)

thresholdPriority

int (see priority filtering)

thresholdPriorityClassName

string (see priority filtering)

namespaces

(see namespace filtering)

labelSelector

(see label filtering)

nodeFit

bool (see node fit filtering)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingNodeAffinity":
  enabled: true
  params:
    nodeAffinityType:
    - "requiredDuringSchedulingIgnoredDuringExecution"
RemovePodsViolatingNodeTaints

这个策略确保在节点上违反NoSchedule污点的pod被移除。例如,有一个pod "podA "具有容忍污点key=value:NoSchedule的容忍度,并在被污点的节点上运行。如果该节点的污点随后被更新/删除,污点就不再满足于其pod的容忍度,将被驱逐出去。

节点污点可以通过指定exceptedTaints的列表排除。如果一个节点污点的键或键=值与exceptedTaints条目相匹配,该污点将被忽略。

例如,excludedTaints条目 "dedicated "将匹配所有键为 "dedicated "的污点,而不考虑其值;excludedTaints条目 "dedicated=special-user "将匹配键为 "dedicated "而值为 "special-user "的污点。

配置参数

Name

Type

excludedTaints

list(string)

thresholdPriority

int (see priority filtering)

thresholdPriorityClassName

string (see priority filtering)

namespaces

(see namespace filtering)

labelSelector

(see label filtering)

nodeFit

bool (see node fit filtering)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingNodeTaints":
  enabled: true
  params:
    excludedTaints:
    - dedicated=special-user # exclude taints with key "dedicated" and value "special-user"
    - reserved # exclude all taints with key "reserved"
RemovePodsViolatingTopologySpreadConstraint

这个策略确保把违反拓扑传播约束的pod从节点上驱逐出去。具体来说,它试图驱逐最小数量的pod,以平衡拓扑域到每个约束的最大打散度。该策略需要k8s 1.18+版本。

默认情况下,该策略只处理硬约束,将参数includeSoftConstraints设置为true时,将包括软性约束。

策略参数labelSelector在平衡拓扑域时不被利用,只在驱逐过程中应用,以确定pod是否可以被驱逐。

配置参数

Name

Type

includeSoftConstraints

bool

thresholdPriority

int (see priority filtering)

thresholdPriorityClassName

string (see priority filtering)

namespaces

(see namespace filtering)

labelSelector

(see label filtering)

nodeFit

bool (see node fit filtering)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingTopologySpreadConstraint":
    enabled: true
    params:
      includeSoftConstraints: false
RemovePodsHavingTooManyRestarts

这个策略可以确保将重启次数过多的pod从节点上驱逐。例如,一个带有EBS/PD的pod不能把卷/磁盘挂到实例上,那么这个pod应该被重新安排到其他节点上。它的参数包括podRestartThreshold,这是一个pod应该被驱逐的重启次数(所有符合条件的容器的总和),以及initContainers,这决定了init容器的重启是否应该被计入该计算中。

配置参数

Name

Type

podRestartThreshold

int

includingInitContainers

bool

thresholdPriority

int (see priority filtering)

thresholdPriorityClassName

string (see priority filtering)

namespaces

(see namespace filtering)

labelSelector

(see label filtering)

nodeFit

bool (see node fit filtering)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsHavingTooManyRestarts":
    enabled: true
    params:
      podsHavingTooManyRestarts:
        podRestartThreshold: 100
        includingInitContainers: true
PodLifeTime

这个策略会驱逐超过maxPodLifeTimeSeconds的pod。

还可以指定podStatusPhases,以便只驱逐具有特定StatusPhases的pod,目前这个参数仅限于运行和待定。

配置参数

Name

Type

maxPodLifeTimeSeconds

int

podStatusPhases

list(string)

thresholdPriority

int (see priority filtering)

thresholdPriorityClassName

string (see priority filtering)

namespaces

(see namespace filtering)

labelSelector

(see label filtering)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"PodLifeTime":
    enabled: true
    params:
      podLifeTime:
        maxPodLifeTimeSeconds: 86400
        podStatusPhases:
        - "Pending"
RemoveFailedPods

这个策略将驱逐处于失败状态阶段的pod。可以提供一个可选的参数来过滤失败的原因。通过设置可选的参数includingInitContainers为true,原因可以扩展到包括InitContainers的原因。可以指定一个可选的参数minPodLifetimeSeconds来驱逐超过指定秒数的pod。最后,可以指定可选的参数excludeOwnerKinds,如果一个pod有任何这些Kinds列为OwnerRef,该pod将不被考虑驱逐。

配置参数

Name

Type

minPodLifetimeSeconds

uint

excludeOwnerKinds

list(string)

reasons

list(string)

includingInitContainers

bool

thresholdPriority

int (see priority filtering)

thresholdPriorityClassName

string (see priority filtering)

namespaces

(see namespace filtering)

labelSelector

(see label filtering)

nodeFit

bool (see node fit filtering)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemoveFailedPods":
    enabled: true
    params:
      failedPods:
        reasons:
        - "NodeAffinity"
        includingInitContainers: true
        excludeOwnerKinds:
        - "Job"
        minPodLifetimeSeconds: 3600
Pods过滤方式

在驱逐Pods的时候,有时并不需要所有Pods都被驱逐,Descheduler提供一些过滤方式。

a. Namespace过滤
  • PodLifeTime
  • RemovePodsHavingTooManyRestarts
  • RemovePodsViolatingNodeTaints
  • RemovePodsViolatingNodeAffinity
  • RemovePodsViolatingInterPodAntiAffinity
  • RemoveDuplicates
  • RemovePodsViolatingTopologySpreadConstraint
  • RemoveFailedPods
  • LowNodeUtilization和HighNodeUtilization

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
  "PodLifeTime":
     enabled: true
     params:
        podLifeTime:
          maxPodLifeTimeSeconds: 86400
        namespaces:
          include:
          - "namespace1"
          - "namespace2"

在例子中,PodLifeTime只在namespace1和namespace2上执行。对于排除字段也是如此。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
  "PodLifeTime":
     enabled: true
     params:
        podLifeTime:
          maxPodLifeTimeSeconds: 86400
        namespaces:
          exclude:
          - "namespace1"
          - "namespace2"
代码语言:javascript
代码运行次数:0
运行
复制

该策略在除namespace1和namespace2之外的所有命名空间上执行。

b. 优先级过滤

所有的策略都能够配置一个优先级阈值,只有在阈值下的pod才能被驱逐。你可以通过设置thresholdPriorityClassName(将阈值设置为给定的优先级类别的值)或thresholdPriority(直接设置阈值)参数来指定这个阈值。默认情况下,该阈值被设置为系统-集群-关键优先级类的值。

注意:将evictSystemCriticalPods设置为 "true "可以完全禁用优先级过滤。

例如,设置 thresholdPriority

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"PodLifeTime":
    enabled: true
    params:
      podLifeTime:
        maxPodLifeTimeSeconds: 86400
      thresholdPriority: 10000

设置thresholdPriorityClassName

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"PodLifeTime":
    enabled: true
    params:
      podLifeTime:
        maxPodLifeTimeSeconds: 86400
      thresholdPriorityClassName: "priorityclass1"

注意: 你不能同时配置thresholdPriority和thresholdPriorityClassName,如果给定的优先级类不存在,descheduler将不会创建它,并会抛出一个错误。

c. 标签过滤

下面的策略可以配置一个标准的kubernetes labelSelector,通过标签过滤pod。如果设置为 "true",在驱逐它们之前,discheduler将考虑符合驱逐标准的pod是否适合在其他节点上。如果一个pod不能被重新安排到其他节点上,它将不会被驱逐。目前,在设置nodeFit为true时,会考虑以下标准。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
      nodeFit: true

请注意,节点适应性过滤参考的是当前的pod规格,而不是它的所有者的规格,因为Descheduler是一个 "尽力而为 "的机制。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"PodLifeTime":
  enabled: true
  params:
    podLifeTime:
      maxPodLifeTimeSeconds: 86400
    labelSelector:
      matchLabels:
        component: redis
      matchExpressions:
        - {key: tier, operator: In, values: [cache]}
        - {key: environment, operator: NotIn, values: [dev]}

d. nodeFit过滤

以下策略接受一个nodeFit参数,可以优化调度。

  • RemoveDuplicates
  • LowNodeUtilization
  • HighNodeUtilization
  • RemovePodsViolatingInterPodAntiAffinity
  • RemovePodsViolatingNodeAffinity
  • RemovePodsViolatingNodeTaints
  • RemovePodsViolatingTopologySpreadConstraint
  • RemovePodsHavingTooManyRestarts
  • RemoveFailedPods

小结

Pod 驱逐机制

当desceduler决定从一个节点上驱逐pod时,它采用了以下一般机制。

  • 关键pod不会被驱逐,比如 priorityClassName 设置为 system-cluster-critical 或 system-node-critical 的 Pod。
  • 不属于ReplicationController、ReplicaSet(Deployment)、StatefulSet或Job的pod(如静态pod等)永远不会被驱逐,因为这些pod不会被重新创建。
  • 与DaemonSets相关的pods永远不会被驱逐。
  • 具有本地存储的Pod永远不会被驱逐(除非设置evictLocalStoragePods为true)。
  • 带有PVC的Pod不会被驱逐(除非设置了ignorePvcPods为true)
  • 在LowNodeUtilization和RemovePodsViolatingInterPodAntiAffinity中,pod是按其优先级从低到高驱逐的,如果它们有相同的优先级,Besteffort 类型的 Pod 要先于 Burstable 和 Guaranteed 类型被驱逐
  • 带有descheduler.alpha.kubernetes.io/evict annotation的pod都可以被驱逐。这个annotation用,可以让用户选择哪些pod被驱逐。
  • 具有非零的DeletionTimestamp的pod默认不会被驱逐
Pod Disruption Budget (PDB)

PodDisruptionBudget能够针对自发的驱逐(即上面提到的通过API发起驱逐)提供保护,通过配置 PDB(PodDisruptionBudget) 对象来避免所有副本同时被删除。

局限性

以下为其他注意项与缺陷:

  • 基于request计算节点负载并不能反映实际情况
  • 驱逐Pod导致应用服务的不稳定,过策略计算出一系列符合要求的 Pod,进行驱逐。好的方面是,descheduler 不会驱逐没有副本控制器的 Pod,不会驱逐带本地存储的 Pod 等,保障在驱逐时,不会导致应用故障。但是使用 client.PolicyV1beta1().Evictions 驱逐 Pod 时,会先删掉 Pod 再重新启动,而不是滚动更新。
  • 其功能在于驱逐而非调度,因资源相关视图与调度器存在差异,可能存在频繁调度驱逐节点

由于笔者时间、视野、认知有限,本文难免出现错误、疏漏等问题,期待各位读者朋友、业界专家指正交流。

参考文献

1.https://github.com/kubernetes-sigs/descheduler

2. https://cloud.tencent.com/developer/article/2050316

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DCOS 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
k8s二次调度
在之前文章中,kube-schedule原理,当中我们说到了k8s原始的调度,有一些不合理性,当时也介绍了一些优先级调度以及自定义调度,下面主要说下这个开源的二次调度工具Descheduler。
SY小站
2020/07/03
1K0
Kubernetes 调度均衡器 Descheduler 使用
从 kube-scheduler 的角度来看,它是通过一系列算法计算出最佳节点运行 Pod,当出现新的 Pod 进行调度时,调度程序会根据其当时对 Kubernetes 集群的资源描述做出最佳调度决定,但是 Kubernetes 集群是非常动态的,由于整个集群范围内的变化,比如一个节点为了维护,我们先执行了驱逐操作,这个节点上的所有 Pod 会被驱逐到其他节点去,但是当我们维护完成后,之前的 Pod 并不会自动回到该节点上来,因为 Pod 一旦被绑定了节点是不会触发重新调度的,由于这些变化,Kubernetes 集群在一段时间内就可能会出现不均衡的状态,所以需要均衡器来重新平衡集群。
我是阳明
2022/02/11
1.3K0
Kubernetes 调度均衡器 Descheduler 使用
通过 Descheduler 实现 Kubernetes 集群均衡
在介绍 Kubernetes 集群均衡器之前我们还是非常有必要再来回顾下 kube-scheduler 组件的概念。我们知道基本上所有的分布式系统都需要一个流程或应用来调度集群中的任务来执行,同样 Kubernetes 也需要这样一个调度器来执行任务,我们熟知的 kube-scheduler 组件就是扮演这个角色的,该组件是作为 Kubernetes 整个控制面板的一部分来运行的,并监听所有未分配节点新创建的 Pod,为其选择一个最合适的节点绑定运行。kube-scheduler 是如何来选择最合适的节点的呢?
我是阳明
2020/06/15
1.4K0
通过 Descheduler 实现 Kubernetes 集群均衡
Descheduler 实现 K8S Pod 二次调度
Kubernetes中的调度是将待处理的pod绑定到节点的过程,由Kubernetes的一个名为kube-scheduler的组件执行。调度程序的决定,无论是否可以或不能调度容器,都由其可配置策略指导,该策略包括一组规则,称为谓词和优先级。调度程序的决定受到其在第一次调度时出现新pod时的Kubernetes集群视图的影响。由于Kubernetes集群非常动态且状态随时间而变化,因此可能需要将已经运行的pod重新调试到其它节点上,已达到节点使用资源平衡。
YP小站
2020/06/04
1.9K0
Descheduler 实现 K8S Pod 二次调度
【K8S专栏】Kubernetes调度管理
在日常工作中,每个机场都有调度室,用来管理飞机应该从哪里降落,停在什么地方。在Kubernetes也有这样的调度器,主要作用就是将Pod安排到合适的节点上。
没有故事的陈师傅
2022/09/15
6980
【K8S专栏】Kubernetes调度管理
kubernetes中资源使用优化之pod重调度
如果你也像我一样遇到上述问题的话,救星来了,那就是kubernetes-sigs/descheduler项目,该项目可以重新平衡资源使用,避免节点利用率不均匀,造成资源空闲和浪费,descheduler根据其策略,找到可以移动的 pod 并驱逐它们。请注意,在当前的实现中,descheduler不会安排被驱逐的pod的替换,而是依赖于默认的kube-scheduler。 项目地址: https://github.com/kubernetes-sigs/descheduler
yxxhero
2022/05/31
1.6K0
kubernetes中资源使用优化之pod重调度
k8s解决pod调度不均衡的问题
k8s是通过sceduler来调度pod的,在调度过程中,由于一些原因,会出现调度不均衡的问题,例如:
dogfei
2020/07/31
16K2
k8s解决pod调度不均衡的问题
17个应该了解的Kubernetes优化
Kubernetes 持续发展,提供可以显著增强集群性能、效率和安全性的新功能和优化。对于高级工程师,掌握这些优化可以带来更强大、更可扩展且更具成本效益的部署。以下是 18 个高级 Kubernetes 节点优化的精选列表,按其在 2024 年的预期实用性和受欢迎程度排序。
云云众生s
2024/03/28
6440
descheduler 二次调度让 Kubernetes 负载更均衡
Kubernetes 调度器的作用是将 Pod 绑定到某一个最佳的节点。为了实现这一功能,调度器会需要进行一系列的筛选和打分。
陈少文
2022/07/18
2K0
descheduler 二次调度让 Kubernetes 负载更均衡
Kubernetes-Pod的重新平衡和碎片整理
默认情况下,Kubernetes不会重新计算和重新平衡工作负载。 您可能会遇到一些节点过度利用的集群,而其他节点只有少量的Pod。 您可以如何解决这个问题呢?
DevOps云学堂
2023/10/07
8400
Kubernetes-Pod的重新平衡和碎片整理
Kubernetes 中 Descheduler 组件的使用与扩展
实例在新建时,调度器可以根据当时集群状态选择最优节点进行调度,但集群内资源使用状况是动态变化的,集群在一段时间内就会出现不均衡的状态,需要 Descheduler 将节点上已经运行的 pods 迁移到其他节点,使集群内资源分布达到一个比较均衡的状态。有以下几个原因我们希望将节点上运行的实例迁移到其他节点:
田飞雨
2022/09/02
1.3K0
Kubernetes 中 Descheduler 组件的使用与扩展
Kubernetes (K8S)中深入理解Pods调度
我们部署的 Pod 是通过集群的自动调度策略来选择节点的,默认情况下调度器考虑的是资源足够,并且负载尽量平均,但是有的时候我们需要能够更加细粒度的去控制 Pod 的调度,比如我们希望一些机器学习的应用只跑在有 GPU 的节点上;但是有的时候我们的服务之间交流比较频繁,又希望能够将这服务的 Pod 都调度到同一个的节点上。这就需要使用一些调度方式来控制 Pod 的调度了,主要有两个概念:亲和性和反亲和性,亲和性又分成节点亲和性(nodeAffinity)和 Pod 亲和性(podAffinity)。
王先森sec
2023/10/17
7900
Crane如何做到利用率提升3倍稳定性还不受损?
陈凯悦,腾讯云高级开发工程师,Crane和SuperEdge项目核心开发。专注于大规模离在线混部和资源调度,目前负责Crane离在线混部和调度相关工作。 颜卫,腾讯高级开发工程师,Crane项目核心开发。专注于Kubernetes大规模集群管理和成本优化,丰富的超大规模集群管理和混部经验。目前负责Crane离在线混部和资源优化相关工作。 作为云平台用户,我们都希望购买的服务器物尽其用,能够达到最大利用率。然而要达到理论上的节点负载目标是很难的,计算节点总是存在一些装箱碎片和低负载导致的闲置资源。下图展示了
腾讯云原生
2022/12/08
1.2K0
Crane如何做到利用率提升3倍稳定性还不受损?
Kubernetes | 集群调度 - ClusterScheduling
Scheduler 是 Kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:
Zkeq
2023/05/14
5000
Kubernetes | 集群调度 - ClusterScheduling
K8s降本增效之VPA上篇
VPA全称VerticalPodAutoscaler,即Pod的横向扩缩,其根据容器资源使用率自动设置CPU和内存的requests及limit,从而允许在节点上进行适当的调度,以便为每个 Pod 提供适当的资源。它既可以缩小过度请求资源的容器,也可以根据其使用情况随时提升资源不足的容量。
zouyee
2023/01/11
1.6K0
【K8s】Kubernetes 服务调度详解
在 Kubernetes 中,服务调度是指 kube-scheduler 组件根据特定的调度算法和策略,将 Pod 分配到最合适的 Node 节点上,以满足应用程序的资源需求和 Kubernetes 集群的资源限制,实现集群资源充分、合理的利用。
行者Sun
2024/09/02
4570
【K8s】Kubernetes 服务调度详解
Kubernetes之调度篇
这边肯定会有其他场景也会有对pod的调度有特殊要求,这边只是列举了其中几个情况,对于上述遇到的情况我们需要怎么处理,其实k8s给我们提供了丰富的调度策略来满足我们的需求。下面我们来一一说下这些调度策略。
聂伟星
2020/08/25
1.6K0
k8s中pod的状态包括_k8s pod状态
可以在根容器上设置Ip地址,其它容器都共享此ip,以实现Pod内部的网路通信,同时外部服务要访问容器也可以通过此ip
全栈程序员站长
2022/09/22
2.4K0
k8s中pod的状态包括_k8s pod状态
K8s调度策略
在K8s中,调度是指将Pod放置到合适的节点上。调度器通过 K8s 的监测机制来发现集群中新创建且尚未被调度到节点上的Pod。 调度器会将所发现的每一个未调度的Pod调度到一个合适的节点上来运行。
谢公子
2023/02/27
1.1K0
K8s调度策略
k8s实践(14)--scheduler调度器和pod调度策略
k8s实践(10) -- Kubernetes集群运行原理详解 介绍过kube-scheduler。
黄规速
2024/01/08
4K0
k8s实践(14)--scheduler调度器和pod调度策略
相关推荐
k8s二次调度
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验