K8s 如何实现跨集群节点均匀调度分布Pod(Pod拓扑分布约束)| 运维进阶
K8s 如何实现跨集群节点均匀调度分布Pod(Pod拓扑分布约束)| 运维进阶
talkwithtrend
talkwithtrend.com社区(即twt社区)官方公众号,持续发布优秀社区原创内容。内容深度服务企业内各方向的架构师、运维主管、开发和运维工程师等IT专业岗位人群,让您时刻和国内企业IT同行保持信息同步。
【作者】山河已无恙, RHCE、CKA认证,多家平台签约作者,持续分享云原生、Linux 方面的技术干货。兴趣是吃饭,喜欢吃饱了晒太阳。
Pod 调度的简单介绍
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─
$kubectl
get nodes
NAME STATUS ROLES AGE VERSION
vms155.liruilongs.github.io Ready <none> 54d v1.22.2
vms156.liruilongs.github.io Ready <none> 54d v1.22.2
vms81.liruilongs.github.io Ready control-plane,master 378d v1.22.2
vms82.liruilongs.github.io Ready <none> 378d v1.22.2
vms83.liruilongs.github.io Ready <none> 378d v1.22.2
通过帮助手册可以简单了解下
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─
$kubectl
explain pod.spec.topologySpreadConstraints
KIND: Pod
VERSION: v1
RESOURCE: topologySpreadConstraints <[]Object>
DESCRIPTION:
TopologySpreadConstraints describes how a group of pods ought to spread
across topology domains. Scheduler will schedule pods
in
a way
which
abides
by the constraints. All topologySpreadConstraints are ANDed.
TopologySpreadConstraint specifies how to spread matching pods among the
given topology.
。。。。。
如何实现跨节点均匀分布 Pod
在定义 Pod 的yaml 资源文件中,可以定义一个或多个 topologySpreadConstraints 条目以指导 kube-scheduler 如何将每个新来的 Pod 与跨集群的现有 Pod 相关联。从而实现 Pod 的均匀调度,这些字段包括(1.22 版本)
apiVersion:
v1
kind:
Pod
metadata:
name:
example-pod
spec:
# 配置一个拓扑分布约束
topologySpreadConstraints:
-
maxSkew:
<integer>
topologyKey:
<string>
whenUnsatisfiable:
<string>
labelSelector:
<object>
### 其他 Pod 字段置于此处
在最新的版本中提供了其他的一些字段
---
apiVersion:
v1
kind:
Pod
metadata:
name:
example-pod
spec:
# 配置一个拓扑分布约束
topologySpreadConstraints:
-
maxSkew:
<integer>
minDomains:
<integer>
# 可选;自从 v1.25 开始成为 Beta
topologyKey:
<string>
whenUnsatisfiable:
<string>
labelSelector:
<object>
matchLabelKeys:
<list>
# 可选;自从 v1.25 开始成为 Alpha
nodeAffinityPolicy:
[Honor|Ignore]
# 可选;自从 v1.26 开始成为 Beta
nodeTaintsPolicy:
[Honor|Ignore]
# 可选;自从 v1.26 开始成为 Beta
### 其他 Pod 字段置于此处
具体通过这些字段如何配置,先来看一个 Demo
pod 拓扑约束依赖于 节点标签 来识别每个工作节点的所在的 拓扑域 。这里为了以均匀的方式在所有集群工作节点上均匀的分布 Pod,我们使用 k8s 集群默认自带的节点主机名节点标签作为拓扑域,可以保证每个节点都在自己唯一的拓扑域中。
拓扑约束会基于指定的标签来做为拓扑域,这里通过 kubernetes.io/hostname 的 values 作为拓扑域。
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─
$kubectl
get node --label-columns kubernetes.io/hostname
NAME STATUS ROLES AGE VERSION HOSTNAME
vms155.liruilongs.github.io Ready <none> 54d v1.22.2 vms155.liruilongs.github.io
vms156.liruilongs.github.io Ready <none> 54d v1.22.2 vms156.liruilongs.github.io
vms81.liruilongs.github.io Ready control-plane,master 378d v1.22.2 vms81.liruilongs.github.io
vms82.liruilongs.github.io Ready <none> 378d v1.22.2 vms82.liruilongs.github.io
vms83.liruilongs.github.io Ready <none> 378d v1.22.2 vms83.liruilongs.github.io
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$
spec.topologySpreadConstaints 定义为
apiVersion:
v1
kind:
Pod
metadata:
name:
example-pod
spec:
# 配置一个拓扑分布约束
topologySpreadConstraints:
-
maxSkew:
1
# 以绝对均匀的方式分配 POD
topologyKey:
kubernetes.io/hostname
#使用主机名这个标签作为拓扑域
whenUnsatisfiable:
ScheduleAnyway
#始终调度 pod,即使它不能满足 pod 的均匀分布
labelSelector:
<object>
#作用于匹配这个选择器的 Pod
### 其他 Pod 字段置于此处
涉及多 pod 调度,所以我们需要创建一个 deploy ,同时创建一个命名空间。具体的资源文件
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$cat
liruilong-topo-namespace.yaml
apiVersion:
v1
kind:
Namespace
metadata:
name:
liruilong-topo-namespace
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$cat
deploy.yaml
apiVersion:
apps/v1
kind:
Deployment
metadata:
name:
liruilong
spec:
replicas:
10
template:
spec:
topologySpreadConstraints:
-
maxSkew:
1
topologyKey:
kubernetes.io/hostname
whenUnsatisfiable:
ScheduleAnyway
labelSelector:
matchLabels:
app:
liruilong
containers:
-
name:
pause
image:
registry.aliyuncs.com/google_containers/pause:3.5
为了方便 Demo ,我们使用 kustomize 来整合 yaml 文件。并且配置一个通用的标签。
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$cat
kustomization.yaml
namespace:
liruilong-topo-namespace
commonLabels:
app:
liruilong
resources:
-
liruilong-topo-namespace.yaml
-
deploy.yaml
生成的 yaml 文件为:
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$kubectl
kustomize
./
apiVersion:
v1
kind:
Namespace
metadata:
labels:
app:
liruilong
name:
liruilong-topo-namespace
---
apiVersion:
apps/v1
kind:
Deployment
metadata:
labels:
app:
liruilong
name:
liruilong
namespace:
liruilong-topo-namespace
spec:
replicas:
10
selector:
matchLabels:
app:
liruilong
template:
metadata:
labels:
app:
liruilong
spec:
containers:
-
image:
registry.aliyuncs.com/google_containers/pause:3.5
name:
pause
topologySpreadConstraints:
-
labelSelector:
matchLabels:
app:
liruilong
maxSkew:
1
topologyKey:
kubernetes.io/hostname
whenUnsatisfiable:
ScheduleAnyway
应用生成的 yaml 文件,为了方便,顺便切一下命名空间
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
apply -k ./
namespace/liruilong-topo-namespace created
deployment.apps/liruilong created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
config
set
-context $(kubectl config current-context) --namespace=liruilong-topo-namespace
Context
"kubernetes-admin126459646@kubernetes"
modified.
查看 pod 分布,master 节点设置了污点,所以不调度,剩下的 4 个工作节点,上面的副本数为 10,所以均匀分布为 [ 2 2 3 3 ] ,这里实际上是利用了 whenUnsatisfiable: ScheduleAnyway 的配置,即不管如何都会发生调度,因为 master 上没有调度,所有是 0,但是其他节点为 2,3 即不符合 maxSkew 设置的 1,简单理解 maxSkew 即 pod 在节点分布的差值不能超过的值。
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-547cf79f6f-2mw8f 1/1 Running 0 8m2s 10.244.171.150 vms82.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-4b687 1/1 Running 0 8m2s 10.244.217.21 vms155.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-68nmv 1/1 Running 0 8m2s 10.244.70.60 vms83.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-8n8zc 1/1 Running 0 8m2s 10.244.171.191 vms82.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-cgk9k 1/1 Running 0 8m2s 10.244.70.27 vms83.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-gpx4l 1/1 Running 0 8m2s 10.244.217.22 vms155.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-j4rk7 1/1 Running 0 8m2s 10.244.194.77 vms156.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-t4fhr 1/1 Running 0 8m2s 10.244.194.76 vms156.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-wndvb 1/1 Running 0 8m2s 10.244.194.78 vms156.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-zjnp9 1/1 Running 0 8m2s 10.244.217.20 vms155.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
需要注意的是,缩减 Deployment 并不能保证均匀分布,并可能导致 Pod 分布不平衡。但是可以使用 Descheduler,或者销毁重建的方式重新平衡 Pod 分布。看下 Demo
这是添加一个补丁文件,修改副本数为 4
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$cat
increase_replicas.yaml
apiVersion:
apps/v1
kind:
Deployment
metadata:
name:
liruilong
spec:
replicas:
4
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$cat
kustomization.yaml
namespace:
liruilong-topo-namespace
commonLabels:
app:
liruilong
resources:
-
liruilong-topo-namespace.yaml
-
deploy.yaml
patchesStrategicMerge:
-
increase_replicas.yaml
重新应用,会发现 pod 的调度完全变成了非均匀,即缩减副本数并不会发生重新的 Pod 均匀分布。
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
apply -k ./
namespace/liruilong-topo-namespace unchanged
deployment.apps/liruilong configured
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-547cf79f6f-2mw8f 1/1 Running 0 32m 10.244.171.150 vms82.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-68nmv 1/1 Running 0 32m 10.244.70.60 vms83.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-8n8zc 1/1 Running 0 32m 10.244.171.191 vms82.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-cgk9k 1/1 Running 0 32m 10.244.70.27 vms83.liruilongs.github.io <none> <none>
这要如果希望均匀分布,要不使用工具,要不只能重新部署,下面为重新部署
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
delete -k ./
namespace
"liruilong-topo-namespace"
deleted
deployment.apps
"liruilong"
deleted
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
apply -k ./
namespace/liruilong-topo-namespace created
deployment.apps/liruilong created
重新部署可以发现 pod 均匀分布,四个工作节点各部署一个 [1 1 1 1] 。
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-547cf79f6f-25c4b 1/1 Running 0 4s 10.244.171.180 vms82.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-2qhmh 1/1 Running 0 4s 10.244.217.25 vms155.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-8qmbc 1/1 Running 0 4s 10.244.194.81 vms156.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-gbw9f 1/1 Running 0 4s 10.244.70.23 vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
修改节副本数为 8 ,可以看到当前 pod 分布为 [ 2 2 2 2 ]
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$vim
increase_replicas.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
apply -k ./
namespace/liruilong-topo-namespace unchanged
deployment.apps/liruilong configured
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-547cf79f6f-25c4b 1/1 Running 0 85s 10.244.171.180 vms82.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-2qhmh 1/1 Running 0 85s 10.244.217.25 vms155.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-8qmbc 1/1 Running 0 85s 10.244.194.81 vms156.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-b9swn 1/1 Running 0 6s 10.244.171.187 vms82.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-dqxw5 1/1 Running 0 6s 10.244.70.15 vms83.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-gbw9f 1/1 Running 0 85s 10.244.70.23 vms83.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-js8ft 1/1 Running 0 6s 10.244.217.26 vms155.liruilongs.github.io <none> <none>
liruilong-547cf79f6f-vnxhd 1/1 Running 0 6s 10.244.194.82 vms156.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
具体的字段解释
topologySpreadConstraints:
-
maxSkew:
1
topologyKey:
kubernetes.io/hostname
whenUnsatisfiable:
ScheduleAnyway
labelSelector:
matchLabels:
app:
liruilong
maxSkew :描述这些 Pod 可能被均匀分布的程度。你必须指定此字段且该数值必须大于零。其语义将随着 whenUnsatisfiable 的值发生变化:简单来讲,就是如果为均匀分布,那么两个节点之前的 pod 差值最大可以为多大。
-
如果你选择 whenUnsatisfiable: DoNotSchedule,则 maxSkew 定义目标拓扑中匹配 Pod 的数量与 全局最小值之间的最大允许差值。例如,如果你有 3 个可用区,分别有 2、2 和 1 个匹配的 Pod,则 MaxSkew 设为 1,且全局最小值为 1。 如果你选择 whenUnsatisfiable: ScheduleAnyway,则该调度器会更为偏向能够降低偏差值的拓扑域。
topologyKey :是节点标签的键。如果节点使用此键标记并且具有相同的标签值, 则将这些节点视为处于同一拓扑域中。我们将拓扑域中(即键值对)的每个实例称为一个域。调度器将尝试在每个拓扑域中放置数量均衡的 Pod。另外,我们将符合条件的域定义为其节点满足 nodeAffinityPolicy 和 nodeTaintsPolicy 要求的域。当 topologyKey 的值为 none 的时候。
whenUnsatisfiable : 指示如果 Pod 不满足分布约束时如何处理:
DoNotSchedule(默认)告诉调度器不要调度。 ScheduleAnyway 告诉调度器仍然继续调度,只是根据如何能将偏差最小化来对节点进行排序。
labelSelector :用于查找匹配的 Pod。匹配此标签的 Pod 将被统计,以确定相应拓扑域中 Pod 的数量
多个拓扑分布约束
在这之前需要做一些准备工作,在每个工作节点上在打一个标签 disktype=node-group1。作为新的拓扑域
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
label node vms82.liruilongs.github.io disktype=node-group1 --overwrite
node/vms82.liruilongs.github.io labeled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
label node vms83.liruilongs.github.io disktype=node-group1 --overwrite
node/vms83.liruilongs.github.io labeled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
label node vms155.liruilongs.github.io disktype=node-group2 --overwrite
node/vms155.liruilongs.github.io labeled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
label node vms156.liruilongs.github.io disktype=node-group2 --overwrite
node/vms156.liruilongs.github.io labeled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get node --label-columns disktype
NAME STATUS ROLES AGE VERSION DISKTYPE
vms155.liruilongs.github.io Ready <none> 55d v1.22.2 node-group2
vms156.liruilongs.github.io Ready <none> 55d v1.22.2 node-group2
vms81.liruilongs.github.io Ready control-plane,master 379d v1.22.2
vms82.liruilongs.github.io Ready <none> 379d v1.22.2 node-group1
vms83.liruilongs.github.io Ready <none> 379d v1.22.2 node-group1
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
当前集群的 pod 在 4 个工作节点的分布, [0 1 1 1]
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-744498fcbd-4z7l4 1/1 Running 0 7h32m 10.244.70.34 vms83.liruilongs.github.io <none> <none>
liruilong-744498fcbd-jpngw 1/1 Running 0 7h32m 10.244.217.27 vms155.liruilongs.github.io <none> <none>
liruilong-744498fcbd-vt9gb 1/1 Running 0 7h32m 10.244.194.86 vms156.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
这里添加一个新的 Pod ,添加了两个拓扑分布约束,要求这个 pod 即在 topologyKey: kubernetes.io/hostname 的拓扑域,同时在 topologyKey: disktype 的拓扑域
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$cat
two-constrains.yaml
kind:
Pod
apiVersion:
v1
metadata:
name:
mypod
labels:
app:
liruilong
spec:
topologySpreadConstraints:
-
maxSkew:
1
topologyKey:
kubernetes.io/hostname
whenUnsatisfiable:
DoNotSchedule
labelSelector:
matchLabels:
app:
liruilong
-
maxSkew:
1
topologyKey:
disktype
whenUnsatisfiable:
DoNotSchedule
labelSelector:
matchLabels:
app:
liruilong
containers:
-
name:
pause
image:
registry.aliyuncs.com/google_containers/pause:3.5
应用上面的 yaml 文件, pod 调度到了 82 节点,当前的 pod 分布为 [1 1 1 1]
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-744498fcbd-4z7l4 1/1 Running 0 8h 10.244.70.34 vms83.liruilongs.github.io <none> <none>
liruilong-744498fcbd-jpngw 1/1 Running 0 8h 10.244.217.27 vms155.liruilongs.github.io <none> <none>
liruilong-744498fcbd-vt9gb 1/1 Running 0 8h 10.244.194.86 vms156.liruilongs.github.io <none> <none>
mypod 1/1 Running 0 39m 10.244.171.178 vms82.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
现在把 82 节点的 拓扑域标签去掉,即 80 节点不属于 disktype 约束的拓扑域。
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
label node vms82.liruilongs.github.io disktype-
node/vms82.liruilongs.github.io unlabeled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get node --label-columns disktype
NAME STATUS ROLES AGE VERSION DISKTYPE
vms155.liruilongs.github.io Ready <none> 55d v1.22.2 node-group2
vms156.liruilongs.github.io Ready <none> 55d v1.22.2 node-group2
vms81.liruilongs.github.io Ready control-plane,master 379d v1.22.2
vms82.liruilongs.github.io Ready <none> 379d v1.22.2
vms83.liruilongs.github.io Ready <none> 379d v1.22.2 node-group1
删除上面的 pod 重新应用 yaml 文件,这时候 82 节点已不满足多拓扑分布的约束。可以看到 pod 调度到了 83 节点.
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
delete -f two-constrains.yaml
pod
"mypod"
deleted
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
apply -f two-constrains.yaml
pod/mypod created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-744498fcbd-4z7l4 1/1 Running 0 8h 10.244.70.34 vms83.liruilongs.github.io <none> <none>
liruilong-744498fcbd-jpngw 1/1 Running 0 8h 10.244.217.27 vms155.liruilongs.github.io <none> <none>
liruilong-744498fcbd-vt9gb 1/1 Running 0 8h 10.244.194.86 vms156.liruilongs.github.io <none> <none>
mypod 1/1 Running 0 8s 10.244.70.33 vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
有冲突的拓扑分布约束
如果所有节点都不满足 pod 的拓扑分布约束,当前 pod 就会调度失败。下面为创建了一个新的补丁文件,修改副本数为 5,使用 kubernetes.io/hostname 作为拓扑域
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$kubectl
kustomize
./
apiVersion:
v1
kind:
Namespace
metadata:
labels:
app:
liruilong
name:
liruilong-topo-namespace
---
apiVersion:
apps/v1
kind:
Deployment
metadata:
labels:
app:
liruilong
name:
liruilong
namespace:
liruilong-topo-namespace
spec:
replicas:
5
selector:
matchLabels:
app:
liruilong
template:
metadata:
labels:
app:
liruilong
spec:
containers:
-
image:
registry.aliyuncs.com/google_containers/pause:3.5
name:
pause
topologySpreadConstraints:
-
labelSelector:
matchLabels:
app:
liruilong
maxSkew:
1
topologyKey:
kubernetes.io/hostname
whenUnsatisfiable:
DoNotSchedule
当前 whenUnsatisfiable: DoNotSchedule,即不满足约束时,不发生调度, master 有污点,默认不发生调度,所以当 副本数为 5 的时候,工作节点各调度一个,剩下的一个 pod 调度到哪里都会违反 maxSkew: 1 ,所以发生 pending 。
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
apply -k ./
namespace/liruilong-topo-namespace created
deployment.apps/liruilong created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-744498fcbd-22c56 1/1 Running 0 76s 10.244.194.89 vms156.liruilongs.github.io <none> <none>
liruilong-744498fcbd-7vn7r 1/1 Running 0 76s 10.244.70.61 vms83.liruilongs.github.io <none> <none>
liruilong-744498fcbd-8d9jq 0/1 Pending 0 76s <none> <none> <none> <none>
liruilong-744498fcbd-8zh7q 1/1 Running 0 76s 10.244.171.157 vms82.liruilongs.github.io <none> <none>
liruilong-744498fcbd-rhtg5 1/1 Running 0 76s 10.244.217.28 vms155.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
可以通过日志查看详细信息
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
describe pods liruilong-744498fcbd-8d9jq | grep -A 10 -i events
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 6m23s default-scheduler 0/5 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn
’t tolerate, 4 node(s) didn’
t match pod topology spread constraints.
Warning FailedScheduling 4m22s (x1 over 5m22s) default-scheduler 0/5 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn
’t tolerate, 4 node(s) didn’
t match pod topology spread constraints.
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
事件中提示:1 个节点有污点{node-role.kubernetes.io/master: },该 pod 不能容忍,4 个节点不符合 pod 拓扑结构的传播限制。
同样的,如果我们把 master 节点排除出拓扑区域,那么就可以满足 maxSkew: 1,可以看到 同样的资源。调度成功发生。
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
label node vms81.liruilongs.github.io kubernetes.io/hostname-
node/vms81.liruilongs.github.io unlabeled
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
delete -k ./
namespace
"liruilong-topo-namespace"
deleted
deployment.apps
"liruilong"
deleted
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
apply -k ./
namespace/liruilong-topo-namespace created
deployment.apps/liruilong created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─
$kubectl
get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liruilong-744498fcbd-5vbmz 1/1 Running 0 5s 10.244.171.143 vms82.liruilongs.github.io <none> <none>
liruilong-744498fcbd-cxlxm 1/1 Running 0 5s 10.244.70.37 vms83.liruilongs.github.io <none> <none>
liruilong-744498fcbd-hzgpr 1/1 Running 0 5s 10.244.194.90 vms156.liruilongs.github.io <none> <none>
liruilong-744498fcbd-nk858 1/1 Running 0 5s 10.244.194.91 vms156.liruilongs.github.io <none> <none>
liruilong-744498fcbd-x2pv2 1/1 Running 0 5s 10.244.217.29 vms155.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/podtopolog]
└─$
拓扑分布约束在实际的使用过程中还要考虑其他的调度策略,比如选择器,节点亲和性等,感兴趣小伙伴可以到官网了解下,关于 pod 通过拓扑分布约束实现的跨节点的均匀分布 pod 就和小伙伴们分享到这里,生活加油。
博文参考:
https://mediu m.com/geekculture/kubernetes-distributing-pods-evenly-across-cluster-c6bdc9b49699
欢迎点击文末 阅读原文 到社区原文下讨论交流 觉得本文有用,请 转发 或点击 赏 ,让更多同行看到
资料/文章推荐:
-
容器云平台规划部署架构设计 | 周末送资料
-
K8S 需要多少台服务器?
-
容器云平台监控架构设计及优化
-
Kubernetes 常见故障排查和处理
-
容器常见故障排查处理和使用规范建议
-
容器云平台如何进行日常巡检?| 运维进阶
下载 twt 社区客户端 APP
长按识别二维码即可下载
或到应用商店搜索“twt”
长按二维码关注公众号
*本公众号所发布内容仅代表作者观点,不代表社区立场
-
2023年血糖新标准公布,不是3.9-6.1,快来看看你的血糖正常吗? 2023-02-07
-
2023年各省最新电价一览!8省中午执行谷段电价! 2023-01-03
-
GB 55009-2021《燃气工程项目规范》(含条文说明),2022年1月1日起实施 2021-11-07
-
PPT导出高分辨率图片的四种方法 2022-09-22
-
2023年最新!国家电网27家省级电力公司负责人大盘点 2023-03-14
-
全国消防救援总队主官及简历(2023.2) 2023-02-10
-
盘点 l 中国石油大庆油田现任领导班子 2023-02-28
-
我们的前辈!历届全国工程勘察设计大师完整名单! 2022-11-18
-
关于某送变电公司“4·22”人身死亡事故的快报 2022-04-26
