本页面介绍了如何解决在 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 表示无法从映像注册表加载容器使用的映像。
如需获取有关排查这些状态的指导,请参阅排查映像拉取问题。
错误:OutOfPods
状态为 OutOfPods 表示节点无法运行 Pod,因为该节点已达到其最大 Pod 容量。
表现
您可能会在 Pod 的事件中看到类似如下内容的消息:
Node didn't have enough resource: pods, requested: 1, used: 32, capacity: 32
原因
当请求调度节点上已达到容量上限的 Pod 时,会发生此错误。这种情况通常会在节点启动期间发生,例如,当 kube-scheduler 组件在 kubelet 代理报告静态 Pod(如 kube-proxy 组件)的存在之前就将 Pod 分配给新节点,而这些静态 Pod 自身需要占用 Pod 容量。
解决方法
要解决此问题,请尝试以下解决方法之一:
增加每个节点的 Pod 数量上限。如果您的节点始终达到其 Pod 数量上限,请为节点池增加
--max-pods-per-node设置。增加 Pod 数量可能需要更大的节点来处理增加的资源需求。启用集群自动扩缩器和节点自动预配。如果您经常遇到 Pod 容量不足的情况,可以启用集群自动扩缩器和节点自动预配功能,以帮助确保集群有足够的节点来满足工作负载的需求。
更改自动扩缩配置文件。如果您已在使用集群自动扩缩器,请尝试将自动扩缩配置文件更改为
balanced配置文件,而不是optimize-utilization配置文件。optimize-utilization配置文件会增加出现OutOfPods错误的几率,因为它会尝试将 Pod 放置在利用率最高的节点上。
错误:Pod 无法调度
状态为 PodUnschedulable 表示由于资源不足或某些配置错误而无法调度 Pod。
如果您已配置控制平面指标,则您可以在调度器指标和 API 服务器指标中找到有关这些错误的详细信息。
使用无法调度的 Pod 交互式 playbook
您可以使用 Google Cloud 控制台中的交互式 playbook 排查 PodUnschedulable 错误:
前往无法调度的 Pod 交互式 playbook:
在集群下拉列表中,选择您要排查问题的集群。如果您找不到集群,请在 过滤条件字段中输入集群的名称。
在命名空间下拉列表中,选择您要排查问题的命名空间。如果您找不到命名空间,请在 过滤条件字段中输入命名空间。
为帮助您找出原因,请逐一查看该 playbook 中的各个部分:
- 调查 CPU 和内存
- 调查每个节点的 Pod 数量上限
- 调查自动扩缩器行为
- 调查其他故障模式
- 关联更改事件
可选:如需接收有关未来
PodUnschedulable错误的通知,请在未来应对措施提示部分中选择创建提醒。
错误:资源不足
如果 CPU、内存或其他资源不足以满足 Pod 的请求,则可能会出现 PodUnschedulable 状态。
表现
您可能会遇到指示缺少 CPU、内存或其他资源的错误。例如:No nodes are available that match all of the predicates:
Insufficient cpu (2)。此消息表示在两个节点上没有足够的 CPU 可用于满足 Pod 的请求。
原因
如果您的 Pod 资源请求量超过任何符合条件的节点池中单个节点所能提供的资源,则 GKE 不会安排 Pod,也不会触发扩容以添加新节点。
您的集群在 kube-system 命名空间中运行系统容器。这些容器也使用集群资源。
解决方法
请尝试按以下解决方法操作:
通过在
spec: containers: resources: requests字段中指定较低的值来调整 Pod 的资源请求。默认 CPU 请求是 100M 或 CPU(或一个核心)的 10%。创建具有足够资源的新节点池,以满足 Pod 的请求。
启用节点自动预配功能,以便 GKE 能够自动创建节点池,这类节点池具有可运行未安排的 Pod 的节点。
错误:MatchNodeSelector
MatchNodeSelector 错误表示没有与 Pod 的标签选择器匹配的节点。
表现
Pod 状态或事件显示 MatchNodeSelector 错误。
原因
Pod 清单的 nodeSelector 字段中指定的标签在集群中的任何节点上都不存在。
解决方法
如需解决此错误,请确保 Pod 的 nodeSelector 字段中指定的标签与集群中至少一个节点上的标签匹配:
通过检查 Pod 的
spec: nodeSelector字段,确定 Pod 正在寻找的标签要求。如需查看是否有任何标签符合 Pod 的要求,请查看分配给集群中节点的实际标签:
kubectl get nodes --show-labels如果某个节点要运行此 Pod,请附加必要的标签:
kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE替换以下内容:
NODE_NAME:要为其添加标签的节点。LABEL_KEY:标签的键。LABEL_VALUE:标签的值。
如需了解详情,请参阅 Kubernetes 文档中的为节点分配 Pod。
错误:PodToleratesNodeTaints
PodToleratesNodeTaints 错误表示 Pod 无法调度到任何节点上,因为 Pod 没有与现有节点污点相对应的容忍设置。
表现
Pod 状态或事件显示 PodToleratesNodeTaints 错误。
原因
Pod 无法调度到任何节点上,因为 Pod 没有与现有节点污点相对应的容忍设置。
解决方法
检查节点上的污点:
kubectl describe nodes NODE_NAME在输出中,选中
Taints字段,该字段列出了键值对和调度效果。如果列出的效果是NoSchedule,则在该节点上没有 Pod 可以计划,除非它有一个匹配的容忍设置。从节点中移除污点。例如,如需移除
NoSchedule污点,请运行以下命令:kubectl taint nodes NODE_NAME key:NoSchedule-
错误:PodFitsHostPorts
PodFitsHostPorts 错误表示节点正在尝试使用已被占用的端口。
表现
Pod 状态显示 PodFitsHostPorts 错误。
原因
某个 Pod 正在请求的目标主机端口已被目标节点上的另一个 Pod 或进程使用。
解决方法
如需解决此问题,请考虑遵循 Kubernetes 最佳实践并使用 NodePort 服务,而不是 hostPort 设置。
如果您必须使用宿主端口,请检查 Pod 的清单,并确保同一节点上的所有 Pod 都为 hostPort 设置定义了唯一的值。
错误:不具备最低限度的可用性
如果节点有足够的资源,但无法用于调度,则可能会出现此错误。
表现
您看到
Does not have minimum availability错误。节点的状态显示为
SchedulingDisabled状态或Cordoned状态。
原因
节点的封锁状态可防止新 Pod 被调度到该节点上。
解决方法
如需使节点再次可用于调度 Pod,请取消封锁该节点:
控制台
执行以下步骤:
前往 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
选择您要调查的集群。节点标签页显示节点及其状态。
如需在节点上启用调度,请执行以下步骤:
在列表中,点击您要调查的节点。
在节点详情部分中,点击取消封锁。
kubectl
如需获取节点的状态,请运行以下命令:
kubectl get nodes
如需在节点上启用调度,请运行:
kubectl uncordon NODE_NAME
错误:已达到每个节点的 Pod 数上限
Too many pods 错误表示 Pod 无法调度,因为目标节点已达到其配置的最大 Pod 容量。
表现
- Pod 卡在
Unschedulable状态。 - 您会看到一条包含“
Too many pods”字样的消息。
原因
集群中的所有节点都达到每个节点的 Pod 数上限。
解决方法
要解决此错误,请完成以下步骤:
在 Google Cloud 控制台中,通过 GKE 集群详情中的“节点”标签页查看
Maximum pods per node配置。获取节点列表:
kubectl get nodes对于每个节点,请验证在节点上运行的 Pod 数量:
kubectl get pods -o wide | grep NODE_NAME | wc -l如果达到了上限,请添加新的节点池,或向现有节点池添加更多节点。
问题:在启用集群自动扩缩器的情况下,已达到节点池大小上限
当节点池在集群自动扩缩器下达到其配置的最大大小时,就会出现此问题。
表现
GKE 不会触发使用此节点池安排的 Pod 纵向扩容。相反,Pod 会保持 Pending 状态。
原因
节点池已达到大小上限,根据集群自动扩缩器配置。
解决方法
通过更改集群自动扩缩器配置来增加节点池的大小上限。
问题:在停用集群自动扩缩器的情况下,已达到节点池大小上限
当节点池已达到其最大大小且集群自动扩缩器已停用时,就会出现此问题。
表现
GKE 无法使用节点池调度 Pod。
原因
节点池已达到节点数量上限,并且集群自动扩缩器已停用。
解决方法
要解决此问题,请尝试以下解决方法之一:
错误:PersistentVolumeClaims 未绑定
Unbound PersistentVolumeClaims 错误表示 Pod 引用了未绑定的 PersistentVolumeClaim。
表现
Pod 状态或事件显示 Unbound PersistentVolumeClaims 错误。
原因
此错误可能是由以下某种原因造成的:
- 您的 PersistentVolume 预配失败。
- 在手动预配 PersistentVolume 并将其绑定到 PersistentVolumeClaim 期间,出现了配置错误。
解决方法
通过获取 PersistentVolumeClaim 的事件来验证预配是否失败:
kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0替换以下内容:
STATEFULSET_NAME:StatefulSet 对象的名称。PVC_NAME:PersistentVolumeClaim 对象的名称。
尝试再次预配卷。
错误:配额不足
如果 GKE 尝试扩容集群以调度 Pod,但遇到配额限制,则扩容会失败。
表现
您在 Pod 的事件中收到 scale.up.error.quota.exceeded 错误消息。
原因
扩容集群会超出项目的可用配额。
解决方法
验证您的项目是否有足够的 Compute Engine 配额供 GKE 纵向扩容集群。如需了解详情,请参阅扩容错误。
问题:API 已弃用
在清单中使用不再受支持的 API 可能会阻止工作负载部署。
表现
工作负载因使用已弃用的 API 而无法部署或运行。
原因
您的清单使用了已弃用且已在集群的次要版本中移除的 API。
解决方法
确保您没有使用已弃用的 API。更新清单以使用受支持的 API。如需了解详情,请参阅功能和 API 弃用。
错误:没有可供请求的 Pod 端口使用的空闲端口
将 Pod 绑定到宿主端口会限制 GKE 可以调度 Pod 的范围,因为每个 hostIP 地址、hostPort 设置和 protocol 值组合都必须是唯一的。
表现
您会看到类似于以下内容的错误:
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 字段中指定了相同的值。
解决方法
要解决此问题,请尝试以下解决方法之一:
- 遵循 Kubernetes 最佳实践,并使用
NodePort服务而非主机端口。 - 如果您必须使用宿主端口,请检查 Pod 的清单,并确保同一节点上的所有 Pod 都为
hostPort字段定义了唯一的值。
问题:Pod 中的应用和探测失败
当您运行使用 HTTPS 与服务器通信的应用时,会出现此问题。
表现
这些应用中的故障类似于以下内容:
- Pod 未启动,容器崩溃并显示退出代码
137。 活跃性或就绪性探测失败,并显示类似于以下内容的错误消息:
probeResult="failure" output="Get "https://example.com/healthy": EOF"Pod 运行正常,但应用日志显示连接失败。
原因
Kubernetes 1.30 版及更高版本使用会停用以下 TLS 加密套件的 Golang 版本:
TLS_RSA_WITH_AES_128_GCM_SHA256TLS_RSA_WITH_AES_256_GCM_SHA384TLS_RSA_WITH_AES_128_CBC_SHATLS_RSA_WITH_AES_256_CBC_SHATLS_RSA_WITH_3DES_EDE_CBC_SHA
解决方法
使用 TLS 1.2 及更高版本中的支持的加密套件。
后续步骤
如果您在文档中找不到问题的解决方案,请参阅获取支持以获取进一步的帮助,包括以下主题的建议:
- 请与 Cloud Customer Care 联系,以提交支持请求。
- 通过在 StackOverflow 上提问并使用
google-kubernetes-engine标记搜索类似问题,从社区获得支持。您还可以加入#kubernetes-engineSlack 频道,以获得更多社区支持。 - 使用公开问题跟踪器提交问题或功能请求。