llhuii / dive-into-k8s

Apache License 2.0
0 stars 0 forks source link

污点和容忍度源码分析 #1

Open llhuii opened 3 years ago

llhuii commented 3 years ago

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/

  1. 给节点打污点: kubectl taint nodes node1 key1=value1:NoSchedule
  2. 给pod打容忍度:
    tolerations:
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoSchedule"

容忍度和污点不匹配的条件:

  1. 容忍度的Effect不为空且与污点的Effect不相等
  2. 容忍度的Key存在且与污点的key不相等
  3. 容忍度的operator值:
    • 值为空或者Equal时,Value不相等
    • 值非Exists

代码:

  1. scheduler filter 插件:code.k8s.io/pkg/scheduler/framework/plugins/tainttoleration/taint_toleration.go
  2. 匹配规则: code.k8s.io/vendor/k8s.io/api/core/v1/toleration.go

    // ToleratesTaint checks if the toleration tolerates the taint.
    // The matching follows the rules below:
    // (1) Empty toleration.effect means to match all taint effects,
    //     otherwise taint effect must equal to toleration.effect.
    // (2) If toleration.operator is 'Exists', it means to match all taint values.
    // (3) Empty toleration.key means to match all taint keys.
    //     If toleration.key is empty, toleration.operator must be 'Exists';
    //     this combination means to match all taint values and all taint keys.
    func (t *Toleration) ToleratesTaint(taint *Taint) bool {
    if len(t.Effect) > 0 && t.Effect != taint.Effect {
        return false
    }
    
    if len(t.Key) > 0 && t.Key != taint.Key {
        return false
    }
    
    // TODO: Use proper defaulting when Toleration becomes a field of PodSpec
    switch t.Operator {
    // empty operator means Equal
    case "", TolerationOpEqual:
        return t.Value == taint.Value
    case TolerationOpExists:
        return true
    default:
        return false
    }
llhuii commented 3 years ago

所以kind创建名为kindnet(用于配置cni和更新路由规则的网络插件)的daemonset pod template存在

spec:
  template:
    spec:
      tolerations:
      - effect: NoSchedule
        operator: Exists

表示可以容忍到任意打了NoSchedule污点的节点

节点的污点除了kubectl taint打, 还包括:

  1. kubectl cordon, 节点新增以下状态:

    taints:
    - effect: NoSchedule
      key: node.kubernetes.io/unschedulable
      timeAdded: "2021-06-05T16:40:35Z"
    unschedulable: true    
  2. code.k8s.io/pkg/controller/nodelifecycle/node_lifecycle_controller.go 会给节点打上以下污点:

    • key=node.kubernetes.io/unreachable, effect=NoExecute
    • key=node.kubernetes.io/not-ready, effect=NoExecute
    • 其他, effect=NoSchedule