调试 Pod

本指南旨在帮助用户调试部署到 Kubernetes 中且行为不正确的应用程序。这不是针对想要调试集群的人员的指南。对于此目的,您应该查看 本指南

诊断问题

故障排除的第一步是分类。问题是什么?是您的 Pod、您的复制控制器还是您的 Service?

调试 Pod

调试 Pod 的第一步是查看它。使用以下命令检查 Pod 的当前状态和最近的事件

kubectl describe pods ${POD_NAME}

查看 Pod 中容器的状态。它们是否都处于 Running 状态?是否有最近的重启?

根据 Pod 的状态继续调试。

我的 Pod 保持挂起状态

如果 Pod 卡在 Pending 状态,这意味着它无法被调度到节点上。通常,这是因为某种类型的资源不足阻止了调度。查看上述 kubectl describe ... 命令的输出。应该有来自调度器的消息,说明它无法调度您的 Pod 的原因。原因包括

  • 您没有足够的资源:您可能耗尽了集群中的 CPU 或内存供应,在这种情况下,您需要删除 Pod、调整资源请求或向集群添加新节点。有关更多信息,请参阅 计算资源文档

  • 您正在使用 hostPort:当您将 Pod 绑定到 hostPort 时,该 Pod 可以调度的位置有限。在大多数情况下,hostPort 是不必要的,请尝试使用 Service 对象来公开您的 Pod。如果您需要 hostPort,那么您只能调度与 Kubernetes 集群中的节点数量一样多的 Pod。

我的 Pod 保持等待状态

如果 Pod 卡在 Waiting 状态,则它已被调度到工作节点,但无法在该机器上运行。同样,kubectl describe ... 中的信息应该具有参考价值。Waiting Pod 的最常见原因是无法拉取镜像。有三件事需要检查

  • 确保您输入了正确的镜像名称。
  • 您是否已将镜像推送到注册表?
  • 尝试手动拉取镜像,以查看是否可以拉取镜像。例如,如果您在 PC 上使用 Docker,请运行 docker pull <image>

我的 Pod 保持终止状态

如果 Pod 卡在 Terminating 状态,这意味着已发出 Pod 的删除请求,但控制平面无法删除 Pod 对象。

通常,如果 Pod 具有 finalizer,并且集群中安装了阻止控制平面删除 finalizer 的 准入 webhook,则会发生这种情况。

要识别此场景,请检查您的集群是否有针对 pods 资源的 UPDATE 操作的 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration。

如果 webhook 由第三方提供

  • 确保您使用的是最新版本。
  • 禁用 UPDATE 操作的 webhook。
  • 向相应的提供商报告问题。

如果您是 webhook 的作者

  • 对于 mutating webhook,请确保它永远不会在 UPDATE 操作上更改不可变字段。例如,通常不允许更改容器。
  • 对于 validating webhook,请确保您的验证策略仅适用于新更改。换句话说,您应该允许在安装 validating webhook 之前创建的 Pod 通过验证。这允许在安装 validating webhook 之前创建的 Pod 继续运行。

我的 Pod 崩溃或处于不正常状态

一旦您的 Pod 已被调度,调试正在运行的 Pod 中描述的方法可用于调试。

我的 Pod 正在运行,但没有按照我告诉它的方式执行

如果您的 Pod 没有按预期执行,可能是您的 Pod 描述中存在错误(例如,您本地机器上的 mypod.yaml 文件),并且该错误在您创建 Pod 时被无声地忽略了。通常,Pod 描述中的一部分嵌套不正确,或者键名拼写错误,因此该键被忽略。例如,如果您将 command 拼写为 commnd,则 Pod 将被创建,但不会使用您打算使用的命令行。

首先要做的是删除您的 Pod,然后使用 --validate 选项再次创建它。例如,运行 kubectl apply --validate -f mypod.yaml。如果您将 command 拼写为 commnd,则会收到如下错误

I0805 10:43:25.129850   46757 schema.go:126] unknown field: commnd
I0805 10:43:25.129973   46757 schema.go:129] this may be a false alarm, see https://github.com/kubernetes/kubernetes/issues/6842
pods/mypod

接下来要检查的是 apiserver 上的 Pod 是否与您打算创建的 Pod 相匹配(例如,您本地机器上的 yaml 文件中)。例如,运行 kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml,然后手动比较原始 Pod 描述 mypod.yaml 与从 apiserver 获取的 mypod-on-apiserver.yaml。通常,“apiserver”版本上会有一些原始版本上没有的行。这是预期的。但是,如果原始版本上有一些 apiserver 版本上没有的行,则这可能表明您的 Pod 规范存在问题。

调试复制控制器

复制控制器相当简单。它们可以创建 Pod,也可以不能创建 Pod。如果它们无法创建 Pod,请参阅 上面的说明 以调试您的 Pod。

您还可以使用 kubectl describe rc ${CONTROLLER_NAME} 来检查与复制控制器相关的事件。

调试 Service

Service 在一组 Pod 上提供负载均衡。以下是一些可能导致 Service 无法正常工作的常见问题。以下说明应有助于调试 Service 问题。

首先,验证 Service 是否存在端点。对于每个 Service 对象,apiserver 会提供一个或多个 EndpointSlice 资源。

您可以使用以下命令查看这些资源

kubectl get endpointslices -l kubernetes.io/service-name=${SERVICE_NAME}

确保 EndpointSlice 中的端点与您期望成为 Service 成员的 Pod 数量相匹配。例如,如果您的 Service 是针对具有 3 个副本的 nginx 容器,则您应该在 Service 的端点切片中看到三个不同的 IP 地址。

我的 Service 缺少端点

如果您缺少端点,请尝试使用 Service 使用的标签列出 Pod。假设您有一个标签为

...
spec:
  - selector:
     name: nginx
     type: frontend

您可以使用

kubectl get pods --selector=name=nginx,type=frontend

列出与此选择器匹配的 Pod。验证列表与您期望提供 Service 的 Pod 相匹配。验证 Pod 的 containerPort 与 Service 的 targetPort 相匹配

网络流量未转发

请参阅 调试 Service 以获取更多信息。

接下来

如果以上方法都无法解决您的问题,请按照 调试 Service 文档 中的说明,确保您的 Service 正在运行,具有 Endpoints,并且您的 Pods 实际上正在提供服务;您拥有 DNS 正常工作、安装了 iptables 规则,并且 kube-proxy 似乎没有出现故障。

您还可以访问 故障排除文档 以获取更多信息。

最后修改时间:2025 年 4 月 9 日上午 5:08 PST:更新文档以弃用 Endpoints API (#49831) (649bda2cbd)