kubernetes scheduler affinity 亲和性调度,打散调度
节点亲和性是节点和POD之间的关系,那些POD可以运行在那些节点上,那些POD不可以运行在那些节点上。POD亲和性是POD之间的关系,那些POD不能运行在同一个节点上,那些可以运行在同一个节点上。
requiredDuringSchedulingIgnoredDuringExecution:硬限制
preferredDuringSchedulingIgnoredDuringExecution:软限制
nodeAffinity:Pod愿意在某个节点上。
nodeAntiAffinity:Pod不愿意在某个节点上。
podAffinity:Pod愿意在一起(同样一个节点/机架)。
podAntiAffinity:Pod不愿意在一起。
topologySpreadConstraints:打散调度,不让相同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 # 权重 # 先检查硬性限制,如果硬性限制有多节点符合条件,再检查软性限制
补充:
preferredDuringSchedulingIgnoreDuringExecution:软亲和性;不管节点上能否满足设定条件,Pod都可以被调度,只是Pod优先被调度到符合条件多的节点上。 - preference:# 与相应权重相关联的节点选择器项。 matchExpressions:# 按节点标签列出的节点选择器要求列表 - key: # 键 operator:# 表示键与一组值的关系。有效的运算符有:In、NotIn、Exist、DoesNotExsit。GT和LT values: # 值;若operator为In或NotIn则值必须为非空;若operator为Exists或DoesNotExist则值必须为空;若operator为Gt或Lt则值必须有一个元素。 matchFields:# 按节点字段列出的节点选择器要求列表 - key: # 键 operator:# 表示键与一组值的关系。有效的运算符有:In、NotIn、Exist、DoesNotExsit。GT和LT values: # 值;若operator为In或NotIn则值必须为非空;若operator为Exists或DoesNotExist则值必须为空;若operator为Gt或Lt则值必须有一个元素。 weight: # 权重,0~100的数值
不必完全符合定义的要求,符合最好:
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
字段选择matchFields:区别在于上面的选择的是label,这里选择的是字段。
nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchFields: - key: metadata.name # k8s资源中的字段 operator: In values: - target-host-name
参考:
https://www.cnblogs.com/Smbands/p/10949478.html
打散调度topologySpreadConstraints:
apiVersion: apps/v1 kind: Deploymentmetadata: name: nginxspec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: DoNotSchedule labelSelector: - matchLabels: app: nginx containers: - name: nginx image: nginx
将所有 nginx 的 Pod 严格均匀打散调度到不同节点上,不同节点上 nginx 的副本数量最多只能相差 1 个,如果有节点因其它因素无法调度更多的 Pod (比如资源不足),那么就让剩余的 nginx 副本 Pending
更多用法:
imroc.cc/k8s/ha/pod-split-up-scheduling/ kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/