k8s测试服磁盘故障(目测)的一次复盘

k8s测试服磁盘故障(目测)的一次复盘

Scroll Down

作为经验不足的一名运维菜鸟,我没有能够完全hold住这次测试服master节点出现的故障问题。对此很惆怅,会质疑自己的能力,因为我历来以解决大小问题故障而欢喜,每一次没能靠自己解决的问题都会为我带来或大或小的困扰。

这次没能手动解决问题,我还是选择将我的排查解决过程分享出来,或许会为陌生的另一个菜鸟带去一点帮助和启发。更甚,如果有大佬看完我微薄的分析之后能提点一二,不胜感激

一、第一个出现的问题:已有Pod访问出现问题

测试 和 开发 群里圈圈说,某两个服务不能访问了。
1chaterror.png

尝试一:

尝试访问了其中一个服务,web 报错 504:
1nginx504.png

分析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-controllerlogs -f 服务pod 的同时,web访问服务平台,以此测试查看流量走向,对比结果显示流量只到了nginx-ingress-controller,没有到达后端服务pod,难道是nginx-ingress-controller处理请求太多,导致流量阻塞,所以导致了浏览器访问超时?

经理的回复让我感觉事情应该没有这么简单,这问题可能还有先例。

1chathardwareerror.png

尝试二:

云界面查看相应监控,并没有发现什么过分的数据

2cloudmonitor.png

但是使用df命令的时候确实是卡住了,emmmmmm,我承认,毕竟我还是运维菜鸟,毕竟没有啥经验,搜!

这篇文章得知,可以使用strace命令查看df运行情况。我运行之后发现卡在了pod挂载的pv,也就是物理机的nfs

1stracedfh.png

上图中可以看出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符号连接就是执行程序的绝对路径

然后我发现,两个链接对应的都是"/",这就让菜鸟的我步步艰难了,就给我整不会了,接着搜。。。

psproc.png

搜半天没搜到,我就在想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的几个状态,你要说经验嘛,还真没有……所以搜!

2nfs_state.png

这篇文章说了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:

3kubeletpoderror.png

3.1kubeletpoderror.png

基于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不能创建

然后我就放弃了自己探索,之前经理也说让提个工单问一下,帮不帮另说,我就去提了工单求助。
aliCloud.png

疯狂等待与补充知识……然后其他部门的同事就来催我部门的朋友,同部门的朋友就来催我,时间就是生命,我向领导说明之后,选择了妥协,重启。

重启之后看到无数个NS下的POD都是ERROR,心一惊。虽然跟领导交代了,还是感觉,完了,闯祸了………

好在过了一会,所有POD都被Owner的RS全部重新拉起了。然后之前的df -h问题,两个服务问题全部都好了,开发小哥的Pod也创建出来了。重启果然解决80%问题。但是作为初入职场的运维菜鸟,好想有大佬带着我一块把这个问题手动解决了,多宝贵的经验啊,可惜……