【笔记】k8s之Taint(瑕疵)、Toleration(容忍)、NodeSelector使用小结
文章目录
1. 故事背景
目前我只有一个k8s集群,测试和生产环境都在这个集群里。测试环境是未经测试的版本,有可能会因为BUG而拉垮机器。为了避免这个风险,我有两个选择:
建立两个集群,把生产和测试分离
同一个集群,但把测试的服务调度到指定的节点上。
基于成本,我选择了第二个方案。
2. 提前准备
- 本次试验是在
CentOS 7.4 64位
系统 - 拥有
Kubernetes集群
3. Taints and Tolerations
k8s通过Taints/Tolerations
机制,可以让那些心胸宽广(容忍)的Pod才可以接受(调度到)这个有缺陷(瑕疵)的节点上。
当Node(节点)被打上Taint(瑕疵)后,因为Pod追求“完美”,正常的Pod是不会被调度至有瑕疵的节点(Master节点就是利用了这个特性)。如果Pod比较大度,可以Toleration(容忍)这些Taint(瑕疵),那么是可以调度到这个节点的。
根据背景,我需要在测试节点上,打上Taint(瑕疵):
# 简易语法说明,详细看官方文档,NoSchedule是effect的一种
kubectl taint nodes {node-name} {key}={value}:NoSchedule
# 我的实践,test=true表达这个节点是测试环境的节点
kubectl taint nodes k8s-test test=true:NoSchedule
执行之后,不会有新的Pod调度至此,不过原来就在此节点的Pod不会被驱逐。
“瑕疵”有了,测试环境的Pod也需要“容忍”TA才可以调度至此:
# 因为我用的Deployment,我以此为例,如果你直接用Pod,也是一样的
# 在节点spec.template.spec下,新增tolerations
tolerations:
- key: "test"
operator: "Exists"
effect: "NoSchedule"
上面的例子表达可以容忍key为”test”(只需要存在即可,不需要判断value),并且effect为”NoSchedule”的节点。
至此,我的测试Pod便可以调度至这个有瑕疵的节点上了。
4. NodeSelector
上一节完成后,看起来已经完成我的需求了,实际上并没有。上一节完成的需求仅仅是测试Pod可以在测试节点上调度,但测试Pod并非100%调度至测试节点上。(我虽然容忍你,但我不一定选你)
为了完成目的,我们可以这样做:
# 首先给节点打标签label(同样表示测试环境)
kubectl label nodes k8s-test test=true
# 在Deployment描述文件里,节点spec.template.spec下,新增nodeSelector
nodeSelector:
test: "true"
通过NodeSelector让Pod选择符合条件的节点,就可以满足我的需求了。
5. 总结
- 首先,节点通过新增
Taint
(瑕疵)来拒绝Pod调度 - 其次,Pod增加
Toleration
表示容忍这个瑕疵,拥有了调度至此的条件 - 最后,Pod通过
nodeSelector
,告诉k8s一生只爱TA,不愿意调度去其他节点
🙂联姻成功,恭喜💐
6. 题外话
在Taint的实践上,我遇过一个问题。上面的实践中,effect
使用了NoSchedule
,我也说明了,原来在此节点上的Pod不会被驱逐。
在我一开始实践时,使用的是NoExecute
,这个effect
则会驱逐不该在这里生存的Pod。
对于业务Pod没关系,而那些系统类、工具辅助类的Pod则有影响,譬如:flannel、traefik等,会导致网络不正常,还有些收集日志的Pod等等,他们存在的形式大多是daemonset。
最后我把Taint删掉,等Daemonset类的Pod同步完成后,再改为NoSchedule
,就一切正常了。
删除的例子:
# 简易说明,注意后面的减号
kubectl taint nodes {node-name} {key}:{effect}-
# 实例
kubectl taint nodes k8s-test test:NoExecute-
文章作者 xifan
上次更新 2018-09-25