K8s Pod 出现 UnexpectedAdmissionError 的原因及解决方案
在 Kubernetes 集群中,UnexpectedAdmissionError 是一种 Pod 状态,表示在 Pod 的准入控制阶段(Admission Control)发生了意外错误,导致 Pod 无法正常启动。这种错误通常与资源分配、调度器配置或设备管理相关。以下是详细的原因分析和解决方案。
1. 常见原因分析
1.1 资源不足或分配失败
• GPU 资源不足:当
Pod请求GPU资源(如nvidia.com/gpu)时,如果节点上的可用GPU数量不足,会导致UnexpectedAdmissionError。例如,请求 1 个 GPU,但节点上可用 GPU 为 0。• CPU 或内存资源不足:在某些情况下,CPU 管理器(
CPU Manager)或内存管理器无法为Pod分配足够的资源,也会触发此错误。
1.2 调度器配置问题
• 多调度器竞争:如果集群中同时存在多个调度器(如默认调度器和自定义调度器),可能会导致资源分配冲突。例如,两个调度器同时尝试分配同一资源,导致资源不足。
• 调度器未启用 Leader 选举:如果多个调度器实例未启用
Leader选举(--leader-elect=false),可能会导致重复调度Pod,进而引发资源分配失败。
1.3 设备插件问题
• GPU 设备插件未正确注册:如果
GPU设备插件未正确部署或注册到Kubelet,Kubernetes无法识别GPU资源,导致Pod无法启动。• 设备健康状态异常:如果设备插件报告的设备状态为不健康(如
no healthy devices present),Kubelet会拒绝分配资源,导致UnexpectedAdmissionError。
1.4 磁盘空间不足
• Kubelet 检查点文件写入失败:如果节点的磁盘空间不足,
Kubelet无法写入设备分配检查点文件(如kubelet_internal_checkpoint),会导致资源分配失败。
1.5 节点状态异常
• 节点重启或资源耗尽:如果节点重启或资源(如 CPU、内存、磁盘)耗尽,
Kubelet可能无法正确处理 Pod 的资源请求,导致UnexpectedAdmissionError。
2. 解决方案
2.1 检查资源分配
• 确认资源请求和限制:确保 Pod 的资源请求(
requests)和限制(limits)配置合理,尤其是 GPU 资源。• 检查节点资源状态:使用
kubectl describe node <node-name>查看节点的资源使用情况,确保有足够的 GPU、CPU 和内存资源。
2.2 优化调度器配置
• 统一调度器配置:如果使用多个调度器,确保同一资源的请求使用相同的调度器,避免资源竞争。
• 启用 Leader 选举:确保调度器和控制器管理器(
Controller Manager)启用了Leader选举(--leader-elect=true),避免重复调度。
2.3 修复设备插件问题
• 检查设备插件状态:确保
GPU设备插件已正确部署并注册到Kubelet。使用kubectl describe node <node-name>查看设备资源状态。• 重启设备插件:如果设备插件异常,尝试重启设备插件或
Kubelet。
2.4 清理磁盘空间
• 释放磁盘空间:检查节点的磁盘使用情况,清理不必要的文件(如日志、临时文件),确保
Kubelet可以正常写入检查点文件。
2.5 重启节点或 Pod
• 重启节点:如果节点状态异常(如资源耗尽或设备插件断开),尝试重启节点以恢复资源分配。
• 删除并重建 Pod:如果
Pod卡在UnexpectedAdmissionError状态,可以尝试删除并重建Pod。
3. 预防措施
• 监控资源使用:使用
Prometheus或Metrics Server监控集群的资源使用情况,及时发现资源瓶颈。• 优化调度策略:合理配置节点亲和性(
Node Affinity)和污点与容忍(Taints and Tolerations),避免资源分配冲突。• 定期维护集群:定期检查设备插件、调度器和控制器的配置,确保集群运行正常。
4. 案例
4.1 现象
某个节点上的 Pod,批量处于 0/1 UnexpectedAdmissionError 状态。
4.2 排查过程
收集Pod内报错信息:
kubectl describe pod <pod name>Pod Update plugin resources failed due to failed to write checkpoint file "kubelet_internal_checkpoint": open /var/lib/kubelet/device-plugins/.873927311: no space left on device, which is unexpected.
检查磁盘空间:
# 查看对应目录磁盘容量实用情况,看是否有磁盘使用率接近 100%
df -h # 查看磁盘挂载情况
lsblk
通常查看根目录空间,绝大多数现场是由于根目录满了导致。
4.3 解决方案
清理根目录空间,kubelet 会自动重新拉起容器,恢复 Pod 状态。以下脚本用于删除(重启)所有处于 UnexpectedAdmissionError 状态的 Pod。
kubectl get pods -A -o jsonpath='{range .items[?(@.status.conditions[?(@.type=="PodScheduled" && @.reason=="UnexpectedAdmissionError")])]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}' \
| while read namespace name; do
kubectl delete pod -n "$namespace" "$name";
done5. 总结
UnexpectedAdmissionError 通常与资源分配、调度器配置或设备管理相关。通过检查资源请求、优化调度器配置、修复设备插件问题以及清理磁盘空间,可以有效解决此问题。同时,定期监控和维护集群是预防此类问题的关键。