diff --git a/cn/docs/tasks/debug-application-cluster/debug-application.md b/cn/docs/tasks/debug-application-cluster/debug-application.md new file mode 100644 index 0000000000..11538f35de --- /dev/null +++ b/cn/docs/tasks/debug-application-cluster/debug-application.md @@ -0,0 +1,182 @@ +--- +title: 应用故障排查 +--- + +本指南帮助用户来调试kubernetes上那些没有正常运行的应用。 +本指南*不能*调试集群。如果想调试集群的话,请参阅[这里](/docs/admin/cluster-troubleshooting)。 + +* TOC +{:toc} + +## FAQ + +强烈建议用户参考我们的[FAQ](https://github.com/kubernetes/kubernetes/wiki/User-FAQ). + +## 诊断问题 + +故障排查的第一步是先给问题分下类。这个问题是什么?Pods,Replication 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 `命令手动拉下镜像试试。 + +#### 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 +``` + + + +如果上面方法没有看到相关异常的信息,那么接下来就要验证从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/)来获取更多信息。