website/content/zh/docs/tasks/debug-application-cluster/debug-application.md

178 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
title: 应用故障排查
---
本指南帮助用户来调试kubernetes上那些没有正常运行的应用。
本指南*不能*调试集群。如果想调试集群的话,请参阅[这里](/docs/admin/cluster-troubleshooting)。
{{< toc >}}
## 诊断问题
故障排查的第一步是先给问题分下类。这个问题是什么PodsReplication Controller或者Service
* [Debugging Pods](#debugging-pods)
* [Debugging Replication Controllers](#debugging-replication-controllers)
* [Debugging Services](#debugging-services)
### Debugging Pods
调试pod的第一步是看一下这个pod的信息用如下命令查看一下pod的当前状态和最近的事件
```shell
$ kubectl describe pods ${POD_NAME}
```
查看一下pod中的容器所处的状态。这些容器的状态都是`Running`吗?最近有没有重启过?
后面的调试都是要依靠pods的状态的。
#### pod停留在pending状态
如果一个pod卡在`Pending`状态则表示这个pod没有被调度到一个节点上。通常这是因为资源不足引起的。
敲一下`kubectl describe ...`这个命令,输出的信息里面应该有显示为什么没被调度的原因。
常见原因如下:
* **资源不足**:
你可能耗尽了集群上所有的CPU和内存此时你需要删除pods调整资源请求或者增加节点。
更多信息请参阅[Compute Resources document](/docs/user-guide/compute-resources/#my-pods-are-pending-with-event-message-failedscheduling)
* **使用了`hostPort`**:
如果绑定一个pod到`hostPort`那么能创建的pod个数就有限了。
多数情况下,`hostPort`是非必要的而应该采用服务来暴露pod。
如果确实需要使用`hostPort`那么能创建的pod的数量就是节点的个数。
#### pod停留在waiting状态
如果一个pod卡在`Waiting`状态则表示这个pod已经调试到节点上但是没有运行起来。
再次敲一下`kubectl describe ...`这个命令来查看相关信息。
最常见的原因是拉取镜像失败。可以通过以下三种方式来检查:
* 使用的镜像名字正确吗?
* 镜像仓库里有没有这个镜像?
* 用`docker pull <image>`命令手动拉下镜像试试。
#### pod处于crashing状态或者unhealthy
首先看一下容器的log:
```shell
$ kubectl logs ${POD_NAME} ${CONTAINER_NAME}
```
如果容器是crashed的用如下命令可以看到crash的log:
```shell
$ kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
```
或者,用`exec`在容器内运行一些命令:
```shell
$ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}
```
注意当一个pod内只有一个容器时可以不带参数`-c ${CONTAINER_NAME}`。
例如名为Cassandra的pod处于running态要查看它的log可运行如下命令
```shell
$ kubectl exec cassandra -- cat /var/log/cassandra/system.log
```
如果以上方法都不起作用找到这个pod所在的节点并用SSH登录进去做进一步的分析。
通常情况下是不需要在Kubernetes API中再给出另外的工具的。
因此如果你发现需要ssh进一个主机来分析问题时请在GitHub上提一个特性请求描述一个你的场景并说明为什么已经提供的工具不能满足需求。
#### pod处于running态但是没有正常工作
如果创建的pod不符合预期那么创建pod的描述文件应该是存在某种错误的并且这个错误在创建pod时被忽略掉。
通常pod的定义中章节被错误的嵌套或者一个字段名字被写错都可能会引起被忽略掉。
例如希望在pod中用命令行执行某个命令但是将`command`写成`commnd`pod虽然可以创建但命令并没有执行。
如何查出来哪里出错?
首先删掉这个pod再重新创建一个重创时像下面这样带着`--validate`这个参数:
`kubectl create --validate -f mypod.yaml``command`写成`commnd`的拼写错误就会打印出来了。
```shell
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
```
<!-- TODO: Now that #11914 is merged, this advice may need to be updated -->
如果上面方法没有看到相关异常的信息那么接下来就要验证从apiserver获取到的pod是否与期望的一致比如创建Pod的yaml文件是mypod.yaml。
运行如下命令来获取apiserver创建的pod信息并保存成一个文件
`kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml`
然后手动对这两个文件进行比较:
apiserver获得的yaml文件中的一些行不在创建pod的yaml文件内这是正常的。
如果创建Pod的yaml文件内的一些行在piserver获得的yaml文件中不存在可以说明创建pod的yaml中的定义有问题。
### Debugging Replication Controllers
RC相当简单。他们要么能创建pod要么不能。如果不能创建pod请参阅上述[Debugging Pods](#debugging-pods)。
也可以使用`kubectl describe rc ${CONTROLLER_NAME}`命令来监视RC相关的事件。
### Debugging Services
服务提供了多个Pod之间的负载均衡功能。
有一些常见的问题可以造成服务无法正常工作。以下说明将有助于调试服务的问题。
首先验证服务是否有端点。对于每一个Service对像apiserver使`endpoints`资源可用。
通过如下命令可以查看endpoints资源
```shell
$ kubectl get endpoints ${SERVICE_NAME}
```
确保endpoints与服务内容器个数一致。
例如如果你创建了一个nginx服务它有3个副本那么你就会在这个服务的endpoints中看到3个不同的IP地址。
#### 服务缺少endpoints
如果缺少endpoints请尝试使用服务的labels列出所有的pod。
假如有一个服务有如下的label
```yaml
...
spec:
- selector:
name: nginx
type: frontend
```
你可以使用如下命令列出与selector相匹配的pod并验证这些pod是否归属于创建的服务
```shell
$ kubectl get pods --selector=name=nginx,type=frontend
```
如果pod列表附合预期但是endpoints仍然为空那么可能没有暴露出正确的端口。
如果服务指定了`containerPort`但是列表中的Pod没有列出该端口则不会将其添加到端口列表。
验证该pod的`containerPort`与服务的`containerPort`是否匹配。
#### 网络业务不工作
如果可以连接到服务上但是连接立即被断开了并且在endpoints列表中有endpoints可能是代理和pods之间不通。
确认以下3件事情
* Pods工作是否正常 看一下重启计数,并参阅[Debugging Pods](#debugging-pods)
* 可以直接连接到pod上吗获取pod的IP地址然后尝试直接连接到该IP上
* 应用是否在配置的端口上进行服务Kubernetes不进行端口重映射所以如果应用在8080端口上服务那么`containerPort`字段就需要设定为8080。
#### 更多信息
如果上述都不能解决你的问题,请按照[Debugging Service document](/docs/user-guide/debugging-services)中的介绍来确保你的`Service`处于running态有`Endpoints``Pods`真正的在服务你有DNS在工作安装了iptables规则kube-proxy也没有异常行为。
你也可以访问[troubleshooting document](/docs/troubleshooting/)来获取更多信息。