根据你提供的 kubectl describe pod i18nnet
输出结果,该 Pod 处于 Pending
状态的核心原因是调度失败(FailedScheduling
)。以下是详细原因分析和解决方案:
✅ 根本原因分析
1. 节点选择器 (Node Selector) 未匹配
你的 Pod 声明了以下要求:
nodeSelector:
region: i18nnet
这意味着 Kubernetes 只会尝试将此 Pod 调度到 具有 region=i18nnet
标签 的 Node 上。然而,根据你的集群状态:
1 node(s) didn't match Pod's node affinity
表明当前集群中 没有任何节点带有 region=i18nnet
标签,因此这部分节点被过滤掉了。
2. 污点 (Taints) 与容忍度 (Tolerations) 不匹配
你的 Pod 虽然定义了一些 Tolerations:
tolerations:
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
timeoutSeconds: 300
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
timeoutSeconds: 300
但这些 Tolerations 并未覆盖所有存在的 Taints:
⚠️ 关键错误信息:
3 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate
说明你的集群中有 3 个 Master 节点 被打上了 node-role.kubernetes.io/master
的 Taint,而你的 Pod 没有对应的 Toleration 来接受这种 Taint,因此这些节点也被排除在外。
🛠️ 解决方案
✅ 方案一:添加缺失的 Toleration(推荐)
如果你打算让这个 Pod 运行在 Master 节点上(生产环境不建议这样做),你需要在 Pod 的定义中添加如下 Toleration:
tolerations:
# 已有的两个 tolerations...
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule" # 或 "NoExecute" 根据需求选择
📌 注意:
NoSchedule
表示可以调度但不保证驱逐已存在的 Pod;NoExecute
更严格,会在节点出现问题时终止 Pod。
✅ 方案二:修改 Node Selector + 确保存在符合条件的节点
如果你想让 Pod 只运行在特定区域的 worker 节点上:
-
检查现有节点的标签:
kubectl get nodes --show-labels
确认是否有节点已经打了
region=i18nnet
的标签。 -
如果没有,则为某个 worker 节点添加标签:
kubectl label nodes <your-worker-node-name> region=i18nnet
-
确保该节点没有被 Taint 阻止调度(即没有
node-role.kubernetes.io/master
或其他阻碍调度的 Taint)。
✅ 方案三:移除 Node Selector(临时测试用)
如果你只是想快速测试能否运行起来,可以暂时移除 nodeSelector
字段,这样 Pod 就可以在任何不受 Taint 影响的节点上运行。
📝 示例修复后的 Pod YAML 片段
apiVersion: v1
kind: Pod
metadata:
name: i18nnet
spec:
containers:
- name: i18nnet-cr
image: busybox:1.28
command: ["sleep", "3600"]
nodeSelector:
region: i18nnet # 确保至少有一个节点有这个标签
tolerations:
# 原有的两个 tolerations...
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
timeoutSeconds: 300
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
timeoutSeconds: 300
# 新增的 master node toleration
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
🔍 验证步骤
-
查看节点列表及标签:
kubectl get nodes --show-labels
确保至少有一个节点同时满足:
- 有
region=i18nnet
标签 - 没有阻止调度的 Taint(或者你有对应的 Toleration)
- 有
-
重新创建 Pod:
kubectl apply -f your-pod.yaml
-
监控调度过程:
kubectl describe pod i18nnet
如果一切正常,你会看到
PodScheduled
变为True
,并且出现在某个节点上。
💡 补充建议
项目 | 说明 |
---|---|
❌ 避免在 Master 节点上运行业务负载 | 除非必要,否则应仅用于管理用途 |
✅ 使用 Deployment/StatefulSet 替代手动创建 Pod | 便于管理和扩展 |
✅ 考虑使用 NodeAffinity 而非硬性 nodeSelector | 更加灵活,支持权重优先级 |
✅ 检查集群资源是否充足 | 使用 kubectl top nodes 查看 CPU/内存使用情况 |
✅ 总结
你的问题是由于 节点选择器未匹配 + 缺少对 Master 节点 Taint 的容忍 导致的调度失败。最推荐的解决方式是:
- 为某个 worker 节点添加
region=i18nnet
标签 - 保持现有的 Tolerations 不变
- 不要在 Master 节点上运行业务 Pod
这样就能顺利调度成功。