37.k8s调度
k8s调度
我们前面的一个章节Kubernetes(k8s)-Request&Limit介绍,介绍过Request参数是决定Pod调度的一个很重要的指标,实际上在Kubernetes里面有非常多的调度算法来决定某一个Pod应该落到哪个节点上面,下面我们就来介绍下这些算法。
node标签
# 查看节点标签
kubectl get node --show-labels=true
# 添加标签 key=value
kubectl label nodes node1 node=node1
# 去除标签 key-
kubectl label nodes node1 node-
node标签选择器
如果同时指定了 nodeSelector 和 nodeAffinity,两者必须都要满足, 才能将 Pod 调度到候选节点上。
如果指定了多个与 nodeAffinity 类型关联的 nodeSelectorTerms,满足一个 nodeSelectorTerms ,pod将可以调度到节点上。
指定了多个与 nodeSelectorTerms 关联的 matchExpressions,满足所有 matchExpressions ,Pod 才会可以调度到节点上。
由于IgnoredDuringExecution,改变labels不会影响已运行的pod.

nodeSelector
参考: 将 Pod 分配给节点
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
# 选择node标签为disktype=ssd的node
nodeSelector:
disktype: ssd
Node亲和性调度affinity
理解 Kubernetes 的亲和性调度
官方doc-节点亲和性
requiredDuringSchedulingIgnoredDuringExecution: 硬策略/硬需求–必须满足preferredDuringSchedulingIgnoredDuringExecution: 软策略/软需求–尽量满足
支持的操作符有:In , 包含NotIn , 不包含,一般用来做反亲和(Anti-Affinity)Exists , 存在DoesNotExist ,不存在Gt , (greater than), label 的值大于某个值,int类型Lt , (less than),label 的值小于某个值,int类型
name in( redis-master, redis-salve)# 匹配所有带有标签name=master或者name=salve的资源
name not in ( php)#匹配所有不具有标签name=php的资源对象
亲和度示例yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
name: myapp
spec:
# 亲和性
affinity:
# 节点亲和度
nodeAffinity:
# 硬策略/硬需求
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
# 匹配所有带有标签disktype=ssd或者disktype=shd的资源
- key: disktype
operator: In
values:
- ssd
- shd
# 软策略/软需求(尽量匹配标签的资源,不满足时会找其他的资源)
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1 # 权重值/(加分项,1-100,100是最高分),能提高匹配概率,不用太关注
preference: # 固定语法,意为偏爱
matchExpressions:
# 尽可能匹配标签为disktye=ssd2的资源
- key: disktype
operator: In
values:
- ssd2
containers:
- name: myapp
image: <Image>
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: <Port>
nodeName
参考: pod 调度到一个指定节点
nodeName不会通过调度器,即使node有污点也能直接运行pod.一般用于测试.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: node1 # 让pod运行在指定node上,nodeName不会通过调度器
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
node调度故障诊断排查
# 显示给定节点的度量值
kubectl top node my-node
# 显示主控节点和服务的地址
kubectl cluster-info
# 将当前集群状态转储到标准输出
kubectl cluster-info dump
# 将当前集群状态输出到 /path/to/cluster-state
kubectl cluster-info dump --output-directory=/path/to/cluster-state
常见调度失败原因
- CPU不足
- 没有匹配到节点标签
- 所有的节点有污点,但你没有配置污点容忍
pod一直是pending
参考: https://cloud.tencent.com/document/product/457/42948
当Pod处在Pending的时候,可能是由于如下哪个问题造成的。
资源不足,造成无法调度;
Pod尚未进入调度阶段;
Pod正在拉取镜像;
看kubelet日志.
# 查看pod详情
kubectl describe po pod名
## 显示pod已经调度到node2,但一直是pending
查看node资源是否足够
# 查看node资源是否足够
kubectl describe node <node-name>
# 或kubectl top node
在返回信息中,请注意关注以下内容:Allocatable:表示此节点能够申请的资源总和。Allocated resources:表示此节点已分配的资源(Allocatable 减去节点上所有 Pod 总的 Request)。
Pod的调度
Pod 的调度是 Kubernetes 中将 Pod 放置在合适节点上运行的过程。调度器是 Kubernetes 控制平面的一部分,它负责根据调度算法和当前集群的状态选择最佳节点。以下是 Pod 调度的主要步骤和考虑因素:
- 调度需求:首先,定义你的 Pod 需要什么样的资源和条件。这可以通过资源请求、限制和 Pod 亲和性规则来指定。
- 资源请求和限制:在 Pod 的定义中,可以为每个容器指定
resources.requests(最小资源需求)和resources.limits(资源使用上限)。调度器会确保 Pod 分配到的节点有足够的资源来满足其请求。在真正的生产集群应该为每个Pod配置对应的资源需求和资源限制,并让服务器留有足够的冗余,当某节点故障的时候,确保还有足够的剩余资源满足故障Pod的创建。 - 标签和选择器:通过标签(Labels)和选择器(Selectors)可以控制 Pod 应该调度到哪些节点上。节点亲和性(node affinity)和反亲和性(node anti-affinity)规则允许 Pods 被吸引或排斥于具有特定标签的节点。
- 污点和容忍度:节点上的污点(Taints)阻止某些 Pod 调度到这些节点上,除非这些 Pod 有匹配的容忍度(Tolerations)。
- Pod 亲和性和反亲和性:Pod 可以通过 Pod 亲和性规则被调度到运行特定 Pod 的节点上,或者通过 Pod 反亲和性规则避免被调度到运行特定 Pod 的节点上。
- 节点选择器:通过节点选择器(nodeSelector),可以将 Pod 分配给具有特定标签的节点。
- PVC关联性: 某些Pod是带有PVC资源的,而部分PVC资源是绑定在某一个节点的,那么这个Pod则只能落到某一个固定节点上面。
调度器在决定将 Pod 放置在何处时,遵循以下基本流程:
- 预选(Predicates):调度器筛选出符合 Pod 资源请求、节点选择器、容忍度等要求的节点。排除那些不满足基本前提条件的节点。
- 优选(Priorities):对于通过预选的节点,调度器会评分,优先考虑那些资源利用率最高、最能满足 Pod 亲和性/反亲和性规则的节点。
- 绑定(Binding):一旦选择了最佳节点,调度器会创建一个绑定操作,将 Pod 和选定的节点关联起来。
Pod 调度是一个复杂的过程,它涉及到多种不同的策略和算法。了解这些概念有助于优化 Pod 的调度策略,使得 Kubernetes 集群能够更高效、稳定地运行。它是由管控组kube-scheduler来完成的。
下面的日志就是我测试集群节点的演示日志
I0204 08:25:52.832631 1 resource_allocation.go:73] "Listing internal info for allocatable resources, requested resources and score" pod="default/nginx-deployment-c5cbddb86-66ggl" node="node01" resourceAllocationScorer="LeastAllocated" allocatableResource=map[cpu:2000 memory:3890135040] requestedResource=map[cpu:750 memory:1258291200] resourceScore=64
I0204 08:25:52.832649 1 resource_allocation.go:73] "Listing internal info for allocatable resources, requested resources and score" pod="default/nginx-deployment-c5cbddb86-66ggl" node="node01" resourceAllocationScorer="NodeResourcesBalancedAllocation" allocatableResource=map[cpu:2000 memory:3890135040] requestedResource=map[cpu:250 memory:0] resourceScore=93
I0204 08:25:52.832661 1 resource_allocation.go:73] "Listing internal info for allocatable resources, requested resources and score" pod="default/nginx-deployment-c5cbddb86-66ggl" node="node02" resourceAllocationScorer="LeastAllocated" allocatableResource=map[cpu:2000 memory:3890126848] requestedResource=map[cpu:450 memory:629145600] resourceScore=80
I0204 08:25:52.832670 1 resource_allocation.go:73] "Listing internal info for allocatable resources, requested resources and score" pod="default/nginx-deployment-c5cbddb86-66ggl" node="node02" resourceAllocationScorer="NodeResourcesBalancedAllocation" allocatableResource=map[cpu:2000 memory:3890126848] requestedResource=map[cpu:250 memory:0] resourceScore=93
I0204 08:25:52.832722 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="NodeResourcesFit" node="node01" score=64
I0204 08:25:52.832728 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="NodeResourcesFit" node="node02" score=80
I0204 08:25:52.832732 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="VolumeBinding" node="node01" score=0
I0204 08:25:52.832736 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="VolumeBinding" node="node02" score=0
I0204 08:25:52.832740 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="PodTopologySpread" node="node01" score=200
I0204 08:25:52.832744 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="PodTopologySpread" node="node02" score=200
I0204 08:25:52.832748 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="InterPodAffinity" node="node01" score=0
I0204 08:25:52.832752 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="InterPodAffinity" node="node02" score=0
I0204 08:25:52.832756 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="NodeResourcesBalancedAllocation" node="node01" score=93
I0204 08:25:52.832760 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="NodeResourcesBalancedAllocation" node="node02" score=93
I0204 08:25:52.832764 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="ImageLocality" node="node01" score=3
I0204 08:25:52.832768 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="ImageLocality" node="node02" score=0
I0204 08:25:52.832772 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="TaintToleration" node="node01" score=300
I0204 08:25:52.832777 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="TaintToleration" node="node02" score=300
I0204 08:25:52.832781 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="NodeAffinity" node="node01" score=0
I0204 08:25:52.832785 1 generic_scheduler.go:434] "Plugin scored node for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" plugin="NodeAffinity" node="node02" score=0
I0204 08:25:52.832791 1 generic_scheduler.go:491] "Calculated node's final score for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" node="node01" score=660
I0204 08:25:52.832795 1 generic_scheduler.go:491] "Calculated node's final score for pod" pod="default/nginx-deployment-c5cbddb86-66ggl" node="node02" score=673
1. 资源分配评分插件
这个打分过程包括
a. NodeResourcesFit(资源适配度)
- 作用:检查节点资源是否能满足 Pod 需求。
b. NodeResourcesBalancedAllocation(资源平衡分配)
- 作用:确保 CPU 和内存资源的分配平衡,避免某一资源耗尽。
2. 存储相关插件
VolumeBinding(卷绑定)
- 作用:检查节点是否满足 Pod 的卷绑定需求(如 PVC 绑定状态)。
3. 拓扑与亲和性插件
a. PodTopologySpread(Pod 拓扑分布)
- 作用:确保 Pod 在指定拓扑域(如节点、区域)中均匀分布。
b. InterPodAffinity(Pod 间亲和性/反亲和性)
- 作用:检查 Pod 与其他 Pod 的亲和性/反亲和性规则。
c. NodeAffinity(节点亲和性)
- 作用:检查节点标签是否匹配 Pod 的亲和性规则。
4. 镜像与污点容忍插件
a. ImageLocality(镜像本地性)
- 作用:优先选择已存在 Pod 所需镜像的节点。
b. TaintToleration(污点容忍)
- 作用:检查节点污点是否被 Pod 容忍。
5. 最终得分计算
6. 调度结果
- 得分对比:
node02总分 673 >node01总分 660。 - 调度决策:调度器会将 Pod
nginx-deployment-c5cbddb86-66ggl绑定到node02。
更多推荐
所有评论(0)