K8S-亲和性
亲和度详说
一、亲和性简介
1、节点亲和性
pod.spec.nodeAffinity
preferredDuringSchedulingIgnoredDuringExecution:软策略
requiredDuringSchedulingIgnoredDuringExecution: 硬策略
2、Pod 亲和性
pod.spec.affinity.podAffinity/podAntiAffinity
preferredDuringSchedulingIgnoredDuringExecution:软策略
requiredDuringSchedulingIgnoredDuringExecution: 硬策略
详细解释
软策略:结合下面的 “operator: NotIn”,意思就是尽量不要将 pod 调度到匹配到的节点,但是如果没有不匹配的节点的话,也可以调度到匹配到的节点
硬策略:结合下面的 “operator: In”,意思就是必须调度到满足条件的节点上,否则就等着 Pending
举例说明
1.可以把自己理解成一个Pod,当你来学云计算,如果你更倾向去zhangsan老师带的班级,把不同老师带的班级当作一个node的话,这个就是节点亲和性。如果你是必须要去zhangsan老师带的班级,这就是硬策略;而你说你想去并且最好能去zhangsan老师带的班级,这就是软策略
2.如果你有一个很好的朋友叫lisi,你倾向和lisi同学在同一个班级,这个就是Pod亲和性。如果你一定要去lisi同学在的班级,这就是硬策略;而你说你想去并且最好能去lisi同学在的班级,这就是软策略。软策略是不去也可以,硬策略则是不去就不行
3、键值运算关系
- In:label 的值在某个列表中
- NotIn:label 的值不在某个列表中
- Gt:label 的值大于某个值
- Lt:label 的值小于某个值
- Exists:某个 label 存在
- DoesNotExist:某个 label 不存在
4、亲和与反亲和
- 从pod出发,可以分成亲和性和反亲和性,分别对应podAffinity和podAntiAffinity
- 从node出发,也可以分成亲和性和反亲和性,分别对应nodeAffinity和nodeAntiAffinity
- 从操作指令来讲,可以有ln、Notln、Exists、DoesNotExist等等
针对亲和性来讲,in代表我要调度到有这个标签的位置
针对反亲和性来讲,in代表我不要调度到有这个标签的位置
不管哪种方式,最终还是要依赖 label 标签
调度策略 | 匹配标签 | 操作符 | 拓扑域支持 | 调度目标 |
---|---|---|---|---|
nodeAffinity | 主机 | In,NotIn,Exists,DoesNotExist, Gt, Lt | 否 | 指定主机 |
podAffinity | pod | In,NotIn,Exists,DoesNotExist | 是 | pod 与指定 pod同一拓扑域 |
podAntAffinity | pod | In,NotIn,Exists,DoesNotExist | 是 | pod 与指定 pod 不在同一拓扑域 |
5、硬策略示例
requiredDuringSchedulingIgnoredDuringExecution
vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname #指定node的标签
operator: NotIn #设置Pod安装到kubernetes.io/hostname的标签值不在values列表中的node上
values:
- node1
#也可指定标签 例:
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: xtz
operator: In
values:
- q
kubectl apply -f pod1.yaml
kubectl get pods -o wide
kubectl delete pod --all && kubectl apply -f pod1.yaml && kubectl get pods -o wide
#如果硬策略不满足条件,Pod 状态一直会处于 Pending 状态
6、软策略示例
preferredDuringSchedulingIgnoredDuringExecution
vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1 注: #如果有多个软策略选项的话,权重越大,优先级越高
preference:
matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
kubectl apply -f pod2.yaml
kubectl get pods -o wide
#把values:的值改成node1,则会优先在node01上创建Pod
kubectl delete pod --all && kubectl apply -f pod2.yaml && kubectl get pods -o wide
7、亲和性与反亲和性示例
#创建一个标签为 app=myapp01 的 Pod
vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp01
labels:
app: myapp01
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
kubectl apply -f pod3.yaml
kubectl get pods --show-labels -o wide
使用 Pod 亲和性调度
vim pod4.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp02
labels:
app: myapp02
spec:
containers:
- name: myapp02
image: soscscs/myapp:v1
affinity: #编写亲和度
podAffinity: #pod 与指定 pod同一拓扑域
requiredDuringSchedulingIgnoredDuringExecution: #制定硬策略
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp01
topologyKey: xtz
解释
仅当节点和至少一个已运行且有键为“app”且值为“myapp01”的标签 的 Pod 处于同一拓扑域时,才可以将该 Pod 调度到节点上。 (更确切的说,如果节点 N 具有带有键 xtz 和某个值 V 的标签,则 Pod 有资格在节点 N 上运行,以便集群中至少有一个具有键 xtz 和值为 V 的节点正在运行具有键“app”和值 “myapp01”的标签的 pod。)
#topologyKey 是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值,则调度器会将这两个节点视为处于同一拓扑域中。 调度器试图在每个拓扑域中放置数量均衡的 Pod。
#如果 xtz 对应的值不一样就是不同的拓扑域。比如 Pod1 在 xtz=a 的 Node 上,Pod2 在 xtz=b 的 Node 上,Pod3 在 xtz=a 的 Node 上,则 Pod2 和 Pod1、Pod3 不在同一个拓扑域,而Pod1 和 Pod3在同一个拓扑域
kubectl apply -f pod4.yaml
kubectl get pods --show-labels -o wide
使用 Pod 反亲和性调度
vim pod5.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp10
labels:
app: myapp10
spec:
containers:
- name: myapp10
image: soscscs/myapp:v1
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp01
topologyKey: kubernetes.io/hostname
#如果节点处于 Pod 所在的同一拓扑域且具有键“app”和值“myapp01”的标签, 则该 pod 不应将其调度到该节点上。 (如果 topologyKey 为 kubernetes.io/hostname,则意味着当节点和具有键 “app”和值“myapp01”的 Pod 处于相同的拓扑域,Pod 不能被调度到该节点上。)
kubectl apply -f pod5.yaml
kubectl get pods --show-labels -o wide
示例2:
vim pod6.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp20
labels:
app: myapp20
spec:
containers:
- name: myapp20
image: soscscs/myapp:v1
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp01
topologyKey: xtz
由于指定 Pod 所在的 node1 节点上具有带有键 xtz 和标签值 m 的标签,node2 也有这个xtz=m的标签,所以 node1 和 node2 是在一个拓扑域中,反亲和要求新 Pod 与指定 Pod 不在同一拓扑域,所以新 Pod 没有可用的 node 节点,即为 Pending 状态
kubectl apply -f pod6.yaml
kubectl get pod --show-labels -owide
更改个labels标签名字就可以了
kubectl label nodes node2 xtz=j --overwrite
kubectl get pod --show-labels -owide
更多推荐
所有评论(0)