Kubernetes调度管理
# 基本介绍
在日常工作中,每个机场都有调度室,用来管理飞机应该从哪里降落,停在什么地方。在 Kubernetes 也有这样的调度器,主要作用就是将 Pod 安排到合适的节点上。
Kubernetes 中的调度器是 kube-scheduler,起工作流程如下:
- 在集群中所有 Node 中,根据调度算法挑选出可以运行该 Pod 的所有 Node;
- 在上一步的基础上,再根据调度算法给筛选出的 Node 进行打分,筛选出分数最高的 Node 进行调度;
- 将 Pod 的 spec.nodeName 填上调度结果的 Node 名字;
其原理图如下:
[[附件/images/20e05099be08d7fe9f69c855e66b05fc_MD5.jpeg|Open: 1573178213038-f29ec980-dff4-4b92-a3f4-4deea9659c83.png]] ![[附件/images/20e05099be08d7fe9f69c855e66b05fc_MD5.jpeg]]
由上图可知,Kubernetes 的调度器核心是两个相互独立的控制循环。
# 1、Informer Path
其主要作用是启动一个 Informer 来监听 Etcd 中 Pod,Node,Service 等与调度器相关的 API 对象的变化。当一个 Pod 被创建出来后,就被通过 Informer Handler 将待调度的 Pod 放入调度队列中,默认情况下,Kubernetes 的调度策略是一个优先级队列,并且当集群信息发生变化的时候,调度器还会对调度队列里的内容进行一些特殊操作。而且 Kubernetes 的默认调度器还负责对调度器缓存(scheduler cache)进行更新,以执行调度算法的执行效率。
# 2、Scheduler Parh
其主要逻辑是不断从队列中出一个 Pod,然后调用 Predicates 进行过滤,然后得到一组 Node(也就是可运行 Pod 的所有 Node 信息,这些信息都是来自 scheduler cache),接下来调用 Priorities 对筛选出的 Node 进行打分,然后分数最高的 Node 会作为本次调度选择的对象。调度完成后,调度器需要将 Pod 的 spec.nodeName 的值修改为调度的 Node 名字,这个步骤称为 Bind。
但是在 Bind 阶段,Kubernetes 默认调度器只会更新 scheduler cache 中的信息,这种基于乐观假设的 API 对象更新方式被称为 Assume。在 Assume 之后,调度器才会向 API Server 发起更新 Pod 的请求,来真正完成 Bind 操作。如果本次 Bind 失败,等到 scheduler cache 更新之后又会恢复正常。
正是由于有 Assume 的原因,当一个 Pod 完成调度需要在某个 Node 节点运行之前,kubelet 还会进行一部 Admit 操作来验证该 Pod 是否能够运行在该 Node 上,作为 kubelet 的二次验证。
# 常用的预算策略有:
CheckNodeCondition
GeneralPredication:
- HostName,
- PodFitsHostPort,
- MatchNodeSelector,
- PodFitsResources
NoDiskConflict
# 优先级和抢占机制
正常情况下,当一个 Pod 调度失败后,它会被搁置起来,直到 Pod 被更新,或者集群状态发生变化,调度器才会对这个 Pod 进行重新调度。但是有的时候我们不希望一个高优先级的 Pod 在调度失败就被搁置,而是会把某个 Node 上的一些低优先级的 Pod 删除,来保证高优先级的 Pod 可以调度成功。
Kubernetes 中优先级是通过 ProrityClass 来定义,如下:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for high priority service pods only."
2
3
4
5
6
7
其中的 value 就是优先级数值,数值越大,优先级越高。优先级是一个 32bit 的整数,最大值不超过 10 亿,超过 10 亿的值是被 Kubernetes 保留下来作为系统 Pod 使用的,就是为了保证系统 Pod 不会被抢占。另外如果 globalDefault 的值设置为 true 的话表明这个 PriorityClass 的值会成为系统默认值,如果是 false 就表示只有在申明这个 PriorityClass 的 Pod 才会拥有这个优先级,而对于其他没有申明的,其优先级为 0。
如下定义 Pod 并定义优先级:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
priorityClassName: high-priority
2
3
4
5
6
7
8
9
10
11
12
上面的 PriotiryClassName 就是定义我们的 PriorityClass,当这个 Pod 提交给 Kubernetes 之后,Kubernetes 的 PriorityAdmissionController 会自动将这个 Pod 的 spec.priority 字段设置为我们定义的值。而当这个 Pod 拥有这个优先级之后,高优先级的 Pod 就可能比低优先级的 Pod 先出队,从而尽早完成调度。
而当一个高优先级的 Pod 调度失败后,其抢占机制就会被触发,这时候调度器就会试图从当前的集群中寻找一个节点,使得这个节点上的一个或多个低优先级的 Pod 被删除,然后这个高优先级的 Pod 就可以被调度到这个节点上。
当抢占发生时,这个高优先级 Pod 并不会立即调度到即将抢占的节点上,调度器只会将这个 Pod 的 spec.nominatedNodeName 的值设置为被抢占节点的 Node 名字,然后这个 Pod 会重新进入下一个调度周期,然后会在这个周期内决定这个 Pod 被调度到哪个节点上。在这个重新调度期间,如果有一个更高的优先级 Pod 也要抢占这个节点,那么调度器就会清空原 Pod 的 nominatedNodeName 的值,而更高优先级的 Pod 将会抢占这个值。
实现原理:
Kubernetes 用两个队列来实现抢占算法:ActiveQ 和 unschedulableQ。
- ActiveQ:凡是在 ActiveQ 里的 Pod,都是下一个周期需要调度的对象,所以当 Kubernetes 创建一个新的 Pod,这个 Pod 就会被放入 ActiveQ 里;
- unschedulableQ:专门用来存放调度失败的 Pod;
那么如果一个 Pod 调度失败,调度器就会将其放入 unschedulableQ 里,然后调度器会检查这个调度失败的原因,分析并确认是否可以通过抢占来解决此次调度问题,如果确定抢占可以发生,那么调度器就会把自己缓存的所有信息都重新复制一份,然后使用这个副本来模拟抢占过程。如果模拟通过,调度器就会真正开始抢占操作了:
- 调度器会检查牺牲者列表,清空这些 Pod 所携带的 nominatedNodeName 字段;
- 调度器会把抢占者的 nominatedNodeName 的字段设置为被抢占的 Node 名字;
- 调度器会开启 Goroutine,同步的删除牺牲者;
接下来调度器就会通过正常的调度流程,把抢占者调度成功。在这个过程中,调度器会对这个 Node,进行两次 Predicates 算法:
- 假设上述抢占者已经运行在这个节点上,然后运行 Predicates 算法;
- 调度器正常执行 Predicates 算法;
只有上述者两个都通过的情况下,这个 Node 和 Pod 才会被 绑定。
# 高级调度
上面介绍的是 Kubernetres 默认的调度策略,有时候默认的调度策略不能满足我们的需求,比如想把 Pod 调度到指定的节点,或者不让某些节点调度 Pod。这时候就要用到更高级的调度策略,主要有如下几种:
- nodeSelector
- nodeName
- nodeAffinity
- podAffinity
- podAntiAffinity
- 污点调度
# nodeSelector
nodeSelector 也可以叫做节点选择器,其原理是通过在节点上定义 label 标签,然后 Pod 中指定选择这些标签,让 Pod 能够调度到指定的节点上。
比如给 kk-node01 指定 env=uat 标签,命令如下:
kubectl label nodes kk-node01 env=uat
现在在 Pod 的 YAML 清单中配置 nodeSelector,如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeselector
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
nodeSelector:
env: uat
2
3
4
5
6
7
8
9
10
这样,该 Pod 就会调度到 kk-node01 节点上,如果该 Pod 指定为 env=prod,则调度不到 kk-node01 节点。
# nodeName
nodeName 也是节点选择器,和 nodeSelector 不同之处在于 nodeName 是直接指定节点名,这属于强调度,定义方式如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodename
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
nodeName: kk-node01 ## 节点名字
2
3
4
5
6
7
8
9
# nodeAffinity
nodeAffinity 叫做节点亲和性调度,其调度方式比 nodeSelector 和 nodeName 更强大。
目前,nodeAffinity 支持两种调度策略:
- preferredDuringSchedulingIgnoredDuringExecution
- requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution 表示如果有 Node 匹配,则优先调度到该 Node,如果没有,可以根据配置调度到其他节点。requiredDuringSchedulingIgnoredDuringExecution 则表示必须满足条件的节点才允许调度。
定义 preferredDuringSchedulingIgnoredDuringExecution 的例子如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-preferred
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: disktype
operator: In
values: ["ssd", "harddisk"]
weight: 60
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
requiredDuringSchedulingIgnoredDuringExecution 的例子如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-required
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values: ["ssd", "harddisk"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
其中,operator 支持 In,NotIn, Exists, DoesNotExist. Gt, and Lt。
# podAffinity
上面介绍的 nodeSelector,nodeName,nodeAffinity 都是针对节点的,下面介绍的 podAffinity 和 podAntiAffinity 则是针对 Pod。
podAffinity 表示 Pod 亲和性调度,意识就是把 Pod 调度到与它比较紧密的 Pod 上,如下:
apiVersion: v1
kind: Pod
metadata:
name: fronted
labels:
app: myapp
row: fronted
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
name: backend
labels:
app: db
row: backend
spec:
containers:
- name: db
image: busybox
imagePullPolicy: IfNotPresent
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values: ["myapp"]
topologyKey: kubernetes.io/hostname
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
这表示把后端 pod 和前端 pod 调度在一起。
podAffinity 也有 preferredDuringSchedulingIgnoredDuringExecution 和 requiredDuringSchedulingIgnoredDuringExecution,也就是硬亲和和软亲和,其使用情况和 nodeAffinity 一样。
# podAntiAffinity
上面介绍了 pod 的亲和性,这里介绍的 podAntiAffinity 则是 Pod 的反亲和性,也就是说不将这类 Pod 调度到一起。在日常工作中,这种亲和性使用频率还比较高。微服务很少有单 Pod,基本都是多个 Pod,为了提高应用的高可用,不会将同应用的多个 Pod 调度到同一台机器上,这时候就要用到 podAntiAffinity,如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname
containers:
- name: nginx
image: nginx
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 污点调度
在 Kubernetes 中,有些节点自带污点 ,比如 Master 节点,这类节点,如果 Pod 没有配置容忍污点,则这些 Pod 不会调度到这类节点上。
在实际中,污点调度也是非常有用的,有些场景某些节点只允许某些项目组的 Pod 允许,比如大数据项目是一些高 IO 项目,不想和其他普通项目混合在一起,而其他项目如果使用标签选择器配置部署又比较麻烦,这时候就可以使用污点选择器。
我们可以通过kubectl explain node.spec.taints
来查看污点相关的配置信息:
kubectl explain node.spec.taints
KIND: Node
VERSION: v1
RESOURCE: taints <[]Object>
DESCRIPTION:
If specified, the node's taints.
The node this Taint is attached to has the "effect" on any pod that does
not tolerate the Taint.
FIELDS:
effect <string> -required-
Required. The effect of the taint on pods that do not tolerate the taint.
Valid effects are NoSchedule, PreferNoSchedule and NoExecute.
Possible enum values:
- `"NoExecute"` Evict any already-running pods that do not tolerate the
taint. Currently enforced by NodeController.
- `"NoSchedule"` Do not allow new pods to schedule onto the node unless
they tolerate the taint, but allow all pods submitted to Kubelet without
going through the scheduler to start, and allow all already-running pods to
continue running. Enforced by the scheduler.
- `"PreferNoSchedule"` Like TaintEffectNoSchedule, but the scheduler tries
not to schedule new pods onto the node, rather than prohibiting new pods
from scheduling onto the node entirely. Enforced by the scheduler.
key <string> -required-
Required. The taint key to be applied to a node.
timeAdded <string>
TimeAdded represents the time at which the taint was added. It is only
written for NoExecute taints.
value <string>
The taint value corresponding to the taint key.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
其中 effect 定义对 Pod 的排斥效果:
- NoSchdule:仅影响调度过程,对现存在的 Pod 不产生影响;
- NoExecute:不仅影响调度,而且还影响现存 Pod,不容忍的 Pod 对象将被驱逐;
- PreferNoSchedule:软排斥,不是完全禁止 Pod 调度;
如果要给节点添加污点,则如下:
kubectl taint nodes kk-node01 node-type=dev:NoSchedule
给节点 kk-node01 增加一个污点,它的键名是 node-type,键值是 dev,效果是 NoSchedule。 这表示只有拥有和这个污点相匹配的容忍度的 Pod 才能够被分配到 kk-node01 这个节点。
如果要删除污点,则使用如下命令:
kubectl taint nodes kk-node01 node-type=dev:NoSchedule-
如果要配置容忍污点,则如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
tolerations:
- key: "node-type"
operator: Equal
value: dev
effect: NoSchedule
tolerationSeconds: 20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
operator 支持Equal
和Exists
,默认是Equal
。
如果是 Equal,表示污点的键值需要一致,如果使用 Exists,则表示只要存在该键的污点,比如:
tolerations:
- key: "key1"
operator: "Exists"
effect: "NoSchedule"
2
3
4
该配置表示只要匹配容忍度,并且 key1 的健存在即可调度。
如果一个容忍度的 key 为空且 operator 为 Exists, 表示这个容忍度与任意的 key、value 和 effect 都匹配,即这个容忍度能容忍任何污点。
如果 effect 为空,则可以与所有键名 key1 的效果相匹配。
你可以给一个节点添加多个污点,也可以给一个 Pod 添加多个容忍度设置。 Kubernetes 处理多个污点和容忍度的过程就像一个过滤器:从一个节点的所有污点开始遍历, 过滤掉那些 Pod 中存在与之相匹配的容忍度的污点。余下未被过滤的污点的 effect 值决定了 Pod 是否会被分配到该节点,特别是以下情况:
- 如果未被忽略的污点中存在至少一个 effect 值为 NoSchedule 的污点, 则 Kubernetes 不会将 Pod 调度到该节点。
- 如果未被忽略的污点中不存在 effect 值为 NoSchedule 的污点, 但是存在 effect 值为 PreferNoSchedule 的污点, 则 Kubernetes 会 尝试 不将 Pod 调度到该节点。
- 如果未被忽略的污点中存在至少一个 effect 值为 NoExecute 的污点, 则 Kubernetes 不会将 Pod 调度到该节点(如果 Pod 还未在节点上运行), 或者将 Pod 从该节点驱逐(如果 Pod 已经在节点上运行)。
例如,假设你给一个节点添加了如下污点
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule
2
3
假定有一个 Pod,它有两个容忍度:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
2
3
4
5
6
7
8
9
在这种情况下,上述 Pod 不会被调度到上述节点,因为其没有容忍度和第三个污点相匹配。 但是如果在给节点添加上述污点之前,该 Pod 已经在上述节点运行, 那么它还可以继续运行在该节点上,因为第三个污点是三个污点中唯一不能被这个 Pod 容忍的。
通常情况下,如果给一个节点添加了一个 effect 值为 NoExecute 的污点, 则任何不能忍受这个污点的 Pod 都会马上被驱逐,任何可以忍受这个污点的 Pod 都不会被驱逐。 但是,如果 Pod 存在一个 effect 值为 NoExecute 的容忍度指定了可选属性 tolerationSeconds 的值,则表示在给节点添加了上述污点之后, Pod 还能继续在节点上运行的时间。例如:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
2
3
4
5
6
这表示如果这个 Pod 正在运行,同时一个匹配的污点被添加到其所在的节点, 那么 Pod 还将继续在节点上运行 3600 秒,然后被驱逐。 如果在此之前上述污点被删除了,则 Pod 不会被驱逐。
# 重新调度
在 Kubernetes 中,kube-scheduler 负责将 Pod 调度到合适的 Node 上,但是 Kubernetes 是一个非常动态的,高度弹性的环境,有时候会造成某一个或多个节点 pod 数分配不均,比如:
- 一些节点利用率低下或过度使用
- 添加删除标签或添加删除污点,pod 或 Node 亲和性改变等造成原调度不再满足
- 一些节点故障,其上运行的 Pod 调度到其他节点
- 新节点加入集群
由于以上种种原因,可能导致多个 Pod 运行到不太理想的节点,而整个 K8S 集群也会处于一段时间不均衡的状态,这时候就需要重新平衡集群。Descheduler 就是这样一个项目。
Descheduler 可以根据一些规则配置来重新平衡集群状态,目前支持的策略有:
- RemoveDuplicates
- LowNodeUtilization
- RemovePodsViolatingInterPodAntiAffinity
- RemovePodsViolatingNodeAffinity
- RemovePodsViolatingNodeTaints
- RemovePodsViolatingTopologySpreadConstraint
- RemovePodsHavingTooManyRestarts
- PodLifeTime
这些策略可以启用,也可以关闭,默认情况下,所有策略都是启动的。
另外,还有一些通用配置,如下:
- nodeSelector:限制要处理的节点
- evictLocalStoragePods: 驱除使用 LocalStorage 的 Pods
- ignorePvcPods: 是否忽略配置 PVC 的 Pods,默认是 False
- maxNoOfPodsToEvictPerNode:节点允许的最大驱逐 Pods 数
由于我集群版本是 1.24.2,所以安装 descheduler v0.24 版本。
(1)下载对应的 Helm chart,我这里选择的是 0.24 版本
wget https://github.com/kubernetes-sigs/descheduler/releases/download/descheduler-helm-chart-0.24.0/descheduler-0.24.0.tgz
(2)如果可以科学上网,直接使用以下命令部署即可。
helm install descheduler .
如果不能科学上网,就替换镜像,修改value.yaml
里的镜像信息,如下:
image:
repository: registry.cn-hangzhou.aliyuncs.com/coolops/descheduler
## Overrides the image tag whose default is the chart version
tag: "v0.24.0"
pullPolicy: IfNotPresent
2
3
4
5
然后再执行安装命令。
安装完成过后,会配置默认的调度策略,如下:
apiVersion: v1
data:
policy.yaml: |
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
LowNodeUtilization:
enabled: true
params:
nodeResourceUtilizationThresholds:
targetThresholds:
cpu: 50
memory: 50
pods: 50
thresholds:
cpu: 20
memory: 20
pods: 20
RemoveDuplicates:
enabled: true
RemovePodsViolatingInterPodAntiAffinity:
enabled: true
RemovePodsViolatingNodeAffinity:
enabled: true
params:
nodeAffinityType:
- requiredDuringSchedulingIgnoredDuringExecution
RemovePodsViolatingNodeTaints:
enabled: true
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: descheduler
meta.helm.sh/release-namespace: default
creationTimestamp: "2022-08-02T03:06:57Z"
labels:
app.kubernetes.io/instance: descheduler
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: descheduler
app.kubernetes.io/version: 0.24.0
helm.sh/chart: descheduler-0.24.0
name: descheduler
namespace: default
resourceVersion: "894636"
uid: 4ab2e628-9404-4e52-bd88-615f5e096d90
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
其中配置了:
- LowNodeUtilization:设置了 cpu\内存\pod 水位,thresholds 表示未充分利用,targetThresholds 表示过度使用
- RemoveDuplicates:开启同节点只有一个 Pod 运行
- RemovePodsViolatingInterPodAntiAffinity:删除违反亲和性的 Pod
- RemovePodsViolatingNodeAffinity:删除不满足 Node 亲和性的 Pod
- RemovePodsViolatingNodeTaints:删除不被 Node 污点容忍的 Pod
并且会创建一个 CronJob,周期性的执行调度均衡。
apiVersion: batch/v1
kind: CronJob
metadata:
annotations:
meta.helm.sh/release-name: descheduler
meta.helm.sh/release-namespace: default
creationTimestamp: "2022-08-02T03:06:57Z"
generation: 1
labels:
app.kubernetes.io/instance: descheduler
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: descheduler
app.kubernetes.io/version: 0.24.0
helm.sh/chart: descheduler-0.24.0
name: descheduler
namespace: default
resourceVersion: "898221"
uid: e209e498-71cb-413f-97a9-372aea5442bc
spec:
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 1
jobTemplate:
metadata:
creationTimestamp: null
spec:
template:
metadata:
annotations:
checksum/config: 5efec14c3638fa4028e25f3fa067758f13dcae442fe711439c7d0b2e9913d41e
creationTimestamp: null
labels:
app.kubernetes.io/instance: descheduler
app.kubernetes.io/name: descheduler
name: descheduler
spec:
containers:
- args:
- --policy-config-file
- /policy-dir/policy.yaml
- --v
- "3"
command:
- /bin/descheduler
image: registry.cn-hangzhou.aliyuncs.com/coolops/descheduler:v0.24.0
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10258
scheme: HTTPS
initialDelaySeconds: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: descheduler
resources:
requests:
cpu: 500m
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsNonRoot: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /policy-dir
name: policy-volume
dnsPolicy: ClusterFirst
priorityClassName: system-cluster-critical
restartPolicy: Never
schedulerName: default-scheduler
securityContext: {}
serviceAccount: descheduler
serviceAccountName: descheduler
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 420
name: descheduler
name: policy-volume
schedule: '*/2 * * * *'
successfulJobsHistoryLimit: 3
suspend: false
status:
lastScheduleTime: "2022-08-02T03:28:00Z"
lastSuccessfulTime: "2022-08-02T03:28:03Z"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
该 Job 会每 2 分钟执行一次均衡调度。
# 总结
Kubernetes 的调度策略是非常复杂的,里面有许多复杂的算法,这里介绍的只是一些常用的调度策略,足够满足日常使用。如果想更深入的研究可以多看看官方文档以及源码。