节点亲和性是节点和POD之间的关系,那些POD可以运行在那些节点上,那些POD不可以运行在那些节点上。POD亲和性是POD之间的关系,那些POD不能运行在同一个节点上,那些可以运行在同一个节点上。


requiredDuringSchedulingIgnoredDuringExecution:硬限制

preferredDuringSchedulingIgnoredDuringExecution:软限制

nodeAffinity:Pod愿意在某个节点上。

nodeAntiAffinity:Pod不愿意在某个节点上。

podAffinity:Pod愿意在一起(同样一个节点/机架)。

podAntiAffinity:Pod不愿意在一起。


预选函数中SelectorSpreadPriority会自动做选择。


nodeSelector与nodeAffinity是与关系。



节点亲和性 nodeAffinity:

        根据匹配到的条目的权重相加,匹配到的越多亲和性越高。

必须要符合定义的要求:

apiVersion: v1
kind: Pod
metadata:
  name: node-affinity-required
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: myapp:v1
  affinity: 
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
        nodeSelectorTerms: # 节点选择条件,定义多个nodeSelectorTerms是“或”关系
        - matchExpressions: # 标签选择器,多个matchExpressions 是“或”关系
          - key: zone # 需要有zone这个标签存在,多个key是“与”关系
            operator: In # 基于集合的标签选择器类似in_array
            values: # 二者之一符合条件即可
            - foo
            - bar
      preferredDuringSchedulingIgnoredDuringExecution: # 软限制
      - preference: # 定义倾向性
          matchExpressions: # 标签选择
          - key: zone # 有这个标签名称
            operator: In # 集合类型的选择器
            values: # 有这些标签的节点运行在这些节点,如果没有再选择其他的节点
            - foo
            - bar
        weight: 60 # 权重
        
        # 先检查硬性限制,如果硬性限制有多节点符合条件,再检查软性限制

不必完全符合定义的要求,符合最好:

apiVersion: v1
kind: Pod
metadata:
  name: node-affinity-preferred
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: myapp:v1
  affinity: 
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution: # 软亲和性
      - preference: # 定义倾向性
          matchExpressions: # 标签选择
          - key: zone # 有这个标签名称
            operator: In
            values: # 有这些标签的节点运行在这些节点,如果没有再选择其他的节点
            - foo
            - bar
        weight: 60 # 权重


Pod亲和性 podAffinity:

让后面的Pod跟着前一个Pod运行在同一个节点上,使用标签控制。

apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  namespace: default
  labels:
    app: backend
    tier: db
spec:
  containers:
  - name: nginx
    image: nginx:v1
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions: 
          - key: app
            operator: In
            values: 
            - myapp  # 让后一个Pod运行在和第一个Pod相同的节点上
        topologyKey: kubernetes.io/hostname   #根据节点的主机名

上面的两个Pod会运行在同一个节点上。


反亲和性 podAntiAffinity:

让后面的Pod不能和前一个Pod运行在同一个节点上,根据标签来判定。

apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  namespace: default
  labels:
    app: backend
    tier: db
spec:
  containers:
  - name: nginx
    image: nginx:v1
  affinity:
    podAntiAffinity:  # 使用的是 podAntiAffinity
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions: 
          - key: app
            operator: In
            values: 
            - myapp
        topologyKey: kubernetes.io/hostname

上面的两个Pod不会运行在同一个节点上。


方法二:节点上打上标签,根据节点标签来验证反亲和性。

节点打标签:

kubectl label nodes node1 zone=foo
kubectl label nodes node2 zone=foo

yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  namespace: default
  labels:
    app: backend
    tier: db
spec:
  containers:
  - name: nginx
    image: nginx:v1
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions: 
          - key: app
            operator: In
            values: 
            - myapp
        topologyKey: zone