污点是一块“闲人勿进”的牌子,容忍度则是通行证,于是你可以要求预算型、GPU 或竞价节点只接纳匹配的负载。
给专用者的标记 污点(taint)把节点标成「闲人勿进」,而它本质上是一块牌子,不是一个动作:光打污点并不会把已经运行的东西搬走。新来的 Pod 只要没带匹配的容忍度就绕开,容忍度才是那张「通行证」。这正是你为一个子集群留出专属硬件的方式:GPU 节点、竞价节点、带许可证的机器,只接纳确实需要的负载,而其它 pod 仿佛这批节点不存在。由于它默认按范围生效,一套集群里可以同时住着通用池和专用池,而不必靠一堆标签去捋。
效果决定行为 真正把「牌子」变成「行为」的是污点的 effect 字段。NoSchedule 只挡住新 Pod,对已在运行的不动,是你不想再往里面塞容量时的默认选择。PreferNoSchedule 是软偏好,倾向于、但不禁止,适合折价的池而非硬约束。NoExecute 则会把已经绑上去的 Pod 也驱离,它也常常被拿去「把一个节点排空」:给节点打上 NoExecute,调度器会主动把其上的运行移走。挑哪种 effect,取决于你这一刻真正要的是「拦住」还是「清空」,因为软排除与硬排除是两种截然不同的保证。
配对即约定 容忍度与污点要靠 key、运算符与 effect 三者完全对上才算匹配,因此这层配对是明文、是可以被审查的契约。一份容忍度表达的是「在我能扛住这种污点的节点上生活」,它既不表达偏爱、也不会强制去哪台机器,因此一个带容忍度的 Pod 仍可能落在别处。这正是为什么一个集群既能有一批 GPU 节点、又能有一批通用节点而不互相摸错:放不下的 Pod 就不会被放到那里,而专用负载稳当地落在它们需要的硬件上。把这份配对当成正式的约定去写,哪种代价、为什么要加,到期日是什么,否则契约就会慢慢变成一锅标签粥。
坏掉的样子 最贵的故障是过宽的容忍度污染了专用池。一条写着 operator: Exists 却不带值的容忍度,或一份被复制进公共图表的容忍度,会匹配该键下的所有取值,于是普通发布突然有资格落到图形处理器或竞价节点上。预留池被廉价负载占满,而它真正要服务的专用负载反而长期等待调度。这恰好与守护进程集的故障互为镜像:那边是缺了容忍度导致专用节点没有覆盖,这边是多了容忍度导致专用节点失去保护。请把容忍度当作权限通配符来审计,公共模板里必须写清键值与效果三者。
第二种故障是把本该用 NoSchedule 的地方写成了 NoExecute。前者只拦截新负载,后者会把没有匹配容忍度的运行中负载直接驱离,还可能在 tolerationSeconds 倒计时结束后动手。一个维护污点若选错效果,几秒钟就能排空整组生产负载,而从示例里顺手复制的六十秒容忍倒计时,会把一次预留变成一场无人排期的延迟驱逐。与亲和不同,亲和从不驱逐,而污点侧的效果字段自带破坏力,因此维护污点先在单台节点演练,看过负载分布再向整池推广。
...