Tasks

Step-by-step instructions for performing operations with Kubernetes.

Edit This Page

排查应用故障

本指南旨在帮助用户调试那些部署到 Kubernetes 中但是行为不正确的应用。这 不是 针对想要调试集群的人员的指南。如果想要调试集群,您应该看看 这个指南

诊断问题

故障排查的第一步是分诊。问题是什么?是您的 Pod?您的副本控制器(RC:Replication Controller)?还是您的服务?

调试 Pod

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

$ kubectl describe pods ${POD_NAME}

查看 pod 中容器的状态。它们都是Running?最近有没有重新启动?

根据 pod 的状态继续调试。

pod 一直是 pending 状态

如果 pod 卡在 Pending 状态,意味着它不能被调度到节点上。通常这是因为没有足够的资源导致调度被阻止了。查看 kubectl describe ... 命令的输出。应该有来自调度器说明为什么它无法调度您的 pod 的消息。原因包括:

pod 一直是 waiting 状态

如果一个 Pod 停留在 Waiting 状态,则它已被调度到一个工作节点,但不能在该机器上运行。同样,来自 kubectl describe ... 命令的信息应该是可以分析其原因的。Waiting pod 最常见的原因是无法拉取镜像。有三件事要检查:

pod 崩溃或者其它不健康状态

首先,查看当前容器的日志:

$ kubectl logs ${POD_NAME} ${CONTAINER_NAME}

如果您的容器先前已崩溃,则可以通过以下方式访问先前容器的崩溃日志:

$ kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}

或者,您可以在该容器中运行命令 exec

$ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}

请注意,-c ${CONTAINER_NAME} 是可选的,对于只包含单个容器的 pod 可以省略。

例如,要查看正在运行的 Cassandra pod 的日志,您可以运行

$ kubectl exec cassandra -- cat /var/log/cassandra/system.log

如果这些方法都不起作用,您可以找到运行 pod 的主机并通过 SSH 连接到该主机,但是,在 Kubernetes API 中,通常是没有必要使用这些工具的。因此,如果您发现自己需要 SSH 进入一台机器,请在 GitHub 上提交描述您使用案例的功能请求,以及为什么这些工具不足。

pod 正在运行,但没有按照我所说的去做

如果您的 pod 没有按照您的预期运行,则可能是您的 pod 描述中存在错误(例如,本地计算机上的 mypod.yaml 文件),并且在创建 pod 时错误被默默地忽略了。通常情况下,包括 pod 描述的一部分被错误的嵌套、或者某个键名称键入错误,因此该键被忽略。例如,如果将 command 错误地拼写为 commnd,那么会创建 pod,但不会使用您打算使用的命令行。

首先要做的是删除您的 pod,然后尝试使用 --validate 选项重新创建它。例如,运行 kubectl create --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 描述和从 apiserver 获取的描述 mypod-on-apiserver.yaml。“apiserver” 版本通常会有一些不在原始版本上出现的行,这是预料之中的。但是,如果原件上的某些行在 apiserver 版本上没有,则可能表明您的 pod 描述存在问题。

调试副本控制器

副本控制器相当直接。它们要么能够创建 Pod 要么不能。如果他们无法创建 pod,请参阅 上面的说明 来调试您的 pod。

您也可以使用 kubectl describe rc ${CONTROLLER_NAME} 内省与副本控制器相关的事件。

调试服务

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

首先,确认服务有 endpoints。对于每个服务对象,apiserver 都提供 endpoints 资源。

您可以查看这个资源:

$ kubectl get endpoints ${SERVICE_NAME}

确保 endpoints 符合您希望成为服务成员的容器数量。例如,如果您的服务是针对具有 3 个复本的 nginx 容器,则您希望在服务的 endpoints 中看到三个不同的 IP 地址。

服务缺少 endpoints

如果缺少 endpoints,请尝试使用 Service 中使用的标签列出 pod。想象一下,您有一个服务,标签是:

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

您可以使用:

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

列出与此选择器匹配的 pod。请验证列表是否与您希望提供服务的 pod 相匹配。

如果 pod 列表符合期望值,但您的 endpoints 仍为空,则可能是因为没有暴露正确的端口。如果您的服务有一个指定的 containerPort,但所选的 Pod 没有列出该端口,则不会将其添加到 endpoint 列表中。

验证 pod 的 containerPort与服务的containerPort 匹配

网络流量未被转发

如果您可以连接到服务,但连接会马上断开,并且 endpoints 列表中有 endpoints,则有可能是代理无法联系到您的 pod。

有三件事要检查:

更多信息

如果以上都不能解决您的问题,请按照 调试服务文档 中的说明操作,以确保您的 Service 正在运行、拥有 Endpoints 以及您的 Pods 确实正在服务中;您有正在工作中的 DNS、安装了 iptables 规则,并且 kube-proxy 似乎没有什么不妥之处。

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

Analytics

Create an Issue Edit this Page