调度过程
调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为 predicate;然后对通过的节点按照优先级排序,这个是 priority;最后从中选择优先级最高的节点。如果中间任何一步骤有错误,就直接返回错误。Predicate 有一系列的算法可以使用:
如果在 predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度,直到有节点满足条件。经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程:按照优先级大小对节点排序。优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。这些优先级选项包括:
亲和性
节点亲和性(pod.spec.nodeAffinity)
硬策略 - requiredDuringSchedulingIgnoredDuringExecution
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: hub.escape.com/library/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- k8s-node
软策略 - preferredDuringSchedulingIgnoredDuringExecution
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: hub.escape.com/library/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: source
operator: In
values:
- test
Pod 亲和性(pod.spec.affinity.podAffinity/podAntiAffinity)
- 硬策略 - requiredDuringSchedulingIgnoredDuringExecution
- 软策略 - preferredDuringSchedulingIgnoredDuringExecution
apiVersion: v1 kind: Pod metadata: name: pod-3 labels: app: pod-3 spec: containers: - name: pod-3 image: hub.escape.com/library/myapp:v1 affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: #硬策略 - labelSelector: matchExpressions: - key: app operator: In values: - pod-1 topologyKey: kubernetes.io/hostname podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: #软策略 - weight: 1 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - pod-2 topologyKey: kubernetes.io/hostname
注:拓扑域
第一种,在使用云存储服务的时候,经常会遇到 region,也就是地区的概念,在 K8s 中常通过 label failure-domain.beta.kubernetes.io/region 来标识。这个是为了标识单个 K8s 集群管理的跨 region 的 nodes 到底属于哪个地区;
第二种,比较常用的是可用区,也就是** available zone**,在 K8s 中常通过 label failure-domain.beta.kubernetes.io/zone 来标识。这个是为了标识单个 K8s 集群管理的跨 zone 的 nodes 到底属于哪个可用区;
第三种,是 hostname,就是单机维度,是拓扑域为 **node **范围,在 K8s 中常通过 label kubernetes.io/hostname 来标识,
[
](https://blog.csdn.net/weixin_30336949/article/details/112485203)
污点和容忍
节点亲和性,是 pod 的一种属性(偏好或硬性要求),它使 pod 被吸引到一类特定的节点。Taint 则相反,它使节点能够排斥一类特定的 pod。
**Taint **和 **toleration **相互配合,可以用来避免 pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个 taint,这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。如果将 toleration 应用于 pod 上,则表示这些 pod 可以(但不要求)被调度到具有匹配 taint 的节点上。
污点
- NoSchedule:表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上
- PreferNoSchedule:表示 k8s 将尽量避免将 Pod 调度到具有该污点的 Node 上
- NoExecute:将不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已经存在的 Pod 驱逐出去
1.查看污点
kubectl describe node k8s-master
Taints: node-role.kubernetes.io/master:NoSchedule
2.污点的设置、查看和去除
# 设置污点
$ kubectl taint nodes k8s-node1 key1=value1:NoSchedule
$ kubectl taint nodes k8s-node1 type=master:NoExecute
# 节点说明中查找Taints字段
$ kubectl describe pod pod-name
# 去除污点
$ kubectl taint nodes k8s-node1 key1:NoSchedule-
容忍
设置了污点的 Node 将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod 之间产生互斥的关系,Pod 将在一定程度上不会被调度到 Node 上。但我们可以在 Pod 上设置容忍,意思是设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的 Node 上。
- pod.spec.tolerations
- 其中 operator 的值为 Exists 将会忽略 value 值
- 其中 key, value, effect 要与 Node 上设置的 taint 保持一致
- 其中 tolerationSeconds 用于描述当 Pod 需要被驱逐时可以在 Pod 上继续保留运行的时间
apiVersion: v1 kind: Pod metadata: name: pod-3 labels: app: pod-3 spec: containers: - name: pod-3 image: hub.escape.com/library/myapp:v1 tolerations: - key: "type" operator: "Equal" //操作符 value: "master" //key,value effect: "NoSchedule" //污点策略 tolerationSeconds: 3600 //保留运行时间秒 - key: "type" operator: "Equal" value: "master" effect: "NoExecute" - key: "type" operator: "Exists" effect: "NoSchedule" --- tolerations: 当不指定 key 值时,表示容忍所有的污点 key operator: "Exists" --- tolerations: #当不指定 effect 值时,表示容忍所有的污点作用 - key: "key" operator: "Exists"
指定调度节点
将 Pod 直接调度到指定的 Node 节点上,会跳过 Scheduler 的调度策略,该匹配规则是强制匹配。
1.通过nodeName
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: myweb
spec:
replicas: 7
template:
metadata:
labels:
app: myweb
spec:
nodeName: k8s-node1 ## 通过nodename
containers:
- name: myweb
image: hub.escape.com/library/myapp:v1
ports:
- containerPort: 80
2.通过标签
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: myweb
spec:
replicas: 2
template:
metadata:
labels:
app: myweb
spec:
nodeSelector: #通过标签选择
type: BackendNode
containers:
- name: myweb
image: hub.escape.com/library/myapp:v1
ports: