Black lives matter.
We stand in solidarity with the Black community.
Racism is unacceptable.
It conflicts with the core values of the Kubernetes project and our community does not tolerate it.
We stand in solidarity with the Black community.
Racism is unacceptable.
It conflicts with the core values of the Kubernetes project and our community does not tolerate it.
本指南帮助用户来调试kubernetes上那些没有正常运行的应用。 本指南不能调试集群。如果想调试集群的话,请参阅这里。
故障排查的第一步是先给问题分下类。这个问题是什么?Pods,Replication Controller或者Service?
调试pod的第一步是看一下这个pod的信息,用如下命令查看一下pod的当前状态和最近的事件:
$ kubectl describe pods ${POD_NAME}
查看一下pod中的容器所处的状态。这些容器的状态都是Running
吗?最近有没有重启过?
后面的调试都是要依靠pods的状态的。
如果一个pod卡在Pending
状态,则表示这个pod没有被调度到一个节点上。通常这是因为资源不足引起的。
敲一下kubectl describe ...
这个命令,输出的信息里面应该有显示为什么没被调度的原因。
常见原因如下:
资源不足: 你可能耗尽了集群上所有的CPU和内存,此时,你需要删除pods,调整资源请求,或者增加节点。 更多信息请参阅Compute Resources document
使用了hostPort
:
如果绑定一个pod到hostPort
,那么能创建的pod个数就有限了。
多数情况下,hostPort
是非必要的,而应该采用服务来暴露pod。
如果确实需要使用hostPort
,那么能创建的pod的数量就是节点的个数。
如果一个pod卡在Waiting
状态,则表示这个pod已经调试到节点上,但是没有运行起来。
再次敲一下kubectl describe ...
这个命令来查看相关信息。
最常见的原因是拉取镜像失败。可以通过以下三种方式来检查:
docker pull <image>
命令手动拉下镜像试试。首先,看一下容器的log:
$ kubectl logs ${POD_NAME} ${CONTAINER_NAME}
如果容器是crashed的,用如下命令可以看到crash的log:
$ kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
或者,用exec
在容器内运行一些命令:
$ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}
注意:当一个pod内只有一个容器时,可以不带参数-c ${CONTAINER_NAME}
。
例如,名为Cassandra的pod,处于running态,要查看它的log,可运行如下命令:
$ kubectl exec cassandra -- cat /var/log/cassandra/system.log
如果以上方法都不起作用,找到这个pod所在的节点并用SSH登录进去做进一步的分析。 通常情况下,是不需要在Kubernetes API中再给出另外的工具的。 因此,如果你发现需要ssh进一个主机来分析问题时,请在GitHub上提一个特性请求,描述一个你的场景并说明为什么已经提供的工具不能满足需求。
如果创建的pod不符合预期,那么创建pod的描述文件应该是存在某种错误的,并且这个错误在创建pod时被忽略掉。
通常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文件是mypod.yaml。
运行如下命令来获取apiserver创建的pod信息并保存成一个文件:
kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml
。
然后手动对这两个文件进行比较: apiserver获得的yaml文件中的一些行,不在创建pod的yaml文件内,这是正常的。 如果创建Pod的yaml文件内的一些行,在piserver获得的yaml文件中不存在,可以说明创建pod的yaml中的定义有问题。
RC相当简单。他们要么能创建pod,要么不能。如果不能创建pod,请参阅上述Debugging Pods。
也可以使用kubectl describe rc ${CONTROLLER_NAME}
命令来监视RC相关的事件。
服务提供了多个Pod之间的负载均衡功能。 有一些常见的问题可以造成服务无法正常工作。以下说明将有助于调试服务的问题。
首先,验证服务是否有端点。对于每一个Service对像,apiserver使endpoints
资源可用。
通过如下命令可以查看endpoints资源:
$ kubectl get endpoints ${SERVICE_NAME}
确保endpoints与服务内容器个数一致。 例如,如果你创建了一个nginx服务,它有3个副本,那么你就会在这个服务的endpoints中看到3个不同的IP地址。
如果缺少endpoints,请尝试使用服务的labels列出所有的pod。 假如有一个服务,有如下的label:
...
spec:
- selector:
name: nginx
type: frontend
你可以使用如下命令列出与selector相匹配的pod,并验证这些pod是否归属于创建的服务:
$ kubectl get pods --selector=name=nginx,type=frontend
如果pod列表附合预期,但是endpoints仍然为空,那么可能没有暴露出正确的端口。
如果服务指定了containerPort
,但是列表中的Pod没有列出该端口,则不会将其添加到端口列表。
验证该pod的containerPort
与服务的containerPort
是否匹配。
如果可以连接到服务上,但是连接立即被断开了,并且在endpoints列表中有endpoints,可能是代理和pods之间不通。
确认以下3件事情:
containerPort
字段就需要设定为8080。如果上述都不能解决你的问题,请按照Debugging Service document中的介绍来确保你的Service
处于running态,有Endpoints
,Pods
真正的在服务;你有DNS在工作,安装了iptables规则,kube-proxy也没有异常行为。
你也可以访问troubleshooting document来获取更多信息。