1.前言
k8s的亲和性和反亲和性都是通过标签来影响pod的调度,在此基础上亲和性又分为硬亲和性和软亲和性,required为硬亲和性即标签内容必须要符合才能调度,preferred为软亲和性即标签内容不一定要符合也能调度,除此之外还有node亲和性和pod亲和性,接下来都使用一下这些亲和性的功能
2.node亲和性
2.1node软亲和性
先编辑一个yaml文件
vi deployment-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
replicas: 5
progressDeadlineSeconds: 600
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity: #亲和性配置项
nodeAffinity: #node亲和性配置项
preferredDuringSchedulingIgnoredDuringExecution: #软亲和性配置项
- weight: 70 #配置权重
preference:
matchExpressions:
- key: key1 #配置标签key的值
operator: In #配置操作符
values: #配置标签values的值
- value1
- weight: 30 #配置权重
preference:
matchExpressions:
- key: key2
operator: In
values:
- value2
配置一下node节点的标签,给node01节点打上权重高的标签,node02节点打上权重低的标签
kubectl label node k8s-node01 key1=value1
kubectl label node k8s-node02 key2=value2
执行yaml文件
kubectl create -f deployment-nginx.yaml
查看一下pod再node上的分配情况
kubectl get pod -o wide -n default -l app=nginx
可以看到node01上分配的pod比node02节点多,这就是权重导致的,软亲和性是不强制要求调度到特定节点的,可以把node节点的label标签删掉,再重新创建delpoyment,pod依然能正常调度,我这里只贴一下效果,就不展示过程了
2.2node硬亲和性
编辑一下yaml文件
vi deployment-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
replicas: 5
progressDeadlineSeconds: 600
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: #硬亲和性配置项
nodeSelectorTerms: #通过 nodeSelectorTerms,可以指定多个节点标签的匹配规则,从而更加灵活地控制 Pod 的调度,再有多个nodeSelectorTerms时,他们的关系为或,即node节点满足任意一个nodeSelectorTerms中的规则时,就可以把pod调度到该节点上
- matchExpressions: #通过 matchExpressions,可以精确地指定一个节点标签的匹配规则,从而更加精细地控制 Pod 的调度,在使用多个matchExpressions的情况下,他们的关系为且,即node节点需要满足所有matchExpressions项的规则才可以把pod调度到该节点上
- key: key1
operator: In
values: #这里配置了两个values值,因为控制项使用的是In,只要node满足其中一个即可调度
- value1
- value2
我现在的node节点上是没有标签的,先来测试一下pod的调度情况
可以看到因为设置了硬亲和性的原因pod调度不到任何一个node节点上,状态为pending,接下来我们给node01打上符合yaml文件硬亲和性的标签看看效果
kubectl label node k8s-node01 key1=value1
可以看到给node01节点打上标签后,所有pod都调度到了node01节点上了
3.pod亲和性和反亲和性
3.1pod软亲和性
编辑一下yaml文件
vi deployment-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
replicas: 5
progressDeadlineSeconds: 600
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity:
podAffinity: #pod亲和性配置项
preferredDuringSchedulingIgnoredDuringExecution: #软亲和性配置项
- weight: 70 #配置权重
podAffinityTerm:
labelSelector:
matchExpressions:
- key: key1
operator: In
values:
- value1
topologyKey: zone #在 PodAffinity 中,topologyKey 配置项用于指定 Pod 应该调度到哪些节点上。例如,可以将 topologyKey 设置为 kubernetes.io/hostname,这样 Pod 将调度到与它在同一主机上的节点上
- weight: 30
podAffinityTerm:
labelSelector:
matchExpressions:
- key: key2
operator: In
values:
- value2
topologyKey: zone
执行以下yaml文件看一下效果
kubectl create -f deployment-nginx.yaml
pod软亲和性表示Pod将尽可能被调度到与它们亲和的pod所在的节点上,但如果没有符合条件的pod,Pod仍然可以被调度到其他节点上
3.2pod硬亲和性
编辑一下yaml文件
vi deployment-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
replicas: 5
progressDeadlineSeconds: 600
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution: #硬亲和性配置项
- labelSelector:
matchExpressions:
- key: key1
operator: In
values:
- value1
topologyKey: kubernetes.io/hostname
执行以下yaml文件看一下效果
kubectl create -f deployment-nginx.yaml
现在集群中是没有pod的,没有可以满足pod硬性亲和条件的pod,所以pod无法调度,现在创建两个不符合以上条件标签的pod看看效果
vi web1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web1
spec:
replicas: 2
selector:
matchLabels:
key3: value3
template:
metadata:
labels:
key3: value3 #这里pod使用的标签和上面亲和性的标签不一致
spec:
containers:
- image: nginx:1.19
name: nginx1
kubectl create -f web1.yaml
kubectl get pod -o wide
可以看到依旧没有满足硬亲和性调度的条件,pod还是pending状态,接下来创建一个符合以上条件标签的pod看看效果
vi web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
key1: value1
template:
metadata:
labels:
key1: value1 #此处使用与硬亲和性条件一样的label
spec:
containers:
- image: nginx:1.19
name: nginx
kubectl create -f web.yaml
kubectl get pod -o wide
可以看到有满足硬亲和性条件标签的pod后,所有pod都调度到了与该pod相同的节点上
pod硬亲和性表示Pod必须被调度到与它们亲和的pod的节点上,否则它们将无法被调度
3.3pod硬反亲和性
编辑一下yaml文件
vi deployment-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
replicas: 5
progressDeadlineSeconds: 600
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity:
podAntiAffinity: #反亲和性配置项
requiredDuringSchedulingIgnoredDuringExecution: #硬反亲和性配置项
- labelSelector:
matchExpressions:
- key: key1
operator: In
values:
- value1
topologyKey: zone #避免pod调度到故障节点上
上一个试验创建的web和web1的pod还没删除,使用他们来验证一下硬反亲和性,web使用的标签是符合硬反亲和性的条件,执行一下这个yaml看看效果
kubectl create -f deployment-nginx.yaml
kubectl get pod -o wide
可以看到因为硬反亲和性的原因,所有创建的nginx pod都和web pod不在同一个节点上
3.4pod软反亲和性
编辑一下yaml文件
vi deployment-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
replicas: 5
progressDeadlineSeconds: 600
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity:
podAntiAffinity: #反亲和性配置项
preferredDuringSchedulingIgnoredDuringExecution: #软反亲和性配置项
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: key1
operator: In
values:
- value1
topologyKey: zone
依然使用带有符合反亲和性条件的web pod,执行一下yaml看看效果
kubectl create -f deployment-nginx.yaml
kubectl get pod -o wide
可以看到因为软反亲和性的原因,有一些nginx pod调度到了和web pod相同的节点上
亲和性和反亲和性的使用展示就这么多,接来下所以下上面使用到的配置项的补充
operator:用于指定匹配规则的操作符,operator参数可以设置为In、NotIn、Exists、DoesNotExist、Gt、Lt、Gte、Lte、DoubleEqual、NotEqual等值中的一种
In:表示标签的值必须包含在给定的值列表中
NotIn:表示标签的值不能包含在给定的值列表中
Exists:表示标签必须存在
DoesNotExist:表示标签必须不存在
Gt:表示标签的值必须大于给定的值
Lt:表示标签的值必须小于给定的值
Gte:表示标签的值必须大于或等于给定的值
Lte:表示标签的值必须小于或等于给定的值
DoubleEqual:表示标签的值必须等于给定的值
NotEqual:表示标签的值不能等于给定的值
在软亲和性和软反亲和性的配置中,topologyKey项是必须要配置的,不配置的话执行yaml文件会报错