调试 Pod

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

诊断问题

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

调试 Pod

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

kubectl describe pods ${POD_NAME}

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

根据 Pod 的状态继续调试。

我的 Pod 保持 pending 状态

如果 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 具有终结器,并且集群中安装了阻止控制平面删除终结器的准入 Webhook,则通常会发生这种情况。

要识别这种情况,请检查您的集群是否具有针对 pods 资源的 UPDATE 操作的任何 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration。

如果 Webhook 由第三方提供

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

如果您是 Webhook 的作者

  • 对于 Mutating Webhook,请确保它永远不会更改 UPDATE 操作上的不可变字段。例如,通常不允许更改容器。
  • 对于 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} 来查看与复制控制器相关的事件。

调试服务

服务在一组 Pod 之间提供负载均衡。有几个常见的问题会导致服务无法正常工作。以下说明应有助于调试服务问题。

首先,验证服务是否存在端点。对于每个 Service 对象,apiserver 都会提供一个 endpoints 资源。

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

kubectl get endpoints ${SERVICE_NAME}

确保端点与您期望作为服务成员的 Pod 数量相匹配。例如,如果您的服务适用于具有 3 个副本的 Nginx 容器,则您希望在服务的端点中看到三个不同的 IP 地址。

我的服务缺少端点

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

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

您可以使用

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

列出与此选择器匹配的 Pod。验证列表是否与您期望为 Service 提供服务的 Pod 匹配。验证 Pod 的 containerPort 是否与 Service 的 targetPort 匹配。

网络流量未转发

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

下一步

如果以上方法均不能解决您的问题,请按照调试服务文档中的说明,确保您的 Service 正在运行,具有 Endpoints,并且您的 Pods 实际上在提供服务;您的 DNS 工作正常,iptables 规则已安装,并且 kube-proxy 似乎没有异常行为。

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

上次修改时间:2024 年 1 月 20 日下午 11:44 PST: [en] Correct incorrect expressions (5fcc71ad51)