以下内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、订阅、转发!欢迎扫码关注个人公众号!
目录
一、基本介绍
在 Kubernetes 中,服务调度是指 kube-scheduler 组件根据特定的调度算法和策略,将 Pod 分配到最合适的 Node 节点上,以满足应用程序的资源需求和 Kubernetes 集群的资源限制,实现集群资源充分、合理的利用。
官方文档:Kubernetes Scheduler | Kubernetes
二、工作原理
kube-scheduler 持续监听 kube-apiserver,当检查到没有绑定 Node 节点的 Pod(即 PodSpec.NodeName 为空)时,会为其分配 Node 节点并进行绑定。
整个调度过程大致可以分为 3 个阶段:
- 预选阶段:过滤掉不满足条件的 Node 节点,这个过程称为 Predicates
- 优选阶段:对满足条件的 Node 节点进行优先级排序,称之为 Priorities
- 选定阶段:从多个优选出的 Node 节点中随机选择一个
如果中间任何一个阶段出现错误,就会直接返回错误。
三、节点绑定
节点绑定(Node Selector)是一种调度机制,该机制基于 Node 节点的标签,将 Pod 调度到具有特定标签的 Node 节点上,实现与指定 Node 节点的绑定。
资源清单示例如下:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-deployment
spec:
replicas: 1
selector:
matchLabels:
app: demo-deployment
template:
metadata:
labels:
app: demo-deployment
spec:
containers:
- name: demo-container
image: demo-image:latest
ports:
- containerPort: 80
nodeSelector:
kubernetes.io/hostname: my-node01
🔔 可以通过 kubectl get node <node_name> --show-labels 查看节点标签
上述 deployment.yaml 文件通过 nodeSelector 字段,将新创建的 Pod 绑定到具有 kubernetes.io/hostname=my-node01 标签(即主机名为 my-node01 )的 Node 节点。
四、亲和性调度
亲和性调度(Affinity Scheduling)是一种高级调度机制,允许 Pod 调度到指定的 Node 节点,或与指定 Pod 运行在同一 Node 节点上,实现保障应用程序性能等目标,如减少应用模块间通信延迟,提高数据访问速度。
1、亲和性类型
亲和性调度包括 2 种类型:
- 节点亲和性(Node Affinity):基于 Node 节点的标签调度 Pod
- Pod 亲和性(Pod Affinity):基于同一命名空间下指定 Pod 的标签调度 Pod
2、亲和性规则
亲和性调度的规则包括 2 种类型:
- RequiredDuringSchedulingIgnoredDuringExecution:Pod 在调度时必须满足指定条件,是一种硬策略
- PreferredDuringSchedulingIgnoredDuringExecution:Pod 在调度时首选满足指定条件,但不是强制性的。如果无法满足指定条件,Pod 仍然可以被调度到其他节点上,是一种软策略
3、Node Affinity
# 资源清单(示例)
...
spec:
containers:
- name: demo-container
image: demo-image:latest
ports:
- containerPort: 80
...
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In / NotIn / Exists / DoseNotExist / Gt / Lt
values:
- my-node01
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: kubernetes.io/hostname
operator: In / NotIn / Exists / DoseNotExist / Gt / Lt
values:
- my-node01
...
🔔 operator 选项说明:
In:满足一个就满足
NotIn:一个都不能满足
Exist:只要存在就满足
DoesNotExist:只要不存在就满足
Gt:必须要打大于节点上的数值
Lt:必须要打小于节点上的数值
==========================================================================
🔔 若同时指定 nodeSelector 和 nodeAffinity,同时满足时,Pod 才能调度到节点上
🔔 若在 nodeSelectorTerms 中指定了多个条件,满足任意一个,Pod 就可以调度到节点上
🔔 若在单个 matchExpressions 中指定多个表达式,同时满足时,Pod 才能调度到节点上
4、Pod Affinity
# 资源清单(示例)
...
spec:
containers:
- name: demo-container
image: demo-image:latest
ports:
- containerPort: 80
...
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In / NotIn
values:
- demo-pod
topologyKey: kubernetes.io/hostname
weight: 100
...
五、反亲和性调度
反亲和性调度(Anti-Affinity Scheduling)是一种高级调度机制,确保 Pod 不会同时被调度到同一个 Node 节点上,以避免资源争用、提高容错性,有助于实现故障域隔离和负载均衡。
1、反亲和性类型
- Pod 反亲和性(Pod Anti-Affinity):基于同一命名空间下指定 Pod 的标签调度 Pod
2、反亲和性规则
反亲和性调度的规则包括 2 种类型:
- RequiredDuringSchedulingIgnoredDuringExecution:Pod 在调度时必须满足指定条件,是一种硬策略
- PreferredDuringSchedulingIgnoredDuringExecution:Pod 在调度时首选满足指定条件,但不是强制性的。如果无法满足指定条件,Pod 仍然可以被调度到其他节点上,是一种软策略
3、Pod Anti-Affinity
# 资源清单(示例)
...
spec:
containers:
- name: demo-container
image: demo-image:latest
ports:
- containerPort: 80
...
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In / NotIn
values:
- demo-pod
topologyKey: kubernetes.io/hostname
weight: 100
...
六、污点和容忍
1、污点
在 Kubernetes 中,污点(Taint)是一种节点标记,被污点标记的 Node 节点不允许调度 Pod。
污点具有键(Key)、值(Value)、效应(Effect)三种属性,其中效应包含 3 种类型:
- NoSchedule:默认类型,未配置容忍该污点的 Pod 不会被调度到该节点上
- PreferNoSchedule:Pod 尽量避免被调度到该节点上,但不是强制性的
- NoExecute:未配置容忍该污点的 Pod 不会被调度到该节点上,且在污点生效时会驱逐(Evict)已经运行在该节点上的未配置容忍该污点的 Pod
2、容忍
容忍(Tolerate)是 Pod 可以配置的一种属性,配置了容忍该污点的 Pod 可以被调度到该节点上。
# 资源清单(示例)
...
spec:
containers:
- name: demo-container
image: demo-image:latest
ports:
- containerPort: 80
...
tolerations:
- key: "demo-key"
operator: "Exists"
value: "demo-value"
effect: "NoSchedule"
tolerationSeconds: 6000
...
🔔 operator 值可以为 Exists、Equal,值为 Exists 时 value 可以省略
🔔 tolerationSeconds 用于指定 Pod 被驱逐时,可以继续在 Node 上运行的时间
七、相关命令
1、label
# 新增节点标签
kubectl label node <node-name> key=value
# 删除节点标签
kubectl label node <node-name> key-
# 修改节点标签
kubectl label node <node-name> key=value --overwrite
# 查看节点标签
kubectl get node <node-name> --show-labels
2、taint
# 新增污点标记
kubectl taint node <node-name> key=value:NoSchedule
kubectl taint node <node-name> key=value:NoExecute
# 删除污点标记:
kubectl taint nodes <node-name> key-
# 查看污点标记:
kubectl describe node <node-name>
3、cordon
# 使节点不可调度( 运行的 Pod 不会被驱逐 )
kubectl cordon <node-name>
# 使节点恢复调度
kubectl uncordon <node-name>
4、drain
# 驱逐节点上的 Pod,且使节点不可调度 Pod
kubectl drain <node-name>
# 节点恢复调度方法
kubectl uncordon <node-name>