十四、kubernetes 1.29 之 调度器 、亲和性
一、概念

Sheduler 是作为单独的程序运行的(可以剥离),启动之后会一直监听 API Server,获取
PodSpec.NodeName为空的 pod,对每个 pod 都会创建一个 binding,表明该 pod 应该放到哪个节点上概念听起来是非常简单的,但有很多要考虑的问题:
◆ 公平:如何保证每个节点都能被分配资源
◆ 资源高效利用:集群所有资源最大化被使用
◆ 效率:调度的性能要好,能够尽快地对大批量的 pod 完成调度工作
◆ 灵活:允许用户根据自己的需求控制调度的逻辑
二、自定义调度器
"除了 Kubernetes 自带的调度器,你也可以编写自己的调度器。通过 spec.schedulerName参数指定调度器的名字,可以为 Pod 选择某个调度器进行调度。比如下面的 Pod 选择
my-scheduler进行调度,而不是默认的 default-scheduler。"
Deployment控制器
apiVersion: apps/v1 kind: Deployment metadata: labels: app: myapp name: myapp spec: replicas: 1 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: schedulerName: my-scheduler containers: - image: wangyanglinux/myapp:v1.0 name: myapp创建一个 调度器(逻辑演示)
kubectl proxy --port=8001 vi my-scheduler.sh #!/bin/bash SERVER='localhost:8001' while true; do for PODNAME in $(kubectl --server $SERVER get pods -o json | jq '.items[] | select(.spec.schedulerName =="my-scheduler") | select(.spec.nodeName == null) | .metadata.name' | tr -d '"') do NODES=($(kubectl --server $SERVER get nodes -o json | jq '.items[].metadata.name' | tr -d '"')) NUMNODES=${#NODES[@]} CHOSEN=${NODES[$[ $RANDOM % $NUMNODES]]} curl --header "Content-Type:application/json" --request POST --data '{"apiVersion":"v1","kind":"Binding","metadata": {"name":"'$PODNAME'"},"target": {"apiVersion":"v1","kind": "Node", "name": "'$CHOSEN'"}}' http://$SERVER/api/v1/namespaces/default/pods/$PODNAME/binding/ echo "Assigned $PODNAME to $CHOSEN" done sleep 1 done
三、过程
调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为"预选: 然后对通过的节
点按照优先级排序,这个是优选';最后从中选择优先级最高的节点。如果中间任何一步骤有
错误,就直接返回错误
1、预选
部分预选算法,每个版本不一样
1. PodFitsResources
功能:检查节点上剩余的资源是否大于 Pod 请求的资源
作用:确保节点有足够的 CPU、内存等资源来运行 Pod
2. PodFitsHost
功能:如果 Pod 明确指定了
NodeName,检查节点名称是否匹配作用:确保 Pod 被调度到指定的节点上
3. PodFitsHostPorts
功能:检查节点上已经使用的端口是否与 Pod 申请的端口冲突
作用:避免端口冲突,确保网络服务正常运行
4. PodSelectorMatches
功能:过滤掉与 Pod 指定的标签不匹配的节点
作用:基于节点标签进行智能筛选和匹配
5. NoDiskConflict
功能:确保已挂载的卷与 Pod 指定的卷不冲突(除非它们都是只读)
作用:防止存储卷的访问冲突,确保数据安全
2、优选
如果在预选过程中没有合适的节点,Pod 会一直处于 pending 状态,不断重试调度,直到有节点满足条件。经过这个步骤后,如果有多个节点满足条件,就继续优选过程:按照优先级大小对节点排序。
优先级配置原理
优先级由一系列键值对组成:
键:优先级项的名称
值:权重(表示该项的重要性)
优先级选项详解
➤ LeastRequestedPriority
机制:通过计算 CPU 和 Memory 的使用率来决定权重
倾向:使用率越低权重越高,即倾向于资源使用比例更低的节点
➤ BalancedResourceAllocation
机制:节点上 CPU 和 Memory 使用率越接近,权重越高
建议:应该与 LeastRequestedPriority 一起使用,不建议单独使用
➤ ImageLocalityPriority
机制:倾向于已经存在所需镜像的节点
权重:镜像总大小值越大,权重越高

四、亲和性
1、pod.spec.nodeAffinity
preferredDuringSchedulinglgnoredDuringExecution:软性策略
requiredDuringSchedulinglgnoredDuringExecution:硬性策略
2、软策略
有更好,没有也行
这是一个使用节点亲和性(Node Affinity)的 Pod 配置
采用了
preferredDuringSchedulingIgnoredDuringExecution策略,表示"优选但不强制"Pod 会优先调度到带有
domain=xinxianghf标签的节点上权重(weight)为 1,表示该偏好的相对重要性
apiVersion: v1 kind: Pod metadata: name: node-affinity-preferred labels: app: node-affinity-preferred spec: containers: - name: node-affinity-preferred-pod image: wangyanglinux/myapp:v1.0 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: domain operator: In values: - xinxianghf
3、硬策略
必须有,不然就不玩了
Pod基本信息:
名称:
node-affinity-required标签:
app: node-affinity-required容器配置:
容器名称:
node-affinity-required-pod使用镜像:
wangyanglinux/myapp:v1.0节点亲和性配置:
使用
requiredDuringSchedulingIgnoredDuringExecution策略(硬性要求)要求Pod必须调度到主机名为
k8s-node04的节点上使用节点标签选择器:
kubernetes.io/hostnameapiVersion: v1 kind: Pod metadata: name: node-affinity-required labels: app: node-affinity-required spec: containers: - name: node-affinity-required-pod image: wangyanglinux/myapp:v1.0 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-node04
4、反亲和性pod.spec.podAffinity/podAntiAffinity
针对pod,
preferredDuringSchedulinglgnoredDuringExecution:软性策略
requiredDuringSchedulinglgnoredDuringExecution:硬性策略
亲和性-软策略
weight(权重)定义:
weight是一个介于 1 到 100 之间的整数值,用于在多个软性(preferred)亲和性/反亲和性规则同时存在时,表示该规则的相对重要性或偏好程度。作用机制:
Kubernetes 调度器在通过预选阶段(找到所有满足硬性条件的节点)后,会进入优选阶段,为每个节点打分。
对于每一条满足的软性规则,调度器会为该节点加上此规则对应的
weight分数。分数越高,节点在最终排序中的优先级就越高,Pod 被调度到该节点的可能性就越大。
topologyKey(拓扑域键)定义:
topologyKey是一个节点标签的键(Key),用于定义什么是“同一个拓扑域”。它决定了亲和性/反亲和性规则的作用范围。作用机制:
调度器会检查节点的
topologyKey标签的值。拥有相同标签值的节点被视为在同一个拓扑域中。Pod 亲和性/反亲和性规则是在这个“拓扑域”的范围内生效的。
apiVersion: v1 kind: Pod metadata: name: pod-aff-prefer labels: app: pod-aff spec: containers: - name: myapp image: wangyanglinux/myapp:v1.0 affinity: podAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - pod-1 topologyKey: kubernetes.io/hostname
亲和性-硬策略
容器配置:
容器名称:
pod-aff-req-c使用镜像:
wangyanglinux/myapp:v1.0Pod亲和性配置:
使用
requiredDuringSchedulingIgnoredDuringExecution策略(硬性要求)要求Pod必须与标签为
app: pod-1的其他Pod在同一主机上运行拓扑域键:
kubernetes.io/hostname(基于节点主机名的拓扑域)功能说明:
此配置定义了一个具有强制Pod亲和性规则的Pod,它必须被调度到已经运行着带有
app: pod-1标签的Pod的同一节点上。这种配置适用于需要确保某些Pod在同一节点上紧密协作的场景。apiVersion: v1 kind: Pod metadata: name: pod-aff-req labels: app: pod-aff-req spec: containers: - name: pod-aff-req-c image: wangyanglinux/myapp:v1.0 affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - pod-1 topologyKey: kubernetes.io/hostname
反亲和性-软策略
此 Pod 配置使用了 Pod 反亲和性规则
调度时会优先避免将本 Pod 部署到已经运行着
app: pod-2标签的 Pod 的同一节点上这是一个软性规则(优选规则),如果无法满足,Pod 仍可能被调度到其他节点
apiVersion: v1 kind: Pod metadata: name: pod-antiaff-prefer labels: app: pod-aff spec: containers: - name: myapp image: wangyanglinux/myapp:v1.0 affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - pod-2 topologyKey: kubernetes.io/hostname
反亲和性-硬策略
此 Pod 配置使用了 Pod 反亲和性 规则,采用
requiredDuringSchedulingIgnoredDuringExecution策略(硬性要求)。它要求 Pod 必须避免被调度到已经运行着带有
app: pod-1标签的 Pod 的同一节点上(基于kubernetes.io/hostname拓扑域)。适用于需要确保 Pod 在不同节点上分散部署的场景,以提高可用性或避免资源冲突。
apiVersion: v1 kind: Pod metadata: name: pod-aff-req labels: app: pod-aff-req spec: containers: - name: pod-aff-req-c image: wangyanglinux/myapp:v1.0 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - pod-1 topologyKey: kubernetes.io/hostname
5、总结
更多推荐






所有评论(0)