在 Kubernetes 中,Taints 和 Tolerations 是两个非常重要的概念,它们可以帮助我们在调度 Pod 时,控制哪些节点可以被分配,哪些不能被分配。本文将会对 Taints 和 Tolerations 进行详细介绍,并给出使用场景和示例代码。
Taints 和 Tolerations 是什么?
在 Kubernetes 中,Taints 是一种标记,可以被添加到节点上。每个 Taint 由三部分组成:一个 key、一个 value 和一个 Effect。key 和 value 通常被用于对节点进行分类,而 Effect 则指定了这个 Taint 对节点分配的影响。
在一个节点上,Taint 可以被添加多个,并且不同的 Taint 可以设置不同的 Effect。常见的 Taint Effect 有以下三种:
- NoSchedule:如果一个节点被添加了 NoSchedule 的 Taint,那么任何没有设置对应 Tolerations 的 Pod 都不能被分配到该节点上。
- PreferNoSchedule:如果一个节点被添加了 PreferNoSchedule 的 Taint,那么任何没有设置对应 Tolerations 的 Pod 都不会优先被分配到该节点上,但并非不能被分配。
- NoExecute:如果一个节点被添加了 NoExecute 的 Taint,那么任何没有设置对应 Tolerations 的 Pod 都不能在该节点上运行,同时如果一个已经在该节点上运行的 Pod 没有在对应的时限内设置 Tolerations,那么该 Pod 会被删除。
与 Taint 对应的是 Tolerations,Tolerations 可以被设置在 Pod 上,用于标记哪些节点可以被分配。每个 Tolerations 由两部分组成:一个 key 和一个 operator。如果一个 Tolerations 的 key 与一个节点上的 Taint 的 key 相等并且 operator 相当,那么这个 Pod 就可以被分配到这个节点上。
在 Pod 中设置 Tolerations 时,还可以设置效果的时限,可以指定一个过渡时间,在这个时间内,即使一个节点被添加了 NoExecute 的 Taint,如果一个已经在该节点上运行的 Pod 设置了对应的 Tolerations,那么这个 Pod 也不会被删除。
Taints 和 Tolerations 的使用场景
Taints 和 Tolerations 通常被用于以下三种情况:
在一个集群中,有一些节点的硬件配置比其他节点要好,我们希望将一些高负载的 Pod 分配到这些节点上。可以通过在这些节点上添加 Taint,并在一些需要用到这些节点的 Pod 上设置对应的 Tolerations。
在一个集群中,有一些节点是专门用于运行一些调试或测试的任务,这些任务通常比较占用资源,为了避免影响正式任务的运行,可以给这些节点添加一些 Taint 并设置对应的 Tolerations,在调试或测试任务中设置这些 Tolerations。
在集群中有一些节点用于管理任务,如 etcd、kube-apiserver,通常不希望其他任务被分配到这些节点上,可以设置 NoSchedule 的 Taint 来避免这个问题。
Taints 和 Tolerations 的实践
下面我们将通过一个例子来讲解如何在 Kubernetes 中使用 Taints 和 Tolerations 进行调度。
首先我们需要创建一个集群,这里使用 Minikube 来创建一个本地测试集群:
minikube start --cpus 4 --memory 4g
然后我们可以通过 kubectl 命令来添加一个 Taint,给当前运行的节点添加一个 key 为 "special",value 为 "true",Effect 为 "NoSchedule" 的 Taint:
kubectl taint nodes $(kubectl get nodes -o=jsonpath='{.items[0].metadata.name}') special=true:NoSchedule
这里我们选择给当前唯一的节点添加 Taint,这个 Taint 的作用是禁止运行没有设置对应 Tolerations 的 Pod。
接下来我们创建一个包含 Tolerations 的 Pod,并进行测试:
-- -------------------- ---- ------- ----------- -- ----- --- --------- ----- --------------- ----- ----------- - ----- ----- ------ ------------ ------------ - ---- --------- --------- ------- ------ ------ ------- ------------
在上面的 YAML 文件中,我们定义了一个 Pod,给这个 Pod 增加一个 Tolerations,这个 Tolerations 的 key 等于上面添加 Taint 时的 key,而且它的 operator 和 value 分别等于上面添加 Taint 时的 operator 和 value,即它可以被分配到被添加了 Taint 的节点上。
通过 kubectl apply 命令来创建该 Pod:
kubectl apply -f tolerations-pod.yaml
然后我们可以通过 kubectl get pod 查看该 Pod 的状态,可以看到该 Pod 已经被分配到了被添加了 Taint 的节点上:
NAME READY STATUS RESTARTS AGE tolerations-pod 1/1 Running 0 2m
如果我们尝试创建一个没有设置 Tolerations 的 Pod,可以看到该 Pod 会被调度到一个没有被 Taint 的节点上:
apiVersion: v1 kind: Pod metadata: name: no-tolerations-pod spec: containers: - name: nginx image: nginx:latest
使用 kubectl apply 创建该 Pod,然后通过 kubectl get pod 查看状态:
NAME READY STATUS RESTARTS AGE no-tolerations-pod 1/1 Running 0 14s tolerations-pod 1/1 Running 0 48m
可以看到该 Pod 已经被成功调度到了没有被 Taint 的节点上。
总结
本文对 Kubernetes 中的 Taints 和 Tolerations 进行了详细的介绍,并给出了具体的使用场景和示例代码。在实际的项目中,Taints 和 Tolerations 可以帮助我们实现更精细的调度策略,避免资源的浪费和任务的阻塞。如果你对 Kubernetes 的调度机制感兴趣,Taints 和 Tolerations 的深入学习是非常值得推荐的。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66470cbfd3423812e454b74d