k8s调度分配策略

一、由 POD 指定 k8s 运行节点

# 直接指定节点名称
spec:
  nodeName: kube-01
# 通过节点标签选择节点
spec:
  nodeSelector:
    kubernetes.io/hostname: uat-xxxxx

二、设置 POD 亲和性策略

亲和性策略分为两种,一种节点亲和性,一种 POD 亲和性。

节点亲和性说白了就是约定什么样的 pod 和什么样的 node 关系比较好,可以一起玩。

而 pod 亲和性其实就是,什么样的 pod 之间关系比较好能一起玩,什么样的 pod 之间关系不好,不能一起玩。

spec:
  # 设置亲和策略
  affinity:
    # 节点亲和性
    nodeAffinity:
      # 必须要满足的条件
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                  - linux
      # 尽量要满足的优先条件(能满足最好,不满足拉倒)
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
            matchExpressions:
              - key: another-node-label-key
                operator: In # 可以使用 In,NotIn,Exists,DoesNotExist,Gt,Lt 这些操作符
                values:
                  - another-node-label-value
    # POD亲和性
    podAffinity:
      # 必须要满足的条件
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
              - key: security
                operator: In
                values:
                  - S1
          topologyKey: topology.kubernetes.io/zone # 指定粒度
    # POD反亲和性
    podAntiAffinity:
      # 尽量不要和app=elasticsearch的POD分配到同一个节点
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchExpressions:
                - key: "app"
                  operator: In
                  values:
                    - elasticsearch
            topologyKey: "kubernetes.io/hostname"

三、污点和容忍度

污点是指你可以给一个节点打上“污点”标记,这样 pod 发现这个节点很“污”,就不来了。

给节点设置污点的指令:

# 添加污点
kubectl taint nodes node1 key1=value1:effect
# 移除污点
kubectl taint nodes node1 key1:effect-

每个污点有一个 key 和 value 作为污点的标签,其中 value 可以为空,effect 描述污点的作用。当前 taint effect 支持如下三个选项:

  1. NoSchedule:表示 k8s 将不会把 Pod 调度到具有该污点的 Node 上
  2. PreferNoSchedule:表示 k8s 将尽量避免将 Pod 调度到具有该污点的 Node 上
  3. NoExecute:表示 k8s 不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已经存在的 Pod 驱逐出去
# 设置一个污点
kubectl taint nodes node1 node-role.kubernetes.io/master=:PreferNoSchedule
# 移除一个污点
kubectl taint nodes node1 node-role.kubernetes.io/master:PreferNoSchedule-
# 移除一个污点
kubectl taint nodes node1 node-role.kubernetes.io/master:NoSchedule-

设置了污点的 Node 将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod 之间产生互斥的关系,Pod 将在一定程度上不会被调度到 Node 上。 但我们可以在 Pod 上设置容忍(Toleration),意思是设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的 Node 上。

spec:
  tolerations:
    # key, vaule, effect要与Node上设置的taint保持一致
    - key: "key1"
      operator: "Equal" # Equal表示value值必须匹配
      value: "value1"
      effect: "NoSchedule"
      tolerationSeconds: 3600 # 当Pod需要被驱逐时可以在Pod上继续保留运行的时间
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoExecute"
    - key: "key2"
      operator: "Exists" # Exists表示忽略value值
      effect: "NoSchedule"
    # 不指定key,表示容忍所有的污点key
    - operator: "Exists"
    # 不指定effect,表示容忍所有的污点作用
    - key: "key"
      operator: "Exists"

参考链接: 将 Pod 指派给节点:https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/ 污点和容忍度:https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/