前
作为经验不足的一名运维菜鸟,我没有能够完全hold住这次测试服master节点出现的故障问题。对此很惆怅,会质疑自己的能力,因为我历来以解决大小问题故障而欢喜,每一次没能靠自己解决的问题都会为我带来或大或小的困扰。
这次没能手动解决问题,我还是选择将我的排查解决过程分享出来,或许会为陌生的另一个菜鸟带去一点帮助和启发。更甚,如果有大佬看完我微薄的分析之后能提点一二,不胜感激
一、第一个出现的问题:已有Pod访问出现问题
测试 和 开发 群里圈圈说,某两个服务不能访问了。
尝试一:
尝试访问了其中一个服务,web 报错 504:
分析web访问504问题:
一般情况下nginx访问出现504 Gateway Time-out,是由于程序执行时间过长导致响应超时,比如程序需要执行60秒,而nginx最大响应等待时间为30秒,这样就会出现超时
搜索一下,当出现 504 的时候,可能的情况有以下三种:
1.程序在处理大量数据,导致等待超时。
2.程序中调用外部请求,而外部请求响应超时。
3.连接数据库失败而没有停止,死循环重新连。结合自身实际环境,我觉得比较大可能是第一种情况,所以我第一时间的反应是
先看看
两个服务的Pod
有没有什么问题,然后看看Pod的Owner RS、Deploy有没有问题。# kubectl logs -n NS_NAME Pod_Name # kubectl describe deployment -n NS_NAME Deloy_Name
上述操作结果显示,没有任何报错信息。于是:
logs -f nginx-ingress-controller logs -f pod
log -f nginx-ingress-controller
和logs -f 服务pod
的同时,web访问服务平台,以此测试查看流量走向,对比结果显示流量只到了nginx-ingress-controller,没有到达后端服务pod,难道是nginx-ingress-controller处理请求太多,导致流量阻塞,所以导致了浏览器访问超时?
经理的回复让我感觉事情应该没有这么简单,这问题可能还有先例。
尝试二:
云界面查看相应监控,并没有发现什么过分的数据
但是使用df命令的时候确实是卡住了,emmmmmm,我承认,毕竟我还是运维菜鸟,毕竟没有啥经验,搜!
从这篇文章得知,可以使用
strace
命令查看df运行情况。我运行之后发现卡在了pod挂载的pv,也就是物理机的nfs
上图中可以看出zentao这个服务的pod挂载的外部nfs路径导致df -h 命令卡住了,刚好这时候我想起挂掉的另一个服务pod也挂载了外部nfs路径( 因为这个服云平台的Deploy、svc、ingress是我部署的,所以有记忆 )
分析df -u卡在nfs处:
这时候,我觉得问题已经明晰了,nfs挂掉了,因为df命令基于系统的文件系统来计算磁盘的占用情况的,当nfs挂载点失效时,就导致df命令卡在nfs挂载点处,同时也导致两个服务pod无法使用相应资源导致服务不可用
尝试三:
基于尝试二得出的问题根源在nfs之后,我决定杀掉nfs-server进程并重启一下。
然后emmmm,我发现nfs没有使用systemd托管,然后emmmmmm,作为刚到公司没多长时间的人,我也不知道启动路径在哪儿。。。想起来前一段刚来的那两天,服务器路径结构就给我折磨不行
然后我记得top可以查看进程启动的具体路径来着,就想着通过top命令查一下具体的路径。
然后搜了一下发现,top不能根据进程名称来查看具体信息。可以使用ps命令来查看
# 首先通过ps命令查看具体pid ps -aef | grep nfsd # 拿到pid之后, # 去/proc/pid号 路径下可以查看cwd、exe链接对应目录 # cwd符号链接的是进程运行目录; # exe符号连接就是执行程序的绝对路径
然后我发现,两个链接对应的都是"/",这就让菜鸟的我步步艰难了,就给我整不会了,接着搜。。。
搜半天没搜到,我就在想nfs-server既然没用systemed管理,总得放在哪个目录下吧,不然咋开机重启的,抱着这种想法,我在/etc/init.d/下找到了nfs的启动文件,然后使用该命令重启nfs-server,发现ps -aef | grep nfsd的pid竟然都没变,好家伙,又给整不会了。。。
kill -9 nfsd对应pid,这条命令总该行了吧?杀死该死的nfs之后,我在使用/etc/init.d/下的nfs可执行文件给nfs-server启动起来
然后我又发现kill -9杀不掉,使用top -p pid 查看该进程的状态是D,虽然以前学的时候记得top State的几个状态,你要说经验嘛,还真没有……所以搜!
这篇文章说了kill -9不能杀掉进程的几个原因,这位大佬则是交代了
进程处于D状态一般情况下很短暂,不应该被top或者ps看到。如果看到进程在top和ps看到长期处于D状态,那么可能进程在等待IO时出现了问题导致进程一直等待不到IO资源,此时如果要处理掉这个D进程,那么只能重启整个系统才会恢复。因为此时整个进程无法被kill掉。
二、同时出现的第二个问题:Pod无法创建
故障和工作总是并驾齐驱的嘛~ 就在我还在解决上述问题时,开发小哥哥说他的服务怎么也起不来,Pod一直卡在ContainerCreating状态。查看日志等信息也没有报错什么的。
# 查看pod日志无报错 kubectl logs -n NS pod_name kubectl describe pod -n ns pod_name # decsribe owner deployment kubectl describe
查看日志等没有明显报错,之前也没听说有做ResourceQuota限制,这个Pod也没挂载PV啥的,不应该呀。然后就去查看kubelet日志了,找到几行报错如下:
pod "1d4cc40c-c8ee-44b5-a4b4-667b1f99379a" found, but volume paths are still present on disk
kubectl delete pods pod-name --force --grace-period=0
搜了一下,应该是开发小哥强制删除Pod时造成的问题,然后按照博主提供方法删除了一下已删除Pod的挂载目录。
# 查看 pods 下面数据 ls /var/lib/kubelet/pods/1d4cc40c-c8ee-44b5-a4b4-667b1f99379a/ 注意:直接删除 pod 挂载目录有一定的 危险性, 需要确认是否能删除,如果确认没有问题可以直接删除。 # 查看 etc-hosts 文件中 pod name 名称 cat /var/lib/kubelet/pods/1d4cc40c-c8ee-44b5-a4b4-667b1f99379a/etc-hosts # 删除 1d4cc40c-c8ee-44b5-a4b4-667b1f99379a 目录 cd /var/lib/kubelet/pods/ rm -rf 1d4cc40c-c8ee-44b5-a4b4-667b1f99379a
随后开发小哥吃饭去了,我就用他的yaml重新apply发现,这次pod仍然卡住,但是Pod有报错信息了,来自kubelet:
基于Pod报错分析:
Unable to mount volumes for pod xxx : timeout expired waiting for volumes to attach or mount for pod xxx.
,这是上图kubelet的Pod报错基于这个问题,我觉得问题根源可能就是磁盘出了问题,导致nfs不能加载,等待io,导致开发小哥的Pod不能创建
然后我就放弃了自己探索,之前经理也说让提个工单问一下,帮不帮另说,我就去提了工单求助。
疯狂等待与补充知识……然后其他部门的同事就来催我部门的朋友,同部门的朋友就来催我,时间就是生命,我向领导说明之后,选择了妥协,重启。
重启之后看到无数个NS下的POD都是ERROR,心一惊。虽然跟领导交代了,还是感觉,完了,闯祸了………
好在过了一会,所有POD都被Owner的RS全部重新拉起了。然后之前的df -h问题,两个服务问题全部都好了,开发小哥的Pod也创建出来了。重启果然解决80%问题。但是作为初入职场的运维菜鸟,好想有大佬带着我一块把这个问题手动解决了,多宝贵的经验啊,可惜……
后续问题又复现了,我最终确定问题应该是出在禅道服务使用了nfs进程卡住,导致磁盘读写有问题,我将禅道系统使用的nfs文件系统更换成了hostPath之后再没出现过对应问题,done