Kubernetes使用Pod来作为集装箱装载你的服务,然后将这些Pod调度到节点上去执行。完成调度工作的是Kubernetes组件“kube-scheduler”,除了集群的自动调度外,依赖“Taints”和“Tolerations”也可以实现Pod的人为调度。
一个例子
今天收到告警:演示环境的redis服务异常,登录Kubernetes集群发现Redis Pod没有调度成功,一直提示“Pending”状态,事件输出如下,

因为这个redis使用了“HostPath”类型的卷,必须要调度到服务器10.0.10.123上,从上图看出是因为服务器加了“Taints”导致,查看服务器10.0.10.123的“Taints”详情,

我们的k8s服务器都跑一个守护进程,当服务器的硬盘空间不足时,守护进程会自动给服务器加上这个“Taints”,问题找到了,如何解决呢?有两种思路,一是手动去掉这个节点的“Taints”,二是配置Pod的容忍度,容忍这个“Taints”,因为Redis Pod使用的硬盘空间不大,这里选择第二种,编辑Redis的“deployments”,增加下面配置,

增加Tolerations
配置加入后,可以看到Redis Pod正常的调度并运行起来了,
那么什么是“Taints”,怎么配置“Taints”?
手动给节点加“Taints”很简单,
kubectl taint nodes node1 key1=value1:NoSchedule
取消“Taints”,只需要加一个减号(-)即可,
kubectl taint nodes node1 key1=value1:NoSchedule-
“Taints”由三部分组成:key,value,effort,上面“Taints”的effort就是“NoSchedule”。有三种类型的effort:“NoExecute”,“NoSchedule”和“PreferNoSchedule”,关于它们的具体含义,为了不使这篇文章显得冗繁,请参考官网。
上例“Taints”的key是“
node.kubernetes.io/disk-pressure”,effort是“NoSchedule”,可以看到它没有value,这个是可以接受的。因为没有value,“tolerations”对象中的键“operator”给了值“Exists”,如果有值,“operator”就为“Equal”。
比如有个“Taints”为key1=value1:NoSchedule,要容忍这个“Taints”,“tolerations”就要如下配置
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
这样配置后,你的Pod就可以调度到有上面“Taints”的节点上。