一、集群调度
二、节点亲和性(pod与node的亲和性)
定向调度,指的是利用在pod上声明nodeName或者nodeSelector,以此将Pod调度到期望的node节点上。注意,这里的调度是强制的,这就意味着即使要调度的目标Node不存在,也会向上面进行调度,只不过pod运行失败而已。
NodeName
NodeName
用于强制约束将Pod调度到指定的Name的Node节点上。这种方式,其实是直接跳过Scheduler的调度逻辑,直接将Pod调度到指定名称的节点。
NodeSelector
`NodeSelector用`于将pod调度到添加了指定标签的node节点上。它是通过kubernetes的`label-selector机制`实现的,也就是说,在pod创建之前,会由`scheduler使用MatchNodeSelector`调度策略进行`label`匹配,找出目标node,然后将pod调度到目标节点,该匹配规则是强制约束。
- 自动调度:运行在哪个节点上完全由Scheduler经过一系列的算法计算得出
- 定向调度:NodeName、NodeSelector
- 亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity
- 污点(容忍)调度:Taints、Toleration
NodeAffinity
pod.spec.affinity.nodeAffinity
requiredDuringSchedulingIgnoredDuringExecution Node节点必须满足指定的所有规则才可以,相当于硬限制
nodeSelectorTerms 节点选择列表
matchFields 按节点字段列出的节点选择器要求列表
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持Exists, DoesNotExist, In, NotIn, Gt, Lt
preferredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则的Node,相当于软限制 (倾向)
preference 一个节点选择器项,与相应的权重相关联
matchFields 按节点字段列出的节点选择器要求列表
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt
weight 倾向权重,在范围1-100。
1.pod.spec.affinity.nodeAffinity:
- preferredDuringSchedulingIgnoredDuringExecution 软策略
- requiredDuringSchedulingIgnoredDuringExecution 硬策略
软策略:有就去,没有就算了。
硬策略:必须要有才去。
1)创建硬策略
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: wangyanglinux/myapp:v1
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
nodeSelectorTerms:
- matchExpressions: # 匹配env的值的标签
- key: kuberbetes.io/hostname
operator: NotIn
values:
- k8s-node02
#查看pod的分布
[root@k8s-master-01 affi]# kubectl get pods
NAME READY STATUS RESTARTS AGE
affinity 1/1 Running 0 5s
#只调度在node1节点
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 1/1 Running 0 22s 10.244.1.98 k8s-node-01 <none> <none>
#删除pod之后,重新部署还是在node1上,因为这是硬调度。
[root@k8s-master-01 affi]# kubectl delete pods --all
pod "affinity" deleted
[root@k8s-master-01 affi]# kubectl apply -f pod1.yaml && kubectl get pods -o wide
pod/affinity created
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 0/1 ContainerCreating 0 0s <none> k8s-node-01 <none> <none>
继续测试
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: wangyanglinux/myapp:v1
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
nodeSelectorTerms:
- matchExpressions: # 匹配env的值的标签
- key: kuberbetes.io/hostname
operator: In
values:
- k8s-node03
# 因为我们没有node3节点,所以我们硬性调度到node3节点上,验证一下效果
# 因此一直显示pending的结果
[root@k8s-master-01 affi]# kubectl apply -f pod1.yaml
pod/affinity created
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 0/1 Pending 0 9s <none> <none> <none> <none>
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 0/1 Pending 0 10s <none> <none> <none> <none>
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 0/1 Pending 0 11s <none> <none> <none> <none>
2)软策略
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: wangyanglinux/myapp:v1
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
preferredDuringSchedulingIgnoredDuringExecution: # 软限制
- weight: 1
preference:
matchExpressions: # 匹配env的值的标签
- key: kuberbetes.io/hostname
operator: In
values:
- k8s-node03
#因为是软策略,我们没有node3节点,所以就直接随机在一个node上了。因为是软策略有的话就最好。
[root@k8s-master-01 affi]# kubectl apply -f pod1.yaml
pod/affinity created
[root@k8s-master-01 affi]# kubectl get pods
NAME READY STATUS RESTARTS AGE
affinity 1/1 Running 0 3s
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 1/1 Running 0 6s 10.244.1.100 k8s-node-01 <none> <none>
继续测试
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: wangyanglinux/myapp:v1
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
preferredDuringSchedulingIgnoredDuringExecution: # 软限制
- weight: 1
preference:
matchExpressions: # 匹配env的值的标签
- key: kuberbetes.io/hostname
operator: In
values:
- k8s-node01
#有node1的话,就调度到node1上了。
[root@k8s-master-01 affi]# kubectl apply -f pod1.yaml
pod/affinity created
[root@k8s-master-01 affi]# kubectl get pods
NAME READY STATUS RESTARTS AGE
affinity 1/1 Running 0 3s
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 1/1 Running 0 7s 10.244.1.102 k8s-node-01 <none> <none>
软硬合体
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: wangyanglinux/myapp:v1
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
requireDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- k8s-node02
preferredDuringSchedulingIgnoredDuringExecution: # 软限制
- weight: 1
preference:
matchExpressions: # 匹配env的值的标签
- key: kuberbetes.io/hostname
operator: In
values:
- k8s-node01
键值运算关系
三、pod的亲和性(pod与pod之间)
pod.spec.affinity.podAffinity
requiredDuringSchedulingIgnoredDuringExecution 硬限制
preferredDuringSchedulingIgnoredDuringExecution 软限制
测试
apiVersion: v1
kind: Pod
metadata:
name: node01
labels:
app: node01
spec:
containers:
- name: with-node-affinity
image: wangyanglinux/myapp:v1
查看标签
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
node01 1/1 Running 0 2m48s 10.244.1.104 k8s-node-01 <none> <none>
[root@k8s-master-01 affi]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
node01 1/1 Running 0 3m2s app=node01
测试硬限制
apiVersion: v1
kind: Pod
metadata:
name: pod-3
labels:
app: node01
spec:
containers:
- name: pod-3
image: wangyanglinux/myapp:v1
affinity:
podAffinity: #pod的亲和性
requiredDuringSchedulingIgnoredDuringExecution: #硬限制
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- node01 #与上文创建标签对应
topologyKey: kubernetes.io/hostname
#发现新部署的pod和上文部署的pod在一个节点上,`这是因为拓扑域的影响。拓扑域和标签关联的。
[root@k8s-master-01 affi]# kubectl apply -f pod3.yaml
pod/pod-3 created
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
node01 1/1 Running 0 39m 10.244.1.104 k8s-node-01 <none> <none>
pod-3 1/1 Running 0 111s 10.244.1.105 k8s-node-01 <none> <none>
#即使删除此新部署的pod,重新部署还是会和原来的pod再同一个节点上。
###测试不在同一个节点上
apiVersion: v1
kind: Pod
metadata:
name: pod-3
labels:
app: node01
spec:
containers:
- name: pod-3
image: wangyanglinux/myapp:v1
affinity:
podAntiAffinity: #必须不在一个节点
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In #必须跟app=node01的pod不在同一节点上运行
values:
- node01
topologyKey: kubernetes.io/hostname
[root@k8s-master-01 affi]# kubectl apply -f pod3.yaml
pod/pod-3 created
[root@k8s-master-01 affi]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
node01 1/1 Running 0 52m 10.244.1.104 k8s-node-01 <none> <none>
pod-3 1/1 Running 0 5s 10.244.2.124 k8s-node-02 <none> <none>
注意:发现删除新部署的pod,重新部署之后,分布在不同的node节点上。
apiVersion: v1
kind: Pod
metadata:
name: pod-3
labels:
app: node01
spec:
containers:
- name: pod-3
image: wangyanglinux/myapp:v1
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- node02
topologyKey: kubernetes.io/hostname
#标签是node01,但是yaml文件写的是当app=node02,而且是硬限制。所以一会显示pending状态
[root@k8s-master-01 affi]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
node01 1/1 Running 0 59m app=node01
[root@k8s-master-01 affi]# kubectl apply -f pod3.yaml
pod/pod-3 created
[root@k8s-master-01 affi]# kubectl get pods
NAME READY STATUS RESTARTS AGE
node01 1/1 Running 0 60m
pod-3 0/1 Pending 0 5s
#重新给pod打标签app=node02,立马pod的状态变为running状态
[root@k8s-master-01 affi]# kubectl label pods node01 app=node02
error: 'app' already has a value (node01), and --overwrite is false
[root@k8s-master-01 affi]# kubectl label pods node01 app=node02 --overwrite
pod/node01 labeled
[root@k8s-master-01 affi]# kubectl get pods
NAME READY STATUS RESTARTS AGE
node01 1/1 Running 0 60m
pod-3 1/1 Running 0 42s
亲和性/反亲和性调度策略比较如下:
`topologyKey`用于指定调度时作用域,例如:
如果指定为`kubernetes.io/hostname`,那就是以Node节点为区分范围
如果指定为`beta.kubernetes.io/os,`则以Node节点的操作系统类型来区分
pod的配置项
pod.spec.affinity.podAffinity
requiredDuringSchedulingIgnoredDuringExecution 硬限制
namespaces 指定参照pod的namespace
topologyKey 指定调度作用域
labelSelector 标签选择器
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持In, NotIn, Exists, DoesNotExist.
matchLabels 指多个matchExpressions映射的内容
preferredDuringSchedulingIgnoredDuringExecution 软限制
podAffinityTerm 选项
namespaces
topologyKey
labelSelector
matchExpressions
key 键
values 值
operator
matchLabels
weight 倾向权重,在范围1-100
合体
apiVersion: v1
kind: Pod
metadata:
name: pod-3
labels:
app: node01
spec:
containers:
- name: pod-3
image: wangyanglinux/myapp:v1
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- node02
topologyKey: kubernetes.io/hostname
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- pod-2
topologyKey: kubernetes.io/hostname
参考文章:
https://www.cnblogs.com/sdrbg/category/1521817.html
https://blog.csdn.net/weixin_46837396/article/details/119897561