任务

任务
管理集群
Debug DNS 方案
Enabling Service Topology (EN)
IP Masquerade Agent 用户指南
Kubernetes 云管理控制器
Safely Drain a Node while Respecting the PodDisruptionBudget (EN)
为 Kubernetes 运行 etcd 集群
为系统守护进程预留计算资源
为节点发布扩展资源
使用 CoreDNS 进行服务发现
使用 KMS 提供商进行数据加密
使用 Kubernetes API 访问集群
关键插件 Pod 的调度保证
启用端点切片
命名空间演练
在 Kubernetes 集群中使用 NodeLocal DNSCache
在 Kubernetes 集群中使用 sysctl
在实时集群上重新配置节点的 Kubelet
声明网络策略
开发云控制器管理器
控制节点上的 CPU 管理策略
控制节点上的拓扑管理策略
搭建高可用的 Kubernetes Masters
改变默认 StorageClass
更改 PersistentVolume 的回收策略
自定义 DNS 服务
访问集群上运行的服务
通过命名空间共享集群
通过配置文件设置 Kubelet 参数
配置 API 对象配额
配置多个调度器
配置资源不足时的处理方式
限制存储消耗
集群 DNS 服务自动伸缩
集群安全
集群管理
静态加密 Secret 数据
用插件扩展 kubectl
管理巨页(HugePages)
调度 GPUs

Edit This Page

应用故障排查

本指南帮助用户来调试kubernetes上那些没有正常运行的应用。 本指南*不能*调试集群。如果想调试集群的话,请参阅这里

诊断问题

故障排查的第一步是先给问题分下类。这个问题是什么?Pods,Replication Controller或者Service?

Debugging Pods

调试pod的第一步是看一下这个pod的信息,用如下命令查看一下pod的当前状态和最近的事件:

$ kubectl describe pods ${POD_NAME}

查看一下pod中的容器所处的状态。这些容器的状态都是Running吗?最近有没有重启过?

后面的调试都是要依靠pods的状态的。

pod停留在pending状态

如果一个pod卡在Pending状态,则表示这个pod没有被调度到一个节点上。通常这是因为资源不足引起的。 敲一下kubectl describe ...这个命令,输出的信息里面应该有显示为什么没被调度的原因。 常见原因如下:

  • 资源不足: 你可能耗尽了集群上所有的CPU和内存,此时,你需要删除pods,调整资源请求,或者增加节点。 更多信息请参阅Compute Resources document

  • 使用了hostPort: 如果绑定一个pod到hostPort,那么能创建的pod个数就有限了。 多数情况下,hostPort是非必要的,而应该采用服务来暴露pod。 如果确实需要使用hostPort,那么能创建的pod的数量就是节点的个数。

pod停留在waiting状态

如果一个pod卡在Waiting状态,则表示这个pod已经调试到节点上,但是没有运行起来。 再次敲一下kubectl describe ...这个命令来查看相关信息。 最常见的原因是拉取镜像失败。可以通过以下三种方式来检查:

  • 使用的镜像名字正确吗?
  • 镜像仓库里有没有这个镜像?
  • docker pull <image>命令手动拉下镜像试试。

pod处于crashing状态或者unhealthy

首先,看一下容器的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处于running态,但是没有正常工作

如果创建的pod不符合预期,那么创建pod的描述文件应该是存在某种错误的,并且这个错误在创建pod时被忽略掉。 通常pod的定义中,章节被错误的嵌套,或者一个字段名字被写错,都可能会引起被忽略掉。 例如,希望在pod中用命令行执行某个命令,但是将command写成commnd,pod虽然可以创建,但命令并没有执行。

如何查出来哪里出错? 首先,删掉这个pod再重新创建一个,重创时,像下面这样带着--validate这个参数: kubectl create --validate -f mypod.yamlcommand写成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中的定义有问题。

Debugging Replication Controllers

RC相当简单。他们要么能创建pod,要么不能。如果不能创建pod,请参阅上述Debugging Pods

也可以使用kubectl describe rc ${CONTROLLER_NAME}命令来监视RC相关的事件。

Debugging Services

服务提供了多个Pod之间的负载均衡功能。 有一些常见的问题可以造成服务无法正常工作。以下说明将有助于调试服务的问题。

首先,验证服务是否有端点。对于每一个Service对像,apiserver使endpoints资源可用。

通过如下命令可以查看endpoints资源:

$ kubectl get endpoints ${SERVICE_NAME}

确保endpoints与服务内容器个数一致。 例如,如果你创建了一个nginx服务,它有3个副本,那么你就会在这个服务的endpoints中看到3个不同的IP地址。

服务缺少endpoints

如果缺少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件事情:

  • Pods工作是否正常? 看一下重启计数,并参阅Debugging Pods
  • 可以直接连接到pod上吗?获取pod的IP地址,然后尝试直接连接到该IP上;
  • 应用是否在配置的端口上进行服务?Kubernetes不进行端口重映射,所以如果应用在8080端口上服务,那么containerPort字段就需要设定为8080。

更多信息

如果上述都不能解决你的问题,请按照Debugging Service document中的介绍来确保你的Service处于running态,有EndpointsPods真正的在服务;你有DNS在工作,安装了iptables规则,kube-proxy也没有异常行为。

你也可以访问troubleshooting document来获取更多信息。

反馈