常用的排查命令
1、查看组件状态
#kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-1 Healthy {"health":"true"}
etcd-2 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}
2、查看集群状态
#kubectl cluster-info
Kubernetes master is running at https://10.45.1.1:6443
metrics-server is running at https://10.45.1.1:6443/api/v1/namespaces/kube-system/services/heapster/proxy
KubeDNS is running at https://10.45.1.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
导出集群信息供排查
#kubectl cluster-info dump --namespace kube-system --output-directory=/path/to/cluster-state
3、查看Node状态
#kubectl get node
NAME STATUS ROLES AGE VERSION
c43k09010.cloud.k09.amtest81 Ready master,minio-0,ops1,prometheus,redis-0,worker 6d22h v1.14.8-aliyun.1
c43k090108.cloud.k09.amtest81 Ready worker 6d20h v1.14.8-aliyun.1
c43k090109.cloud.k09.amtest81 Ready worker 6d20h v1.14.8-aliyun.1
c43k090110.cloud.k09.amtest81 Ready worker 6d20h v1.14.8-aliyun.1
c43k090111.cloud.k09.amtest81 Ready worker 6d20h v1.14.8-aliyun.1
c43k090112.cloud.k09.amtest81 Ready worker 6d20h v1.14.8-aliyun.1
c43k090113.cloud.k09.amtest81 Ready worker 6d20h v1.14.8-aliyun.1
c43k090114.cloud.k09.amtest81 Ready worker 6d20h v1.14.8-aliyun.1
c43k090115.cloud.k09.amtest81 Ready worker 6d20h v1.14.8-aliyun.1
c43k09012.cloud.k09.amtest81 Ready master,minio-1,prometheus,redis-1,worker 6d22h v1.14.8-aliyun.1
c43k09108.cloud.k10.amtest81 Ready master,minio-2,redis-2,worker 6d22h v1.14.8-aliyun.1
#kubectl describe node <node-name>
4、查看Pod
#kubectl get pod -owide -A 查看所有命名空间的pod
#kubectl get pod -owide -n <namespace> 查看指定命名空间的pod
#kubectl get pod <pod-name> -oyaml -n <namespace> 查看pod定义及状态
#kubectl describe pod <pod-name> -n <namespace> 查看pod信息及event事件
#kubectl logs -f <pod-name> -n <namespace> -c <container-name> 查看pod日志
5、查看svc
#kubectl get svc -owide -A 查看所有命名空间的svc
#kubectl get svc -owide -n <namespace> 查看指定命名空间的svc
#kubectl get svc <svc-name> -oyaml -n <namespace> 查看svc定义及状态
#kubectl describe svc <svc-name> -n <namespace> 查看svc信息,event及后端endpoint
6、查看组件日志
获取核心组件:
#kubectl get pod -l component=xxx -n kube-system (component:kube-apiserver/kube-controller-manager/kube-scheduler)
获取addon组件:
#kubectl get pod -l k8s-app=xxx -n kube-system (k8s-app:kube-dns/kube-proxy-master/kube-proxy-worker)
查看日志
#kubectl logs <pod-name> -n kube-system
查看上一次的log
#kubectl logs <pod-name> -n kube-system --previous
获取集群日志
#kubectl cluster-info dump --namespace default,kube-system,... --output-directory=/path/to/dump
7、kubelet日志
#cd /cloud/app/kube-base/NodeDaemon#/kubelet/current/
#vim log/tianji/stderr
#vim log/tianji/stdout
8、其他命令参考
https://kubernetes.io/zh/docs/reference/kubectl/cheatsheet/
https://jimmysong.io/kubernetes-handbook/guide/kubectl-cheatsheet.html
K8S组件异常
1、kubelet未正常启动
现象:
pidof kubelet不存在
诊断:
1)检查swap是否关闭swapon -s
,如果未关闭需要关闭swap swapoff -a
2)检查docker daemon是否启动正常 docker info,如无正确输出,检查docker daemon启动失败原因
3)检查kube-base.NodeDaemon#中kubelet启动流程是否有异常,目前kubelet在kubeadm init/join成功后启动,通过启动log检查前置条件是否有异常
4)kubelet启动失败,先通过log/start.log查看启动参数是否有不正确的配置,如果配置正确还是未正常启动,通过log/tianji/stderr查看启动失败原因基本都能看到原因,kubelet启动成功后healthz状态为ok
curl http://127.0.0.1:10248/healthz
ok
kubelet具体失败原因需要根据日志信息具体问题具体分析,可提取error信息,然后判断,需要积累知识库; 创建问题:
a) /var/lib/kubelet/pki/kubelet-client-current.pem生成的内容为空,导致启动失败,重启执行kubeadm init/join
b) kubelet日志存在一下信息说明watch的目录数量超过了系统当前配置的最大值,需要调整下fs.inotify.max_user_watches值:sysctl -w fs.inotify.max_user_watches=xxxx (默认8192,可以先调整到一倍)或者固化到/etc/sysctl.conf中。
Failed to watch directory "/sys/fs/cgroup/memory/docker/245893f1f5392e243d2586b1af96244e5b12bd23a24d8b02d048002cc59e4a44": inotify_add_watch /sys/
fs/cgroup/memory/docker/245893f1f5392e243d2586b1af96244e5b12bd23a24d8b02d048002cc59e4a44: no space left on device
Failed to watch directory "/sys/fs/cgroup/memory/docker": inotify_add_watch /sys/fs/cgroup/memory/docker/245893f1f5392e243d2586b1af96244e5b12bd23a
24d8b02d048002cc59e4a44: no space left on device
2、kubectl访问慢
现象:
诊断:
这种问题一般都是kubectl在获取信息过程中会去访问一些svc超时重试导致如webhook/servicecatalog,通过kubectl -v=8提高日志级别来查看哪些svc访问不了,一般和网络插件有关
3、coredns pod未正常运行
现象:
coredns pod一直处于ContainerCreating状态
诊断:
kubectl describe pod coredns-xxx -n kube-system
从event事件中看到type为warning,Reason为FailedCreatePodSandbox, message包含arp resolve gw ip error
信息,这种由于pod ip到gateway arp不通,一般是交换机配置问题,请环境owner排查交换机等网络配置
4、coredns pod CrashLoopBackoff
现象:
coredns处于CrashLoopBackoff状态
诊断:
1)kubectl logs -f coredns-xxx(dnspod name) -n kube-system,如果发现以下错误信息,说明pod网络访问异常,请联系网络同学排查:
github.com/coredns/coredns/plugin/kubernetes/controller.go:322: Failed to list *v1.Namespace: Get https://10.96.0.1:443/api/v1/namespaces?limit=500&resourceVersion=0: dial tcp 10.96.0.1:443: connect: no route to host
2)如果出现以下错误信息,查询系统/etc/resolv.conf配置是否存在环问题,如果存在本地回环如127.0.0.1或者127.0.0.53那么就容易造成死循环,修改/etc/resolv.conf配置
plugin/loop: Loop (127.0.0.1:44222 -> :53) detected for zone
3)其他问题:无法转发到上游DNS服务器,请排查coredns配置以及Node网络问题
a)coredns pod的dnspolicy需要配置成default模式,如果因为误配置配置成clusterfirst模式会导致转发给自己而产生错误导致域名无法解析
官方文档参考:https://kubernetes.io/zh/docs/tasks/administer-cluster/dns-debugging-resolution/#is-dns-service-up
Node异常
1、节点kubelet有Pressure导致节点NotReady
现象:
kubectl get node 显示节点 NotReady
诊断:
1)kubectl get po -A -owide | grep Evicted; 结果不为空
2)使用kubectl get node xxx -oyaml;查看Evicted的pod所在的Node,查看DiskPressure/PIDPressure/MemoryPressure的status是否为true;
- MemoryPressure为True,表示节点内存压力大,实际可用内存很少;
- PIDPressure为True,表示节点上运行了太多的进程,PID数量不足;
- DiskPressure为True,表示节点上磁盘可用空间不足;
3)对于有DiskPressure的节点,使用df /var/lib/kubelet -h
,如果大于90%;使用df /var/lib/docker -h
来查看,如果大于95%。
4)根分区满了
资源配置不足时的处理方式:https://kubernetes.io/zh/docs/tasks/administer-cluster/out-of-resource/
2、PLEG问题导致节点NotReady
现象:
kubectl get node 显示节点 NotReady
诊断:
1)kubectl describe node XXX 的 Conditions Mesage 部分显示节点 PLEG 时间过长(超过3min),导致节点被判定为 NotReady;或者kubelet日志有如下信息:
kubelet.go:1794] skipping pod synchronization - [container runtime is down PLEG is not healthy: pleg was last seen active 21m18.877402888s ago; threshold is 3m0s]
2)到NotReady的节点,模拟PLEG扫描节点容器状态,如果有docker inspect hang的现象,则为docker daemon的问题,查看是否有runc卡住的问题
docker ps -q |while read id; do echo $id; docker inspect $id 2>&1;done
ps -elf | grep inspect #查看是否有inspect卡住的现象
ps -elf | grep runc #查看是否有runc 卡住的情况
3、cni config不存在导致节点NotReady
现象:
kubectl get node 显示节点 NotReady,原因如下cni config uninitialized
诊断:
查看/etc/cni/net.d/目录,cni配置不存在,当前cni配置由cni插件来安装,可尝试重启对应节点的cni插件pod恢复
4、Kubelet状态未同步到apiserver导致节点NotReady
现象:
kubectl get node 显示节点 NotReady,没有PLEG问题
诊断:
1)kubectl describe node XXX 的 Conditions Mesage 部分显示节点停止上报节点状态,导致节点被判定为 NotReady
2)首先查看kubelet日志是否存在kubelet连接不上apiserver的日志,
a) 如果apiserver地址127.0.0.1,说明节点上存在代理,kubectl get pod -A | grep api-proxy查看api-proxy pod是否正常运行,根据对应的pod状态排查异常原因
b)如果kubelet日志存在如下信息,说明部署时候证书生成有问题
3)如果对应节点的kubelet日志存在如下信息,说明hostname被误改
4)如果对应节点的kubelet日志中显示如下信息,在注册节点的时候出现”use of closed network connection”或者”Timeout:request did not complete with requested timeout 30s”信息:
5)首先在对应的节点上排查apiserver对应的端口能否能够正常连通
telnet apiserver-vip 6443
6)端口能正常连接,可以查看apiserver的日志,在对应的register node时间段查看异常信息,一般为webhook问题,如下面的异常日志,注册节点状态时会通过扩展的webhook来validate,而当前的webhook后端访问不了,导致节点注册不了
E0106 11:29:56.705517 1 dispatcher.go:69] failed calling webhook "validate.harmonycloud.cn": Post https://10.75.32.57:30043/validate?timeout=30s: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
W0106 11:30:03.712378 1 admission.go:353] node "d42d06017.cloud.d06.amtest65" added disallowed labels on node creation: node-role.kubernetes.io/worker
I0106 11:30:33.712914 1 trace.go:81] Trace[1833714781]: "Create /api/v1/nodes" (started: 2021-01-06 11:30:03.711893924 +0800 CST m=+2513.201709824) (total time: 30.00098848s):
Trace[1833714781]: [30.00098848s] [30.000399358s] END
W0106 11:30:33.713377 1 dispatcher.go:68] Failed calling webhook, failing open validate.harmonycloud.cn: failed calling webhook "validate.harmonycloud.cn": Post https://10.75.32.57:30043/validate?timeout=30s: context deadline exceeded (Client.Timeout exceeded while awaiting headers)
E0106 11:30:33.713426 1 dispatcher.go:69] failed calling webhook "validate.harmonycloud.cn": Post https://10.75.32.57:30043/validate?timeout=30s: context deadline exceeded (Client.Timeout exceeded while awaiting headers)
W0106 11:30:40.720189 1 admission.go:353] node "d42d06017.cloud.d06.amtest65" added disallowed labels on node creation: node-role.kubernetes.io/worker
相关的webhook查询方式:
# mutatingwebhook配置
kubectl get mutatingwebhookconfigurations
NAME CREATED AT
ark-webhook-mutating-webhook-configuration 2021-01-12T05:13:23Z
kruise-mutating-webhook-configuration 2021-01-12T05:15:03Z
mutators.kubedb.com 2021-01-12T07:50:01Z
paas-assistant-mutating-webhook-cfg 2021-01-12T05:14:35Z
rama-mutating-webhook 2021-01-12T05:11:40Z
# validatingwebhook
kubectl get validatingwebhookconfigurations
NAME CREATED AT
kruise-validating-webhook-configuration 2021-01-12T05:15:04Z
rama-validating-webhook 2021-01-12T05:11:40Z
validators.kubedb.com
根据apiserver中的异常信息,查看对应的webhook配置信息,是否有针对node的webhook配置,如果有,查看后端的svc是否能访问,不能访问,如例子中webhook:validate.harmonycloud.cn后端不存在,导致节点注册不上
Pod异常
Pod状态
状态 | 描述 |
---|---|
Error |
Pod 启动过程中发生错误 |
NodeLost |
Pod 所在节点失联 |
Unkown |
Pod 所在节点失联或其他未知异常 |
Waiting |
Pod 等待启动 |
Pending |
Pod 等待被调度 |
ContainerCreating |
Pod 容器正在被创建 |
Terminating |
Pod 正在被销毁 |
CrashLoopBackOff |
容器退出,Kubelet 正在将它重启 |
InvalidImageName |
无法解析镜像名称 |
ImageInspectError |
无法校验镜像 |
ErrImageNeverPull |
策略禁止拉取镜像 |
ImagePullBackOff |
正在重试拉取 |
RegistryUnavailable |
连接不到镜像中心 |
ErrImagePull |
通用的拉取镜像出错 |
CreateContainerConfigError |
不能创建 Kubelet 使用的容器配置 |
CreateContainerError |
创建容器失败 |
RunContainerError |
启动容器失败 |
PreStartHookError |
执行 preStart hook 报错 |
PostStartHookError |
执行 postStart hook 报错 |
ContainersNotInitialized |
容器没有初始化完毕 |
ContainersNotReady |
容器没有准备完毕 |
ContainerCreating |
容器创建中 |
PodInitializing |
Pod 初始化中 |
DockerDaemonNotReady |
Docker 还没有完全启动 |
NetworkPluginNotReady |
网络插件还没有完全启动 |
Pod常见问题
Pod异常问题大部分直接通过Pod状态就可以判断相关的错误原因,对于以下几个状态,导致处于该状态的可能原因较多而且在实际的运维过程中也比较常见,所以单独介绍如何排查。
1、Pod处于Pending状态
该状态下,说明Pod还未被调度到某个节点上,通过kubectl describe pod <pod-name>
从Events中基本可以查到当前Pod FailedScheduling的具体原因:
可能的原因:
- 资源不足,所有的Node都满足不了该Pod的资源请求
- Node存在Pod无法容忍的污点
- Node不满足Pod的nodeSelector或者亲和性要求PodAffinity/PodAntiAffinity/NodeAffinity
- Node没有满足条件的local PV
- kube-scheduler异常
诊断:
1)资源不足主要看CPU和Mem可分配的资源量是否满足pod的request值,对于使用GPU的场景,关注剩余可用的GPU数量是否足够,通过kubectl describe node
2)通过kubectl get pod
3)检查nodeSelector以及Affinity配置,是否所有的node都没有pod对应的nodeselector标签,或者Node都不满足nodeAffinity条件,如果两种情况都不存在检查Node上是否存在不满足podAffinity/podAntiAffinity的pod导致无法调度
4)检查pod声明使用的pvc是否处于bound状态,特别对于local pv的情况,如果所有节点没有满足pvc条件的pv存在则无法完成调度
5)如果上述情况都不存在,可能kube-scheduler组件存在异常,查看组件log排查
2、Pod处于Waiting/ContainerCreating状态
通过 kubectl describe pod <pod-name>
命令查看到当前 Pod 的事件消息获取具体的失败原因:
可能原因:
- Pod配置错误
- 镜像拉取失败
- 挂载volume失败
- 磁盘空间不足
- CNI网络错误
- 容器引擎异常
- 存在同名容器
- kube-controller-manager异常
诊断:
1)排查Pod配置是否正确,正确的镜像/容器参数,limit配置是否过小导致容器已启动就被oom kill等
2)排查是否有镜像拉取失败或者镜像太大拉取时间长的情况;以及通过kubelet日志查看是否有docker inspect失败问题(或者docker inspect 镜像名/镜像id)
3)检查kubelet日志是否存在容器挂载volume异常的信息及原因
4)检查磁盘空间是否不足,在pod创建过程中会在容器目录下创建相关目录,如果磁盘空间不足导致容器创建失败,df -h /var/lib/docker如果空间占满,进行清理或者扩容
5)如果kubectl describe pod
6)检查容器容器引擎是否存在问题,会导致容器创建失败,通过kubectl describe pod
7)节点上存在同名容器会导致创建sanbox失败,从events里能看到Conflict信息,先确定重名的原因然后可通过删除之前的同名容器解决
8)如果上述情况都不存在,查看kube-controller-manager日志,排查组件问题
3、Pod处于ImagePullBackOff状态
该状态主要因为镜像拉取失败导致,可以手动docker pull image来查看具体的问题
可能原因:
- 镜像不存在
- 镜像拉取超时
- 镜像仓库认证问题
- HTTP 类型 Registry 地址未加入 insecure-registry
- HTTPS 自签发类型 Registry CA 证书未添加至节点
- 私有镜像仓库认证失败
- 镜像文件损坏
诊断:
1)这个问题直接从events事件中基本可以看出原因,对于不存在的容器镜像,请先联系产品确保是否使用正确的镜像,然后docker pull 如果环境仓库不存在先排查基线是否写的问题,基线没问题然后排查部署拷包是否有异常,环境可通过CICD镜像拷贝临时解决
2)对于镜像拉取超时,如果镜像过大导致的超时需要优化镜像大小或者事先在环境上拉取好镜像,如果因为同时启动大量的pod导致的镜像下载需要排队,可通过配置kubelet开启并行下载及控制并发,对应参数registry-qps/registry-burst
3) docker pull出现仓库认证问题,根据错误信息请联系环境owner处理,认证问题参考官方文档解决:https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry
4)如果push/pull镜像过程中有镜像损坏,也可能出现该状态,重新push/pull
4、Pod处于CrashLoopBackOff状态
该状态说明容器出现异常退出的情况,可能原因:
- 容器进程主动退出
- OOM killed
- 健康检查失败
诊断:
1)检查容器是否主动退出,kubectl describe pod
#kubectl logs <pod-name> -n kube-system --previous
2)如果容器的退出状态码为137=128+9,说明是被主动kill的,如果没有认为的主动kill操作,一般可能存在oom问题
a) 系统oom:如果其他非k8s管理的进程占用了太多的内存,导致系统内存不足,发生了oom,从内核日志中可以看到相关的信息Out of memory: Kill process
,可以根据实际的需求通过kubelet预留足够的资源
b)cgroup oom:从Pod Events中看到Reason为OOMKilled,说明容器实际占用的内存超过了limit的配置,先排查业务进程是否存在内存泄漏的情况,如果没过,则需要根据业务需求调整limit值
3)连续健康检查失败超过配置的次数导致容器重启,从Pod Events日志中可以看到相关信息
5、Pod处于Error状态
该状态说明Pod启动过程中出现了错误,从Pod Events中可以看到相关的可能原因:
可能原因
- 依赖的 ConfigMap、Secret 或者 PV 等不存在
- 请求的资源超过了管理员设置的限制,比如超过了 LimitRange 等
- 违反集群的安全策略,比如违反了 PodSecurityPolicy 等
- 容器无权操作集群内的资源,比如开启 RBAC 后,需要为 ServiceAccount 配置角色绑定
诊断:
1)kubectl get pod
2)查看pod所在的namespace下的limitrange,kubectl get limitrange -o yaml -n
3)是否违反PodSecurityPolicy请参考:https://kubernetes.io/zh/docs/concepts/policy/pod-security-policy/#via-rbac
4)是否无权操作集群资源请参考:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
6、Pod处于Terminating状态
除了kubectl describe pod外,可以查看kubelet日志排查原因:
可能原因:
- 容器删除不掉
- PV umount不掉
- 容器引擎问题
- 存在finalizers
- Node失联,将其上的pod标记为该状态
诊断:
1)如果从pod Events中看不出具体的错误,可以从kubelet日志,根据podname过滤日志信息,获取对应的容器delete失败原因进行排查,如容器目录存在无法删除的文件等
2)如果容器已经成功Terminated,但是无法umount之前挂载的volume,常见的问题日志如下,通过lsof +d 目录查看哪些进程在占用该目录下的问题:
“umount: /var/lib/kubelet/pods/xxxxx/volumes/xxx: target is busy"
3)查看容器引擎是否正常,可先运行下docker ps能够正常输出,然后通过kubectl describe pod
4)如果Pod的metadata中存在finalizers,通常说明该Pod是由某个组件创建的,finalizers 中也会添加一个专属于该组件的标识。通常在删除该Pod时,需要由创建该Pod的组件进行删除前的清理,且只有清理完成并将标识从Pod的finalizers中移除,才可以彻底删除Pod,如果Pod因为finalizers不为空导致一直处于Terminating状态,联系该组件的owner处理,或者kubectl edit该pod将finalizers设置为空
5)如果pod所在的node关机或者网络连接不上导致节点失联,node上的pod会被置于该状态
7、Pod处于Init状态
kubectl describe pod查看event事件,也可以查看kubelet日志排查原因:
可能原因:
- Init容器启动失败/或者在pending状态未执行完毕
- init容器创建过程中hang住
- 网络插件问题导致sanbox创建异常
诊断:
1)kubect logs pod名 -n namespace名 -c init容器名 查看启动失败或这pending的原因
2)检查容器容器引擎是否存在问题,会导致容器创建失败,通过kubectl describe pod
3)典型的现象就是event中出现“DeadlineExceeded desc = context deadline exceeded”,检查对应节点上的网络插件是否为running状态(rama:rama-daemon;terway:terway-vlan; nimitz: nimitz-netplugin&nimitz-openvswitch),然后检查节点上是否存在网络插件进程hang住的情况ps -elf | grep 插件名(rama:rama;terway:terway-vlan;nimitzk8s);如果存在问题,重启节点上的网络插件pod尝试恢复