kuburnetes的Taints与Tolerations

Node亲和性,详细参考这里,指pod的一种属性,以偏好或者硬性要求的方式指示将pod部署到相关的node集合中。Taints与此相反,允许node抵制某些pod的部署,注意taints是node的属性,affinity是pod的属性。

Taints与tolerations一起工作确保pod不会被调度到不合适的节点上。单个节点可以应用多个taint,node应该不接受无法容忍taint的pod调度。Toleration是pod的属性,允许(非强制)pod调度到taints相匹配的node上去。

概念

通过kubectl taint为node添加taint,如:

kubectl taint nodes node1 key=value:NoSchedule

为node node1增加一条taint。Taint的关键字为key,值为value,taint影响NoSchedule。意味着没有pod会被调度到node1上,除非它有匹配的toleration。

为node1删除刚才添加的taints,如下:

kubectl taint nodes node1 key:NoSchedule-

可以为pod指定toleration。以下的两种toleration都与上文中创建的taint匹配,因此这个pod有可能被调试到node1上。

tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"
Toleration与taint匹配的条件是key相同、effect相同,并且:
  • Operator的值是Exists(无需指定values的值)
  • Operator是Equal,并且values的值相等

如果不指定,operator默认是Equal。

注意:两种特殊情况。

  • Key为空,operator为Exists表示匹配所有的key。如下例表示匹配所有的taint:
tolerations:
- operator: "Exists"
  • 空effect表示匹配所有effect,如:
tolerations:
- key: "key"
  operator: "Exists"

上例中用到了NoSchedule的effect。另外,可以使用PreferNoSchedule的effect,这是NoSchedule的“偏好”或者“软“版本。系统尽量避免非tolerate的pod调度到taint node上,但非强制要求。第三种可用的effect是NoExecute,后文描述。

可以为单个node指定多条taint,也可以为单个pod指定多条toleration。系统采用过滤的方式处理这种情况:首先从node的所有taint开始,然后将与pod中的toleration相匹配的taint删除,余下的taint对部署进来的pod产生影响。特别地:

  • 如果余下的taint中至少有一条的effect是NoSchedule,kubernetes将不会高度这个pod到的node上。
  • 如果余下的taint中没有effect为NoSchedule的taint,但至少有一条effect为PreferNoSchedule,则系统尝试着不将pod部署在node上(也就是有可能还是会部署到这个node上)。
  • 如果余下的taint中至少有一条的effect是NoExecute,那么不旦pod不会被调度到这个node上,而且已经运行在这个node上的pod还会被排除。

例如,假如像这样taint一个node:

kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule

pod有两个toleration:

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"

这种情况下,pod不能调度到node上。因为pod没有toleration与node的第三条taint匹配。但是在添加taint之前已经运行在node上的pod不受影响(这里之前运行的pod指添加了toleration的pod),可能将pod排除出node的noExecute因为被过滤而没有生效。

一般情况下,如果一个effect为NoExecute的taint应用于node,运行在node上的所有不能容忍这条taint的pod都会被排挤出node,能容忍这种taint的pod则不会被排挤。然而,如果effect为NoExecute的toleration指定给pod,同时添加可选的tolerationSeconds字段,则表示pod被排挤出node之前,以taint的添加时间为起点,允许此pod在此node上的生存时间。

例如:

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationSeconds: 3600

表示可以多存活3600秒。

使用案例

Taints与tolerations可以灵活的控制pod远离node,或者将不应该运行的pod从node上排挤出去。以下是几个使用案例:

  • 专用node:如果打算指定特定node集合供特定用户专用,那么可以给这些node添加一条taint(kubectl taint nodes nodename dedicated=groupName:NoSchedule),然后在相应的pod上添加匹配的toleration(this would be done most easily by writing a custom admission controller)。拥有teleration的pod被允许像使用集群中的其它node一样使用拥有taint的node。如果打算让pod只使用taint性质的node,并且只能使用taint的node的话,可以对这些taint的node再额外增加标签(e.g. dedicated=groupName),然后再通过入口控制器为这些pod额外再增加亲和性要求它们只能部署到拥有dedicated=groupName的node上。总结就是通过标签的亲和性控制pod部署到特定的node上,通过为node增加taint并且为pod增加toleration抵制其它pod部署到这些node上,从而实现node专用。
  • 拥有特殊硬件的node:在集群中,有少数node拥有特殊的硬件配置(for example GPUs),希望那些不使用特殊的硬件的pod尽量不要部署到这些拥有特殊硬件的node上,为后续到达的需要使用特殊硬件的pod预留出空间。通过如下方法达到这个目的。首先为node添加taint,taint表示node拥有特殊硬件(e.g. kubectl taint nodes nodename special=true:NoSchedule or kubectl taint nodes nodename special=true:PreferNoSchedule),然后为需要使用特殊硬件的pod添加相应的toleration。像专用node的例子一样,通过入口控制器很容易为pod添加对应的toleration。例如:推荐使用“扩展资源”代表特殊硬件,使用“扩展资源”的名称为拥有特殊硬件的node添加taint,当提交的pod被配置为需要使用特殊硬件时,扩展资源入口控制器自动为其加上正确的toleration。
  • 基于taint的驱逐(测试特性):一种当node出现问题时per-pod-configurable的驱逐行为,下节介绍。

基于taint的驱逐

先前提到的effect为NoExecute的taint,它对已经运行在node上的pod的影响如下:
  • 如果pod没有toleration这个taint的话,pod立即被驱逐。
  • 如果toleration了这个taint,并且没有指定tolerationSeconds的值,则一直不会驱逐
  • 如果toleration了这个taint,但是指定tolerationSeconds限定了容忍的时间,则到期后驱逐

基于condition的taint

从kubernetes 1.6开始支持一种测试特性,就是用taint代表node出了问题。具体点就是当描述node状态的某个condition为true时,node controller自动为node添加taint,下以是系统内建的taint(格式特殊,普通用户不能使用):

  • node.kubernetes.io/not-ready: Node is not ready. This corresponds to the NodeCondition Ready being “False”.
  • node.kubernetes.io/unreachable: Node is unreachable from the node controller. This corresponds to the NodeCondition Ready being “Unknown”.
  • node.kubernetes.io/out-of-disk: Node becomes out of disk.
  • node.kubernetes.io/memory-pressure: Node has memory pressure.
  • node.kubernetes.io/disk-pressure: Node has disk pressure.
  • node.kubernetes.io/network-unavailable: Node’s network is unavailable.
  • node.kubernetes.io/unschedulable: Node is unschedulable.
  • node.cloudprovider.kubernetes.io/uninitialized: When the kubelet is started with “external” cloud provider, this taint is set on a node to mark it as unusable. After a controller from the cloud-controller-manager initializes this node, the kubelet removes this taint.

总结起来就是node controller对node执行各种条件测试,当node出现问题时如不可达、资源耗尽等,由node controller自动为node添加系统内置的相关的taint,scheduler在调度pod时通过确认node的taint而非condition决定是否调度。这种方式更加灵活,但是增加了一个将condition映射成taint的步骤。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值