DaemonSet 无法在带有污点的节点上启动 Pod
1. 污点(Taints)的作用
根据知识库中的描述:
- 污点(Taint) 是节点上的标记,用于限制哪些 Pod 可以被调度到该节点。
NoSchedule
效果 表示:未配置对应容忍的 Pod 不能被调度到该节点,但已存在的 Pod 不受影响。node-role.kubernetes.io/platform-node:NoSchedule
是一个典型的污点,通常用于标记特定用途的节点(例如控制平面节点或专用基础设施节点)。
2. DaemonSet 的工作原理
DaemonSet 的设计目标是确保 每个符合要求的节点上运行一个 Pod 副本。然而,如果节点被设置了污点(如 node-role.kubernetes.io/platform-node:NoSchedule
),DaemonSet 控制器会遵循以下规则:
- 默认情况下,DaemonSet 的 Pod 模板如果没有配置对应的容忍(Tolerations),则会被 拒绝调度到带有该污点的节点。
- 这是因为 Kubernetes 调度器会严格检查节点的污点和 Pod 的容忍是否匹配。
3. 为什么 DaemonSet 的 Pod 无法启动?
假设某个节点被标记为 node-role.kubernetes.io/platform-node:NoSchedule
,而 DaemonSet 的 Pod 模板中没有配置以下容忍:
tolerations:
- key: "node-role.kubernetes.io/platform-node"operator: "Exists"effect: "NoSchedule"
此时会发生以下情况:
- 污点与容忍不匹配:节点的污点
node-role.kubernetes.io/platform-node:NoSchedule
要求 Pod 必须有对应的容忍才能调度到该节点。 - DaemonSet 的 Pod 无法通过调度检查:由于 Pod 没有配置容忍,Kubernetes 调度器会拒绝将 Pod 调度到该节点。
- 结果:DaemonSet 控制器会持续尝试调度 Pod 到该节点,但始终失败,最终导致该节点上没有对应的 Pod。
4. 解决方案:为 DaemonSet 添加容忍
要让 DaemonSet 的 Pod 能够在带有 node-role.kubernetes.io/platform-node:NoSchedule
污点的节点上运行,需要在 DaemonSet 的 Pod 模板中显式添加对应的容忍。例如:
apiVersion: apps/v1
kind: DaemonSet
metadata:name: example-daemonset
spec:template:spec:containers:- name: example-containerimage: example-imagetolerations: # 添加容忍配置- key: "node-role.kubernetes.io/platform-node"operator: "Exists" # 匹配任意值effect: "NoSchedule"
关键点解释:
operator: Exists
:表示只要节点存在node-role.kubernetes.io/platform-node
这个键的污点,无论其值是什么,Pod 都可以容忍。effect: NoSchedule
:明确针对NoSchedule
效果的污点。
5. 其他可能原因
虽然污点是主要原因,但其他因素也可能导致 DaemonSet Pod 无法启动:
- 节点状态异常:节点处于
NotReady
或SchedulingDisabled
状态。 - 资源不足:节点的 CPU/内存等资源不足以运行 Pod。
- Pod 容器镜像问题:镜像拉取失败或镜像不存在。
- 命名空间配额限制:命名空间的资源配额(Resource Quota)限制了 Pod 的创建。
6. 验证与排查步骤
-
检查节点的污点:
kubectl describe node <node-name> | grep Taints
确认节点是否存在
node-role.kubernetes.io/platform-node:NoSchedule
污点。 -
检查 DaemonSet 的容忍配置:
kubectl get daemonset <daemonset-name> -o yaml
确认 Pod 模板中是否包含对应的容忍。
-
检查事件日志:
kubectl describe pod <pod-name> -n <namespace>
查看 Pod 的调度失败原因(如
TaintNode
相关错误)。
总结
DaemonSet 无法在带有 node-role.kubernetes.io/platform-node:NoSchedule
污点的节点上启动 Pod 的根本原因是:Pod 模板未配置对应的容忍,导致调度器拒绝调度。
通过在 DaemonSet 的 Pod 模板中添加容忍配置,可以解决这一问题。但需谨慎操作:控制平面节点(如带有 node-role.kubernetes.io/control-plane:NoSchedule
的节点)通常不建议部署用户 Pod,以免影响集群稳定性。