解決K8S中Pod無法正常Mount PVC的問題
今天發(fā)現(xiàn)一個(gè)Pod一直處于ContainerCreating狀態(tài),通過Describe查看,發(fā)現(xiàn)以下錯誤。
- Warning FailedMount 15s kubelet, node-2 MountVolume.WaitForAttach failed for volume "pvc-504feeb6-ae42-45ba-996b-5e8e1039b601" : rbd image kube/kubernetes-dynamic-pvc-bbfd3466-9f2f-11ea-8e91-5a4125e02b87 is still being used
意思就是說該P(yáng)od啟動需要掛載PVC,但是這個(gè)PVC目前正被使用??梢源_定的是除了這個(gè)Deployment之外,沒有其他Deployment在使用這個(gè)PVC,那這是為什么呢?
我們先來看看如果一個(gè)Pod需要掛載卷,在創(chuàng)建Pod的過程中,卷的整個(gè)流程如下:(1)第一步是先創(chuàng)建卷 (2)第二步在節(jié)點(diǎn)上掛載卷 (3)將卷映射到Pod中
在刪除Pod的時(shí)候,卷的卸載過程和上面正好相反。所以初步懷疑是在刪除Pod的時(shí)候,原節(jié)點(diǎn)由于某些原因從節(jié)點(diǎn)上卸載卷失敗,我們來具體排查一下。
1、通過上面Pod的錯誤信息,我們可以獲取到如下有用信息
- rbd image kube/kubernetes-dynamic-pvc-bbfd3466-9f2f-11ea-8e91-5a4125e02b87 is still being used
我們可以從上面的信息獲取到rbd的鏡像信息,拆分如下:
- rbd池:kube
- rbd鏡像:kubernetes-dynamic-pvc-bbfd3466-9f2f-11ea-8e91-5a4125e02b87
2、我們通過ceph命令可以獲取到該鏡像被哪個(gè)節(jié)點(diǎn)使用,如下:
- # rbd info kube/kubernetes-dynamic-pvc-bbfd3466-9f2f-11ea-8e91-5a4125e02b87
- rbd image 'kubernetes-dynamic-pvc-bbfd3466-9f2f-11ea-8e91-5a4125e02b87':
- size 100 GiB in 25600 objects
- order 22 (4 MiB objects)
- snapshot_count: 0
- id: fb236b8b4567
- block_name_prefix: rbd_data.fb236b8b4567
- format: 2
- features: layering
- op_features:
- flags:
- create_timestamp: Tue May 26 17:03:15 2020
- access_timestamp: Tue May 26 17:03:15 2020
- modify_timestamp: Tue May 26 17:03:15 2020
主要關(guān)注block_name_prefix的值。
然后通過以下的命令獲取到具體的節(jié)點(diǎn):
- # rados listwatchers -p kube rbd_header.fb236b8b4567
- watcher=192.168.100.181:0/154937577 client.194364 cookie=18446462598732840971
其中,將從block_name_prefix獲取到的值將rbd_data修改為rbd_header,然后通過以上命令獲取即可。
從上面輸出的信息可以看到這個(gè)rbd鏡像被掛載到192.168.100.181主機(jī)上,這時(shí)候我們需要切換到該主機(jī)進(jìn)行具體的操作。
3、查看具體的文件系統(tǒng)掛載信息
- ls /dev/rbd/kube/kubernetes-dynamic-pvc-bbfd3466-9f2f-11ea-8e91-5a4125e02b87 -l
- lrwxrwxrwx 1 root root 11 7月 27 09:04 /dev/rbd/kube/kubernetes-dynamic-pvc-bbfd3466-9f2f-11ea-8e91-5a4125e02b87 -> ../../rbd4
可以看到這個(gè)rbd鏡像被掛載到/dev/rbd4上,我們可以直接通過rbd unmap命令卸載,如下:
- # rbd unmap /dev/rbd4
不過我這里并沒有這么容易,當(dāng)我在卸載的時(shí)候報(bào)如下錯誤。
- # rbd unmap /dev/rbd4
- rbd: sysfs write failed
- rbd: unmap failed: (16) Device or resource busy
一看到這個(gè)問題,就想到有時(shí)候在umount的時(shí)候,也會遇到Device busy,所以第一反應(yīng)是使用lsof,看是否能找到哪個(gè)進(jìn)程占用了,如下:
- # lsof 2>/dev/null | grep rbd4
但是我并沒有找到任何進(jìn)程,二臉懵逼.....
最后只有瘋狂百度了,找到了兩種解決方式。(1)通過rbd unmap -o force進(jìn)行強(qiáng)制卸載 (2)通過grep 'rbd4' /proc/*/task/*/mountinfo來查找進(jìn)程PID
當(dāng)把這個(gè)rbd鏡像從原節(jié)點(diǎn)卸載過后,就可以看到Pod可以正常啟動了。
寫在最后
由于我是使用的Deployment來管理的有狀態(tài)應(yīng)用,正常使用StatefulSet不會出現(xiàn)這種問題,那使用Deployment該如何避免這種問題呢?
- 使用ReadWriteMany訪問模式的pvc
- 將maxSurge設(shè)置為0,避免在更新過程中產(chǎn)生多余的pod
這兩種方式都有利有弊,具體情況需要使用者去權(quán)衡。
本文轉(zhuǎn)載自微信公眾號「運(yùn)維開發(fā)故事」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系運(yùn)維開發(fā)故事公眾號。