调试 Pod
本指南旨在帮助用户调试部署到 Kubernetes 中且行为不正常的应用程序。这不是针对想要调试其集群的人员的指南。为此,您应该查看 本指南。
诊断问题
故障排除的第一步是分类。问题是什么?是您的 Pod、您的副本控制器还是您的服务?
调试 Pod
调试 Pod 的第一步是查看它。使用以下命令检查 Pod 的当前状态和最近的事件
kubectl describe pods ${POD_NAME}
查看 Pod 中容器的状态。它们是否都处于 Running
状态?最近有重启吗?
根据 Pod 的状态继续调试。
我的 Pod 处于挂起状态
如果 Pod 停留在 Pending
状态,则表示它无法调度到节点上。通常这是因为缺少某种类型的资源,从而阻止调度。查看上面 kubectl describe ...
命令的输出。应该有来自调度程序的消息,说明它为什么无法调度您的 Pod。原因包括
您没有足够的资源:您可能已耗尽集群中的 CPU 或内存供应,在这种情况下,您需要删除 Pod、调整资源请求或向集群添加新节点。有关更多信息,请参阅 计算资源文档。
您正在使用
hostPort
:当您将 Pod 绑定到hostPort
时,Pod 可以调度到的位置数量有限。在大多数情况下,hostPort
是不必要的,请尝试使用服务对象来公开您的 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 的作者
- 对于变异 Webhook,请确保它永远不会更改
UPDATE
操作中的不可变字段。例如,通常不允许更改容器。 - 对于验证 Webhook,请确保您的验证策略仅适用于新更改。换句话说,您应该允许在安装验证 Webhook 之前创建的 Pod 通过验证。这允许在安装验证 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 集群中提供负载均衡。有几个常见问题会导致服务无法正常工作。以下说明应该有助于调试服务问题。
首先,验证服务是否有端点。对于每个服务对象,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。验证列表是否与您期望提供的服务的 Pod 相匹配。验证 Pod 的 containerPort
是否与服务的 targetPort
相匹配
网络流量未转发
有关更多信息,请参阅 调试服务。
下一步
如果上述方法都无法解决您的问题,请按照 调试服务文档 中的说明进行操作,以确保您的 Service
正在运行,具有 Endpoints
,并且您的 Pods
实际上正在提供服务;您的 DNS 正常工作,iptables 规则已安装,并且 kube-proxy 似乎没有出现故障。
您还可以访问 故障排除文档 以获取更多信息。