本页面介绍了如何解决在 Google Kubernetes Engine (GKE) 中部署的工作负载的错误。
如需了解有关排查应用问题的更多一般性建议,请参阅 Kubernetes 文档中的排查应用问题。
所有错误:检查 Pod 状态
如果工作负载的 Pod 存在问题,Kubernetes 会更新 Pod 状态并显示错误消息。使用 Google Cloud 控制台或 kubectl
命令行工具检查 Pod 的状态,以查看这些错误。
控制台
执行以下步骤:
在 Google Cloud 控制台中,前往工作负载页面。
选择要调查的工作负载。概览标签页显示工作负载的状态。
在托管式 Pod 部分中,点击任何错误状态消息。
kubectl
如需查看集群中正在运行的所有 Pod,请运行以下命令:
kubectl get pods
输出类似于以下内容:
NAME READY STATUS RESTARTS AGE
POD_NAME 0/1 CrashLoopBackOff 23 8d
潜在错误会列在 Status
列中。
如需获取有关特定 Pod 的更多详细信息,请运行以下命令:
kubectl describe pod POD_NAME
将 POD_NAME
替换为您要调查的 Pod 的名称。
在输出中,Events
字段会显示有关错误的详细信息。
如需详细信息,请查看容器日志:
kubectl logs POD_NAME
这些日志可帮助您确定是容器中的命令还是代码导致了 Pod 崩溃。
确定错误后,请使用以下部分,尝试解决问题。
错误:CrashLoopBackOff
状态为 CrashLoopBackOff
并不表示存在特定错误,而是表示容器在重启后反复崩溃。
如需了解详情,请参阅排查 CrashLoopBackOff 事件。
错误:ImagePullBackOff 和 ErrImagePull
状态为 ImagePullBackOff
或 ErrImagePull
表示无法从映像注册表加载容器使用的映像。
如需获取有关排查这些状态的指导,请参阅排查映像拉取问题。
错误:Pod 无法调度
状态为 PodUnschedulable
表示由于资源不足或某些配置错误而无法调度 Pod。
如果您已配置控制平面指标,则您可以在调度器指标和 API 服务器指标中找到有关这些错误的详细信息。
使用无法调度的 Pod 交互式 playbook
您可以使用 Google Cloud 控制台中的交互式 playbook 排查 PodUnschedulable
错误:
前往无法调度的 Pod 交互式 playbook:
在集群下拉列表中,选择您要排查问题的集群。如果您找不到集群,请在
过滤条件字段中输入集群的名称。在命名空间下拉列表中,选择您要排查问题的命名空间。如果您找不到命名空间,请在
过滤条件字段中输入命名空间。为帮助您找出原因,请逐一查看该 playbook 中的各个部分:
- 调查 CPU 和内存
- 调查每个节点的 Pod 数量上限
- 调查自动扩缩器行为
- 调查其他故障模式
- 关联更改事件
可选:如需接收有关未来
PodUnschedulable
错误的通知,请在未来应对措施提示部分中选择创建提醒。
错误:资源不足
您可能会遇到指示缺少 CPU、内存或其他资源的错误。例如:No nodes are available that match all of the predicates:
Insufficient cpu (2)
,表示在两个节点上没有足够的 CPU 可用于满足 Pod 的请求。
如果您的 Pod 资源请求量超过任何符合条件的节点池中单个节点所能提供的资源,则 GKE 不会安排 Pod,也不会触发扩容以添加新节点。要让 GKE 对 Pod 进行安排,您必须为 Pod 请求少量的资源,或者创建具有足够资源的新节点池。
此外,您还可以启用节点自动预配功能,以便 GKE 能够自动创建节点池,这类节点池具有可运行未安排的 Pod 的节点。
默认 CPU 请求是 100M 或 CPU(或一个核心)的 10%。如果您想请求更多或更少的资源,请在 spec: containers: resources: requests
下的 Pod 规范中指定该值
错误:MatchNodeSelector
MatchNodeSelector
指示没有与 Pod 的标签选择器匹配的节点。
如需验证这一点,请在 spec: nodeSelector
下,检查 Pod 规范中的 nodeSelector
字段指定的标签。
如需查看集群中节点的标签,请运行以下命令:
kubectl get nodes --show-labels
如需将标签附加到节点,请运行以下命令:
kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE
替换以下内容:
NODE_NAME
:要为其添加标签的节点。LABEL_KEY
:标签的键。LABEL_VALUE
:标签的值。
如需了解详情,请参阅 Kubernetes 文档中的为节点分配 Pod。
错误:PodToleratesNodeTaints
PodToleratesNodeTaints
指示 Pod 无法调度到任何节点上,因为 Pod 没有与现有节点污点相对应的容忍设置。
如需验证属于这种情况,请运行以下命令:
kubectl describe nodes NODE_NAME
在输出中,选中 Taints
字段,该字段列出了键值对和调度效果。
如果列出的效果是 NoSchedule
,则在该节点上没有 Pod 可以计划,除非它有一个匹配的负荷。
解决此问题的一种方法是移除污点。例如,如需移除 NoSchedule 污点,请运行以下命令:
kubectl taint nodes NODE_NAME key:NoSchedule-
错误:PodFitsHostPorts
PodFitsHostPorts
错误表示节点正在尝试使用已被占用的端口。
如需解决此问题,请考虑遵循 Kubernetes 最佳实践并使用 NodePort
而非 hostPort
。
如果您必须使用 hostPort
,请检查 Pod 的清单,并确保同一节点上的所有 Pod 都为 hostPort
定义了唯一的值。
错误:不具备最低限度的可用性
如果节点有足够的资源但仍然显示 Does not have minimum availability
消息,请查看 Pod 的状态。如果状态为 SchedulingDisabled
或 Cordoned
,则节点无法调度新 Pod。您可以使用 Google Cloud 控制台或 kubectl
命令行工具检查节点的状态。
控制台
执行以下步骤:
前往 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
选择您要调查的集群。节点标签页显示节点及其状态。
如需在节点上启用调度,请执行以下步骤:
在列表中,点击您要调查的节点。
在节点详情部分中,点击取消封锁。
kubectl
如需获取节点的状态,请运行以下命令:
kubectl get nodes
如需在节点上启用调度,请运行:
kubectl uncordon NODE_NAME
错误:已达到每个节点的 Pod 数上限
如果集群中的所有节点都达到每个节点的 Pod 数上限,Pod 会卡在“无法调度”状态。在 Pod 事件标签页下,您会看到包含 Too many pods
字词的消息。
要解决此错误,请完成以下步骤:
在 Google Cloud 控制台中,通过 GKE 集群详情中的“节点”标签页查看
Maximum pods per node
配置。获取节点列表:
kubectl get nodes
对于每个节点,请验证在节点上运行的 Pod 数量:
kubectl get pods -o wide | grep NODE_NAME | wc -l
如果达到了上限,请添加新的节点池,或向现有节点池添加更多节点。
问题:在启用集群自动扩缩器的情况下,已达到节点池大小上限
如果节点池已达到大小上限,根据集群自动扩缩器配置,GKE 不会触发使用此节点池安排的 Pod 纵向扩容。如果您希望使用此节点池调度 Pod,请更改集群自动扩缩器配置。
问题:在停用集群自动扩缩器的情况下,已达到节点池大小上限
如果节点池已达到节点数量上限,并且集群自动扩缩器已停用,则 GKE 无法使用节点池调度 Pod。增加节点池的大小或启用集群自动扩缩器,以便 GKE 自动调整集群的大小。
错误:PersistentVolumeClaims 未绑定
Unbound PersistentVolumeClaims
指示 Pod 引用了未绑定的 PersistentVolumeClaim。如果您的 PersistentVolume 预配失败,可能会发生此错误。您可以通过获取 PersistentVolumeClaim 事件并检查其是否失败来验证预配是否失败。
如需获取事件,请运行以下命令:
kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0
请替换以下内容:
STATEFULSET_NAME
:StatefulSet 对象的名称。PVC_NAME
:PersistentVolumeClaim 对象的名称。
如果您在手动预配 PersistentVolume 并将其绑定到 PersistentVolumeClaim 期间遇到配置错误,也可能会出现此问题。
如需解决此错误,请尝试再次预配卷。
错误:配额不足
验证您的项目是否有足够的 Compute Engine 配额供 GKE 纵向扩容集群。如果 GKE 尝试向集群添加节点以安排 Pod,并且扩容将超出项目的可用配额,则您会收到 scale.up.error.quota.exceeded
错误消息。
如需了解详情,请参阅扩容错误。
问题:API 已弃用
确保您没有使用已弃用的 API,这些 API 已与集群的次要版本一起移除。如需了解详情,请参阅功能和 API 弃用。
错误:没有可供请求的 Pod 端口使用的空闲端口
如果您看到类似于以下内容的错误,则表示同一节点上可能有多个 Pod,并且在 hostPort
字段中定义了相同的值:
0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.
将 Pod 绑定到 hostPort
会限制 GKE 可以调度 Pod 的范围,因为每个 hostIP
、hostPort
和 protocol
组合都必须是唯一的。
如需解决此问题,请考虑遵循 Kubernetes 最佳实践并使用 NodePort
而非 hostPort
。
如果您必须使用 hostPort
,请检查 Pod 的清单,并确保同一节点上的所有 Pod 都为 hostPort
定义了唯一的值。
后续步骤
如果您在文档中找不到问题的解决方案,请参阅获取支持以获取进一步的帮助,包括以下主题的建议:
- 请与 Cloud Customer Care 联系,以提交支持请求。
- 通过在 StackOverflow 上提问并使用
google-kubernetes-engine
标记搜索类似问题,从社区获得支持。您还可以加入#kubernetes-engine
Slack 频道,以获得更多社区支持。 - 使用公开问题跟踪器提交 bug 或功能请求。