调试 Pod
本指南旨在帮助用户调试部署到 Kubernetes 中但行为不正常的应用程序。这*不是*针对想要调试其集群的人员的指南。为此,您应该查看本指南。
诊断问题
故障排除的第一步是分类。问题是什么?是您的 Pod、您的副本控制器还是您的服务?
调试 Pod
调试 Pod 的第一步是查看它。使用以下命令检查 Pod 的当前状态和最近的事件
kubectl describe pods ${POD_NAME}
查看 Pod 中容器的状态。它们都处于正在运行
状态吗?最近有重启过吗?
根据 Pod 的状态继续调试。
我的 Pod 始终处于挂起状态
如果 Pod 停留在挂起
状态,则表示它无法调度到节点上。通常这是因为某些类型的资源不足,从而阻止调度。查看上面kubectl describe ...
命令的输出。应该有来自调度程序的有关为什么无法调度您的 Pod 的消息。原因包括
您没有足够的资源:您可能已耗尽集群中的 CPU 或内存,在这种情况下,您需要删除 Pod、调整资源请求或将新节点添加到集群。有关更多信息,请参见计算资源文档。
您正在使用
hostPort
:当您将 Pod 绑定到hostPort
时,Pod 可以调度的位置数量有限。在大多数情况下,hostPort
是不必要的,请尝试使用服务对象公开您的 Pod。如果您确实需要hostPort
,那么您只能调度与 Kubernetes 集群中的节点数量一样多的 Pod。
我的 Pod 始终处于等待状态
如果 Pod 停留在等待
状态,则表示它已调度到工作节点,但无法在该机器上运行。同样,kubectl describe ...
的信息应该很有用。等待
Pod 最常见的原因是无法拉取镜像。有三个需要检查的事项
- 确保您输入的镜像名称正确。
- 您是否已将镜像推送到注册表?
- 尝试手动拉取镜像以查看是否可以拉取镜像。例如,如果您在 PC 上使用 Docker,请运行
docker pull <image>
。
我的 Pod 始终处于终止状态
如果 Pod 停留在终止
状态,则表示已为 Pod 发出删除请求,但控制平面无法删除 Pod 对象。
这通常发生在 Pod 具有终结器 并且集群中安装了准入 Webhook 来阻止控制平面删除终结器时。
要确定这种情况,请检查您的集群是否具有任何针对pods
资源的UPDATE
操作的 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration。
如果 webhook 由第三方提供
- 确保您使用的是最新版本。
- 为
UPDATE
操作禁用 webhook。 - 向相应的提供商报告问题。
如果您是 webhook 的作者
- 对于变异 webhook,确保它永远不会更改
UPDATE
操作中的不可变字段。例如,通常不允许对容器进行更改。 - 对于验证 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 获取的 Pod 描述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
匹配
网络流量未转发
有关更多信息,请参见调试服务。
下一步
如果上述操作都无法解决您的问题,请按照调试服务文档中的说明进行操作,以确保您的服务
正在运行、具有端点
以及您的Pod
实际上正在提供服务;您的 DNS 正常运行、iptables 规则已安装,并且 kube-proxy 似乎没有出现故障。
您还可以访问故障排除文档以获取更多信息。