Pod掛載Volume失敗問題分析
Kubernetes環境偶爾出現StatefulSet中的Pod被刪除,新啟動的Pod(還是排程到原有節點)掛載volume失敗的問題,如下圖,經過一番定位分析,也讓我們對於Kubernetes系統複雜程度有了新的認知。
在分析此問題之前,作為相關背景知識,先簡單介紹對於Kubernetes儲存系統的理解。
| 儲存系統簡析
儲存也是Kubernetes中比較重要而複雜的系統,功能比較龐大,涉及到不同元件中,不同控制器的協作,如下圖。
-
provision,卷分配成功
-
attach,卷掛載在對應worker node
-
mount,卷掛載為檔案系統並且對映給對應Pod
-
umount,卷已經和對應worker node解除對映,且已經從檔案系統umount
-
detach,卷已經從worker node解除安裝
-
recycle,卷被回收
-
pv controller,負責建立和回收卷
-
attach detach controller,負責掛載和解除安裝卷
-
volume manager,負責mount和umount卷
for { desired := getDesiredState(); current := getCurrentState(); makeChanges(desired, current); }
結合以上三個維度,Kubernetes需要保證卷的管理功能分佈在不同控制器的前提下保證卷生命週期順序的正確性。以Pod使用卷為例,看Kubernetes是如何做到這一點?
| Pod啟動流程
此時pvc繫結pv。
2、attach detach controlle,如果pod分配到worker node,並且對應卷已經建立,則將卷掛載到對應worker node,並且給worker node資源增加volume已經掛載對應卷的狀態資訊,結合相關程式碼2[2]和程式碼3[3]。
此時對應node資源狀態中增加volume資訊。
[root@10-10-88-152 ~]# kubectl get nodes 10-10-88-113 -o yaml apiVersion: v1 kind: Node .... volumesAttached: - devicePath: csi-add9fc778d9593d01818d65ccde7013e87327d9f675b47df42a34b860c581711 name: kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-4faa18f5bbbd11e8-1365 - devicePath: csi-5dd249387138238e8e2209eb471450a072dd6543adde7a6769c8461943c789ca name: kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-4fa9b764bbbd11e8-1366 - devicePath: csi-bc9b81e32d84e8890d17568964c1e01af97b0c175e0b73d4bf30bba54e3f1a1e name: kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-4fa94533bbbd11e8-1364 volumesInUse: - kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-4fa94533bbbd11e8-1364 - kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-4fa9b764bbbd11e8-1366 - kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-4faa18f5bbbd11e8-1365
-
先掛載到node中全域性路徑,比如/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-3ecd68c7b7d211e8/globalmount。
-
對映到Pod對應路徑,比如/var/lib/kubelet/pods/49a5fede-b811-11e8-844f-fa7378845e00/volumes/kubernetes.io~csi/pvc-3ecd68c7b7d211e8/mount。
-
actualStateOfWorld中設定volume為掛載成功狀態。
4、pod controller確認卷已經對映成功,啟動Pod,此處不詳細展開。
| Pod被刪除的過程
將Pod從desiredStateOfWorld的快取資訊中清除。
-
actualStateOfWorld中已經掛載的卷和desiredStateOfWorld發現Pod不應該掛載,執行UmountVolume操作,將Pod和卷對映關係解除,並將Pod從actualStateOfWorld的卷資訊中剔除。
-
此時如果實際狀態中卷沒有關聯任何Pod,則說明卷需要可以完全與節點分離,則先執行UnmountDevice將卷的globalpath umount掉,等到下次reconcile時執行MarkVolumeAsDetached將卷完全從實際狀態中刪除掉。
不同元件通過資源狀態協作,attach detach controller需要PVC繫結PV的狀態,volume manager需要node status中volume attached狀態。
元件通過reconcile方式達到期望狀態,並且狀態可能需要多次reconcile中完成,如Pod清除掉後,volume最終和node分離。
|
問題
-
volume manager發現Pod被刪除,執行umount
-
StatefulSet發現Pod被刪除,馬上建立Pod
-
scheduler發現Pod進行排程
-
volume manager發現原有volume需要繫結Pod,執行mount
-
volume manager發現Pod被刪除,執行umount/unmountDevice/MarkVolumeAsDelete(通過幾次reconcile)
-
attach detach controller發現volume在node節點未被使用,執行detach
-
scheduler發現Pod進行排程
-
attach detach controller發現volume需要attach,執行attach
-
volume manager掛載
-
StatefulSet發現Pod被刪除,馬上建立Pod
-
volume manager發現Pod被刪除,執行umount/deviceUmount(通過幾次reconcile),注意此時devicePath和deviceMountPath都為空
-
scheduler發現Pod進行排程
-
volume manager發現原有volume需要繫結Pod,執行mount而此時devicePath和deviceMountPath都為空,問題出現
Sep
14
19
:
28
:
33
10
-10
-40
-16
kubelet: I0914
19
:
28
:
33.174310
1953
operation_generator.
go
:
1168
] Controller attach succeeded
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"49a5fede-b811-11e8-844f-fa7378845e00"
) device path:
"csi-eb93736e654600786d95eaffa7cd5d616f11a90bdc109e0df575e8646c250eb2"
Sep
14
19
:
28
:
33
10
-10
-40
-16
kubelet: I0914
19
:
28
:
33.273344
1953
operation_generator.
go
:
486
] MountVolume.WaitForAttach entering
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"49a5fede-b811-11e8-844f-fa7378845e00"
) DevicePath
"csi-eb93736e654600786d95eaffa7cd5d616f11a90bdc109e0df575e8646c250eb2"
Sep
14
19
:
28
:
33
10
-10
-40
-16
kubelet: I0914
19
:
28
:
33.318275
1953
operation_generator.
go
:
495
] MountVolume.WaitForAttach succeeded
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"49a5fede-b811-11e8-844f-fa7378845e00"
) DevicePath
"csi-eb93736e654600786d95eaffa7cd5d616f11a90bdc109e0df575e8646c250eb2"
Sep
14
19
:
28
:
33
10
-10
-40
-16
kubelet: I0914
19
:
28
:
33.319345
1953
operation_generator.
go
:
514
] MountVolume.MountDevice succeeded
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"49a5fede-b811-11e8-844f-fa7378845e00"
) device mount path
"/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-3ecd68c7b7d211e8/globalmount"
Sep
14
19
:
29
:
12
10
-10
-40
-16
kubelet: I0914
19
:
29
:
12.826916
1953
operation_generator.
go
:
486
] MountVolume.WaitForAttach entering
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"67f223dc-b811-11e8-844f-fa7378845e00"
) DevicePath
"csi-eb93736e654600786d95eaffa7cd5d616f11a90bdc109e0df575e8646c250eb2"
Sep
14
19
:
29
:
14
10
-10
-40
-16
kubelet: I0914
19
:
29
:
14.465225
1953
operation_generator.
go
:
495
] MountVolume.WaitForAttach succeeded
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"67f223dc-b811-11e8-844f-fa7378845e00"
) DevicePath
"csi-eb93736e654600786d95eaffa7cd5d616f11a90bdc109e0df575e8646c250eb2"
Sep
14
19
:
29
:
14
10
-10
-40
-16
kubelet: I0914
19
:
29
:
14.466483
1953
operation_generator.
go
:
514
] MountVolume.MountDevice succeeded
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"67f223dc-b811-11e8-844f-fa7378845e00"
) device mount path
"/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-3ecd68c7b7d211e8/globalmount"
Sep
14
19
:
29
:
15
10
-10
-40
-16
kubelet: W0914
19
:
29
:
15.491424
1953
csi_mounter.
go
:
354
] kubernetes.io/csi: skipping mount dir removal, path does not exist [/
var
/lib/kubelet/pods/
49
a5fede-b811
-11e8
-844f
-fa7378845e00/volumes/kubernetes.io~csi/pvc
-3
ecd68c7b7d211e8/mount]
Sep
14
19
:
29
:
15
10
-10
-40
-16
kubelet: I0914
19
:
29
:
15.491450
1953
operation_generator.
go
:
686
] UnmountVolume.TearDown succeeded
for
volume
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
(OuterVolumeSpecName:
"data"
) pod
"49a5fede-b811-11e8-844f-fa7378845e00"
(UID:
"49a5fede-b811-11e8-844f-fa7378845e00"
). InnerVolumeSpecName
"pvc-3ecd68c7b7d211e8"
. PluginName
"kubernetes.io/csi"
, VolumeGidValue
""
Sep
14
19
:
29
:
44
10
-10
-40
-16
kubelet: W0914
19
:
29
:
44.896387
1953
csi_mounter.
go
:
354
] kubernetes.io/csi: skipping mount dir removal, path does not exist [/
var
/lib/kubelet/pods/
67f
223dc-b811
-11e8
-844f
-fa7378845e00/volumes/kubernetes.io~csi/pvc
-3
ecd68c7b7d211e8/mount]
Sep
14
19
:
29
:
44
10
-10
-40
-16
kubelet: I0914
19
:
29
:
44.896403
1953
operation_generator.
go
:
686
] UnmountVolume.TearDown succeeded
for
volume
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
(OuterVolumeSpecName:
"data"
) pod
"67f223dc-b811-11e8-844f-fa7378845e00"
(UID:
"67f223dc-b811-11e8-844f-fa7378845e00"
). InnerVolumeSpecName
"pvc-3ecd68c7b7d211e8"
. PluginName
"kubernetes.io/csi"
, VolumeGidValue
""
Sep
14
19
:
29
:
44
10
-10
-40
-16
kubelet: I0914
19
:
29
:
44.917540
1953
reconciler.
go
:
278
] operationExecutor.UnmountDevice started
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) on node
"10-10-40-16"
Sep
14
19
:
29
:
44
10
-10
-40
-16
kubelet: W0914
19
:
29
:
44.919231
1953
mount_linux.
go
:
179
] could not determine device
for
path:
"/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-3ecd68c7b7d211e8/globalmount"
Sep
14
19
:
29
:
45
10
-10
-40
-16
kubelet: I0914
19
:
29
:
45.609605
1953
operation_generator.
go
:
760
] UnmountDevice succeeded
for
volume
"pvc-3ecd68c7b7d211e8"
%!(EXTRA
string
=UnmountDevice succeeded
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) on node
"10-10-40-16"
)
Sep
14
19
:
29
:
45
10
-10
-40
-16
kubelet: I0914
19
:
29
:
45.624963
1953
operation_generator.
go
:
486
] MountVolume.WaitForAttach entering
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"77b8caf7-b811-11e8-844f-fa7378845e00"
) DevicePath
""
Sep
14
19
:
29
:
46
10
-10
-40
-16
kubelet: E0914
19
:
29
:
46.006612
1953
nestedpendingoperations.
go
:
267
] Operation
for
"\"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338\""
failed. No retries permitted until
2018
-09
-14
19
:
29
:
46.506583596
+
0800
CST m=+
105572.978439381
(durationBeforeRetry
500
ms). Error:
"MountVolume.WaitForAttach failed for volume \"pvc-3ecd68c7b7d211e8\" (UniqueName: \"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338\") pod \"yoooo-416ea0-0\" (UID: \"77b8caf7-b811-11e8-844f-fa7378845e00\") : resource name may not be empty"
Sep
14
19
:
29
:
46
10
-10
-40
-16
kubelet: I0914
19
:
29
:
46.533962
1953
operation_generator.
go
:
486
] MountVolume.WaitForAttach entering
for
volume
"pvc-3ecd68c7b7d211e8"
(UniqueName:
"kubernetes.io/csi/csi-qcfsplugin^csi-qcfs-volume-3ecd68c7b7d211e8-338"
) pod
"yoooo-416ea0-0"
(UID:
"77b8caf7-b811-11e8-844f-fa7378845e00"
) DevicePath
""
Sep 14 19:29:14以及之前DevicePath非空
Sep 14 19:29:45以及之後DevicePath為空
Sep 14 19 :29 :14 …… MountVolume .MountDevice ……
Sep 14 19 :29 :15 ….. UnmountVolume .TearDown ……
Sep 14 19 :29 :44 …… UnmountVolume .TearDown ……
Sep 14 19 :29 :44 …… operationExecutor .UnmountDevice ……
Sep 14 19 :29 :44 …… could not determine device for path ….
UnmountDevice->GenerateUnmountDeviceFunc->actualStateOfWorld.MarkDeviceAsUnmounted->asw.SetVolumeGloballyMounted
asw.SetVolumeGloballyMounted(volumeName,
false
/* globallyMounted */
,
/* devicePath */
""
,
/* deviceMountPath */
""
)
|
總結
https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/controller/volume/persistentvolume/pv_controller.go#L301
https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/controller/volume/attachdetach/populator/desired_state_of_world_populator.go#L88
https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/controller/volume/attachdetach/reconciler/reconciler.go#L251
https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go#L152
https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/kubelet/volumemanager/reconciler/reconciler.go#L160
https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/kubelet/volumemanager/reconciler/reconciler.go#L238
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2217186/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- linux swap掛載失敗問題處理Linux
- 解決Nessus外掛更新失敗問題
- CentOS7.4中Docker以rw方式掛載volume報Permission denied問題CentOSDocker
- Mac openssl 未找到 / 載入失敗問題處理Mac
- api-server-pod-重啟失敗APIServer
- openwrt 撥號失敗問題
- Kubernetes利用Volume掛載ConfigMap與Secret
- git clone失敗問題解決Git
- 問題一:Kibaba 啟動失敗
- idea 使用日常問題 使用maven外掛 打包沒問題 但是使用 mvn命令打包失敗的問題解決IdeaMaven
- ubifs根檔案系統掛載失敗可能原因
- 最失敗的 JavaScript 面試問題JavaScript面試
- mongodb啟動失敗問題解決MongoDB
- Pyinstaller打包pikepdf失敗的問題排查
- hbase啟動失敗問題解決
- gitbook 入門教程之解決windows熱載入失敗問題GitWindows
- Android studio下載安裝後常見問題中的gradle下載失敗AndroidGradle
- Jenkins外掛安裝失敗Jenkins
- Composer doctrine/dbal 2.0 安裝失敗問題
- js登陸三次失敗問題JS
- gradle包下載失敗Gradle
- 如何對專案中的問題進行分析——FPGA失敗案例小結FPGA
- WebSocket的SSL認證失敗問題記錄Web
- 對於Spring中注入物件失敗的問題Spring物件
- STM32 IIC讀取Eeprom失敗問題
- 建站失敗的原因分析
- Unity之掛載小問題Unity
- Ubuntu中fcitx安裝失敗問題,及軟體換源問題Ubuntu
- 記一次Fresco載入圖片失敗的分析
- Gradio離線部署到內網,資源載入失敗問題(Gradio離線部署問題解決方法)內網
- Linux解決MySQL-python安裝失敗問題LinuxMySqlPython
- Debian 12 + KDE 螢幕共享失敗問題解決
- Kali Linux 2020.1a版本msfconsole啟動失敗問題Linux
- 記一次 Kafka 重啟失敗問題排查Kafka
- DB2資料庫連線失敗問題DB2資料庫
- 合約 USDT 轉賬失敗的問題解決
- 教你一招完美解決vscode安裝go外掛失敗問題 dlv: failed to install dlvVSCodeGoAI
- Android sdk 下載/更新失敗Android