一般情况部署的Pod是通过集群的自动调度策略来选择节点,默认情况下调度器考虑的是资源足够,并且负载尽量平均。但是有时候我们并不需要一些服务都部署在同一节点上,害怕服务之间产生影响;但是有时候也需要部署在同一节点上。这时候就用到了亲和性与反亲和性
亲和性种类:nodeAffinity(节点亲和性)、podAffinity(Pod亲和性)
首先了解最常见与简单的调度方法nodeSelector。通过匹配label去匹配Pod资源。查看node的label
kubectl get nodes --show-labels
为node添加label
kubectl label nodes node1 app=test
之后在Pod的yaml文件中的spec字段添加即可,文档添加的是node-role.kubernetes.io/worker(kubernetes内置节点标签)
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
app: test
调度策略:软策略与硬策略
控制pod可以部署在哪些node上,不可以在那些node上。
示例分析
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: affinity
spec:
replicas: 2
revisionHistoryLimit: 15
template:
metadata:
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: nginxweb
affinity:
nodeAffinity: #节点亲和
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
nodeSelectorTerms:
- matchExpressions: #匹配label
- key: kubernetes.io/hostname
operator: NotIn
values:
- node03
preferredDuringSchedulingIgnoredDuringExecution: # 软策略
- weight: 1
preference:
matchExpressions:
- key: app
operator: In
values:
- test
解释说明:不能运行在node03节点上。如果有节点满足app=test,就先调度到这个节点上。
操作符operator:
注:如果指定多个nodeSelectorTerms,满足其中一个即可
如果指定多个matchExpressions,必须满足所有
示例分析
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone #内置节点标签
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: failure-domain.beta.kubernetes.io/zone
containers:
- name: with-pod-affinity
image: k8s.gcr.io/pause:2.0
内置节点标签如下:
kubernetes.io/hostname
failure-domain.beta.kubernetes.io/zone
failure-domain.beta.kubernetes.io/region
beta.kubernetes.io/instance-type
kubernetes.io/os
kubernetes.io/arch
文件解释说明:在这个 pod 的 affinity 配置定义了一条 pod 亲和规则和一条 pod 反亲和规则。在此示例中,podAffinity 配置为 requiredDuringSchedulingIgnoredDuringExecution,然而 podAntiAffinity 配置为 preferredDuringSchedulingIgnoredDuringExecution。pod 亲和规则表示,仅当节点和至少一个已运行且有键为“security”且值为“S1”的标签的 pod 处于同一区域时,才可以将该 pod 调度到节点上。(更确切的说,如果节点 N 具有带有键 failure-domain.beta.kubernetes.io/zone 和某个值 V 的标签,则 pod 有资格在节点 N 上运行,以便集群中至少有一个节点具有键 failure-domain.beta.kubernetes.io/zone 和值为 V 的节点正在运行具有键“security”和值“S1”的标签的 pod。)pod 反亲和规则表示,如果节点已经运行了一个具有键“security”和值“S2”的标签的 pod,则该 pod 不希望将其调度到该节点上。(如果 topologyKey 为 failure-domain.beta.kubernetes.io/zone,则意味着当节点和具有键“security”和值“S2”的标签的 pod 处于相同的区域,pod 不能被调度到该节点上。)
操作符:In NotIn Exists DoesNotExist
topologyKey 可以是任何合法的标签键。然而,出于性能和安全原因,topologyKey 受到一些限制
示例2
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: affinity
labels:
app: affinity
spec:
replicas: 2
revisionHistoryLimit: 15
template:
metadata:
labels:
app: affinity
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: nginxweb
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- busybox-pod
topologyKey: kubernetes.io/hostname
解释:如果一个节点上面有一个app=busybox-pod这样的 pod 的话,那么我们的 pod 就别调度到这个节点上面来