应用存储和持久化数据卷:核心知识
本次課程的分享主要圍繞以下三個部分:
Volumes 介紹
Pod Volumes
首先來看一下 Pod Volumes 的使用場景:
- 場景一:如果 pod 中的某一個容器在運行時異常退出,被 kubelet 重新拉起之后,如何保證之前容器產生的重要數(shù)據(jù)沒有丟失?
- 場景二:如果同一個 pod 中的多個容器想要共享數(shù)據(jù),應該如何去做?
以上兩個場景,其實都可以借助 Volumes 來很好地解決,接下來首先看一下 Pod Volumes 的常見類型:
Persistent Volumes
接下來看一下 PV(Persistent Volumes)。既然已經(jīng)有了 Pod Volumes,為什么又要引入 PV 呢?我們知道 pod 中聲明的 volume 生命周期與 pod 是相同的,以下有幾種常見的場景:
- 場景一:pod 重建銷毀,如用 Deployment 管理的 pod,在做鏡像升級的過程中,會產生新的 pod并且刪除舊的 pod ,那新舊 pod 之間如何復用數(shù)據(jù)?
- 場景二:宿主機宕機的時候,要把上面的 pod 遷移,這個時候 StatefulSet 管理的 pod,其實已經(jīng)實現(xiàn)了帶卷遷移的語義。這時通過 Pod Volumes 顯然是做不到的;
- 場景三:多個 pod 之間,如果想要共享數(shù)據(jù),應該如何去聲明呢?我們知道,同一個 pod 中多個容器想共享數(shù)據(jù),可以借助 Pod Volumes 來解決;當多個 pod 想共享數(shù)據(jù)時,Pod Volumes 就很難去表達這種語義;
- 場景四:如果要想對數(shù)據(jù)卷做一些功能擴展性,如:snapshot、resize 這些功能,又應該如何去做呢?
以上場景中,通過 Pod Volumes 很難準確地表達它的復用/共享語義,對它的擴展也比較困難。因此 K8s 中又引入了 **Persistent Volumes **概念,它可以將存儲和計算分離,通過不同的組件來管理存儲資源和計算資源,然后解耦 pod 和 Volume 之間生命周期的關聯(lián)。這樣,當把 pod 刪除之后,它使用的PV仍然存在,還可以被新建的 pod 復用。
PVC 設計意圖
了解 PV 后,應該如何使用它呢?
用戶在使用 PV 時其實是通過 PVC,為什么有了 PV 又設計了 PVC 呢?主要原因是為了簡化K8s用戶對存儲的使用方式,做到職責分離。通常用戶在使用存儲的時候,只用聲明所需的存儲大小以及訪問模式。
訪問模式是什么?其實就是:我要使用的存儲是可以被多個node共享還是只能單node獨占訪問(注意是node level而不是pod level)?只讀還是讀寫訪問?用戶只用關心這些東西,與存儲相關的實現(xiàn)細節(jié)是不需要關心的。
通過 PVC 和 PV 的概念,將用戶需求和實現(xiàn)細節(jié)解耦開,用戶只用通過 PVC 聲明自己的存儲需求。PV是有集群管理員和存儲相關團隊來統(tǒng)一運維和管控,這樣的話,就簡化了用戶使用存儲的方式。可以看到,PV 和 PVC 的設計其實有點像面向對象的接口與實現(xiàn)的關系。用戶在使用功能時,只需關心用戶接口,不需關心它內部復雜的實現(xiàn)細節(jié)。
既然 PV 是由集群管理員統(tǒng)一管控的,接下來就看一下 PV 這個對象是怎么產生的。
Static Volume Provisioning
第一種產生方式:靜態(tài)產生方式 - 靜態(tài) Provisioning。
靜態(tài) Provisioning:由集群管理員事先去規(guī)劃這個集群中的用戶會怎樣使用存儲,它會先預分配一些存儲,也就是預先創(chuàng)建一些 PV;然后用戶在提交自己的存儲需求(也就是 PVC)的時候,K8s 內部相關組件會幫助它把 PVC 和 PV 做綁定;之后用戶再通過 pod 去使用存儲的時候,就可以通過 PVC 找到相應的 PV,它就可以使用了。
靜態(tài)產生方式有什么不足呢?可以看到,首先需要集群管理員預分配,預分配其實是很難預測用戶真實需求的。舉一個最簡單的例子:如果用戶需要的是 20G,然而集群管理員在分配的時候可能有 80G 、100G 的,但沒有 20G 的,這樣就很難滿足用戶的真實需求,也會造成資源浪費。有沒有更好的方式呢?
Dynamic Volume Provisioning
第二種訪問方式:動態(tài) Dynamic Provisioning。
動態(tài)供給是什么意思呢?就是說現(xiàn)在集群管理員不預分配 PV,他寫了一個模板文件,這個模板文件是用來表示創(chuàng)建某一類型存儲(塊存儲,文件存儲等)所需的一些參數(shù),這些參數(shù)是用戶不關心的,給存儲本身實現(xiàn)有關的參數(shù)。用戶只需要提交自身的存儲需求,也就是PVC文件,并在 PVC 中指定使用的存儲模板(StorageClass)。
K8s 集群中的管控組件,會結合 PVC 和 StorageClass 的信息動態(tài),生成用戶所需要的存儲(PV),將 PVC 和 PV 進行綁定后,pod 就可以使用 PV 了。通過 StorageClass 配置生成存儲所需要的存儲模板,再結合用戶的需求動態(tài)創(chuàng)建 PV 對象,做到按需分配,在沒有增加用戶使用難度的同時也解放了集群管理員的運維工作。
用例解讀
接下來看一下 Pod Volumes、PV、PVC 及 StorageClass 具體是如何使用的。
Pod Volumes 的使用
首先來看一下 Pod Volumes 的使用。如上圖左側所示,我們可以在 pod yaml 文件中的 Volumes 字段中,聲明我們卷的名字以及卷的類型。聲明的兩個卷,一個是用的是 emptyDir,另外一個用的是 hostPath,這兩種都是本地卷。在容器中應該怎么去使用這個卷呢?它其實可以通過 volumeMounts 這個字段,volumeMounts 字段里面指定的 name 其實就是它使用的哪個卷,mountPath 就是容器中的掛載路徑。
這里還有個 subPath,subPath 是什么?
先看一下,這兩個容器都指定使用了同一個卷,就是這個 cache-volume。那么,在多個容器共享同一個卷的時候,為了隔離數(shù)據(jù),我們可以通過 subPath 來完成這個操作。它會在卷里面建立兩個子目錄,然后容器 1 往 cache 下面寫的數(shù)據(jù)其實都寫在子目錄 cache1 了,容器 2 往 cache 寫的目錄,其數(shù)據(jù)最終會落在這個卷里子目錄下面的 cache2 下。
還有一個 readOnly 字段,readOnly 的意思其實就是只讀掛載,這個掛載你往掛載點下面實際上是沒有辦法去寫數(shù)據(jù)的。
另外emptyDir、hostPath 都是本地存儲,它們之間有什么細微的差別呢?emptyDir 其實是在 pod 創(chuàng)建的過程中會臨時創(chuàng)建的一個目錄,這個目錄隨著 pod 刪除也會被刪除,里面的數(shù)據(jù)會被清空掉;hostPath 顧名思義,其實就是宿主機上的一個路徑,在 pod 刪除之后,這個目錄還是存在的,它的數(shù)據(jù)也不會被丟失。這就是它們兩者之間一個細微的差別。
靜態(tài) PV 使用
接下來再看一下,PV 和 PVC 是怎么使用的。
先看一個靜態(tài) PV 創(chuàng)建方式。靜態(tài) PV 的話,首先是由管理員來創(chuàng)建的,管理員我們這里以 NAS,就是阿里云文件存儲為例。我需要先在阿里云的文件存儲控制臺上去創(chuàng)建 NAS 存儲,然后把 NAS 存儲的相關信息要填到 PV 對象中,這個 PV 對象預創(chuàng)建出來后,用戶可以通過 PVC 來聲明自己的存儲需求,然后再去創(chuàng)建 pod。創(chuàng)建 pod 還是通過我們剛才講解的字段把存儲掛載到某一個容器中的某一個掛載點下面。
那么接下來看一下 yaml 怎么寫。集群管理員首先是在云存儲廠商那邊先去把存儲創(chuàng)建出來,然后把相應的信息填寫到 PV 對象中。
剛剛創(chuàng)建的阿里云 NAS 文件存儲對應的PV,有個比較重要的字段:capacity,即創(chuàng)建的這個存儲的大小,accessModes,創(chuàng)建出來的這個存儲它的訪問方式,我們后面會講解總共有幾種訪問方式。
然后有個 ReclaimPolicy,ReclaimPolicy 的意思就是:這塊存儲在被使用后,等它的使用方 pod 以及 PVC 被刪除之后,這個 PV 是應該被刪掉還是被保留呢?其實就是PV的回收策略。
接下來看看用戶怎么去使用該PV對象。用戶在使用存儲的時候,需要先創(chuàng)建一個 PVC 對象。PVC 對象里面,只需要指定存儲需求,不用關心存儲本身的具體實現(xiàn)細節(jié)。存儲需求包括哪些呢?首先是需要的大小,也就是 resources.requests.storage;然后是它的訪問方式,即需要這個存儲的訪問方式,這里聲明為ReadWriteMany,也即支持多node讀寫訪問,這也是文件存儲的典型特性。
上圖中左側,可以看到這個聲明:它的 size 和它的access mode,跟我們剛才靜態(tài)創(chuàng)建這塊 PV 其實是匹配的。這樣的話,當用戶在提交 PVC 的時候,K8s 集群相關的組件就會把 PV 的 PVC bound 到一起。之后,用戶在提交 pod yaml 的時候,可以在卷里面寫上 PVC聲明,在 PVC聲明里面可以通過 claimName 來聲明要用哪個 PVC。這時,掛載方式其實跟前面講的一樣,當提交完 yaml 的時候,它可以通過 PVC 找到 bound 著的那個 PV,然后就可以用那塊存儲了。這是靜態(tài) Provisioning到被pod使用的一個過程。
動態(tài) PV 使用
然后再看一下動態(tài) Provisioning。動態(tài) Provisioning 上面提到過,系統(tǒng)管理員不再預分配 PV,而只是創(chuàng)建一個模板文件。
這個模板文件叫 StorageClass,在StorageClass里面,我們需要填的重要信息:第一個是 provisioner,provisioner 是什么?它其實就是說我當時創(chuàng)建 PV 和對應的存儲的時候,應該用哪個存儲插件來去創(chuàng)建。
這些參數(shù)是通過k8s創(chuàng)建存儲的時候,需要指定的一些細節(jié)參數(shù)。對于這些參數(shù),用戶是不需要關心的,像這里 regionld、zoneld、fsType 和它的類型。ReclaimPolicy跟我們剛才講解的 PV 里的意思是一樣的,就是說動態(tài)創(chuàng)建出來的這塊 PV,當使用方使用結束、Pod 及 PVC 被刪除后,這塊 PV 應該怎么處理,我們這個地方寫的是 delete,意思就是說當使用方 pod 和 PVC 被刪除之后,這個 PV 也會被刪除掉。
接下來看一下,集群管理員提交完 StorageClass,也就是提交創(chuàng)建 PV 的模板之后,用戶怎么用,首先還是需要寫一個 PVC 的文件。
PVC 的文件里存儲的大小、訪問模式是不變的。現(xiàn)在需要新加一個字段,叫 StorageClassName,它的意思是指定動態(tài)創(chuàng)建PV的模板文件的名字,這里StorageClassName填的就是上面聲明的csi-disk。
在提交完 PVC之后,K8s 集群中的相關組件就會根據(jù) PVC 以及對應的 StorageClass 動態(tài)生成這塊 PV 給這個 PVC 做一個綁定,之后用戶在提交自己的 yaml 時,用法和接下來的流程和前面的靜態(tài)使用方式是一樣的,通過 PVC 找到我們動態(tài)創(chuàng)建的 PV,然后把它掛載到相應的容器中就可以使用了。
PV Spec 重要字段解析
接下來,我們講解一下 PV 的一些重要字段:
- Capacity:這個很好理解,就是存儲對象的大小;
- AccessModes:也是用戶需要關心的,就是說我使用這個 PV 的方式。它有三種使用方式。
- 一種是單 node 讀寫訪問;
- 第二種是多個 node 只讀訪問,是常見的一種數(shù)據(jù)的共享方式;
- 第三種是多個 node 上讀寫訪問。
用戶在提交 PVC 的時候,最重要的兩個字段 —— Capacity 和 AccessModes。在提交 PVC后,k8s集群中的相關組件是如何去找到合適的PV呢?首先它是通過為PV建立的AccessModes索引找到所有能夠滿足用戶的 PVC 里面的 AccessModes 要求的PV list,然后根據(jù)PVC的 Capacity,StorageClassName, Label Selector 進一步篩選PV,如果滿足條件的PV有多個,選擇PV的size最小的,accessmodes列表最短的PV,也即最小適合原則。
- ReclaimPolicy:這個就是剛才提到的,我的用戶方 PV 的 PVC 在刪除之后,我的 PV 應該做如何處理?常見的有三種方式。
- 第一種方式我們就不說了,現(xiàn)在 K8s 中已經(jīng)不推薦使用了;
- 第二種方式 delete,也就是說 PVC 被刪除之后,PV 也會被刪除;
- 第三種方式 Retain,就是保留,保留之后,后面這個 PV 需要管理員來手動處理。
- StorageClassName:StorageClassName 這個我們剛才說了,我們動態(tài) Provisioning 時必須指定的一個字段,就是說我們要指定到底用哪一個模板文件來生成 PV ;
- NodeAffinity:就是說我創(chuàng)建出來的 PV,它能被哪些 node 去掛載使用,其實是有限制的。然后通過 NodeAffinity 來聲明對node的限制,這樣其實對 使用該PV的pod調度也有限制,就是說 pod 必須要調度到這些能訪問 PV 的 node 上,才能使用這塊 PV,這個字段在我們下一講講解存儲拓撲調度時在細說。
PV 狀態(tài)流轉
接下來我們看一下 PV 的狀態(tài)流轉。首先在創(chuàng)建 PV 對象后,它會處在短暫的pending 狀態(tài);等真正的 PV 創(chuàng)建好之后,它就處在 available 狀態(tài)。
available 狀態(tài)意思就是可以使用的狀態(tài),用戶在提交 PVC 之后,被 K8s 相關組件做完 bound(即:找到相應的 PV),這個時候 PV 和 PVC 就結合到一起了,此時兩者都處在 bound 狀態(tài)。當用戶在使用完 PVC,將其刪除后,這個 PV 就處在 released 狀態(tài),之后它應該被刪除還是被保留呢?這個就會依賴我們剛才說的 ReclaimPolicy。
這里有一個點需要特別說明一下:當 PV 已經(jīng)處在 released 狀態(tài)下,它是沒有辦法直接回到 available 狀態(tài),也就是說接下來無法被一個新的 PVC 去做綁定。如果我們想把已經(jīng) released 的 PV 復用,我們這個時候通常應該怎么去做呢?
第一種方式:我們可以新建一個 PV 對象,然后把之前的 released 的 PV 的相關字段的信息填到新的 PV 對象里面,這樣的話,這個 PV 就可以結合新的 PVC 了;第二種是我們在刪除 pod 之后,不要去刪除 PVC 對象,這樣給 PV 綁定的 PVC 還是存在的,下次 pod 使用的時候,就可以直接通過 PVC 去復用。K8s中的StatefulSet管理的Pod帶存儲的遷移就是通過這種方式。
操作演示
接下來,我會在實際的環(huán)境中給大家演示一下,靜態(tài) Provisioning 以及動態(tài) Provisioning 具體操作方式。
靜態(tài) Provisioning 例子
靜態(tài) Provisioning 主要用的是阿里云的 NAS 文件存儲;動態(tài) Provisioning 主要用了阿里云的云盤。它們需要相應存儲插件,插件我已經(jīng)提前部署在我的 K8s 集群中了(csi-nasplugin是為了在 k8s 中使用阿里云 NAS 所需的插件,csi-disk是為了在 k8s 中使用阿里云云盤所需要的插件)。
我們接下來先看一下靜態(tài) Provisioning 的 PV 的 yaml 文件。
volumeAttributes是我在阿里云nas控制臺預先創(chuàng)建的 NAS 文件系統(tǒng)的相關信息,我們主要需要關心的有 capacity 為5Gi; accessModes 為多node讀寫訪問; reclaimPolicy:Retain,也就是當我使用方的 PVC 被刪除之后,我這個 PV 是要保留下來的;以及在使用這個卷的過程中使用的driver。
然后我們把對應的 PV 創(chuàng)建出來:
我們看一下上圖 PV 的狀態(tài),已經(jīng)處在 Available,也就是說它已經(jīng)可以被使用了。
再創(chuàng)建出來 nas-pvc:
我們看這個時候 PVC 已經(jīng)新創(chuàng)建出來了,而且也已經(jīng)和我們上面創(chuàng)建的PV綁定到一起了。我們看一下 PVC 的 yaml 里面寫的什么。
其實很簡單 ,就是我需要的大小以及我需要的 accessModes。提交完之后,它就與我們集群中已經(jīng)存在的 PV 做匹配,匹配成功之后,它就會做 bound。
接下來我們去創(chuàng)建使用 nas-fs 的 pod:
上圖看到,這兩個 Pod 都已經(jīng)處在 running 狀態(tài)了。
我們先看一下這個 pod yaml:
pod yaml 里面聲明了剛才我們創(chuàng)建出來的PVC對象,然后把它掛載到nas-container容器中的 /data 下面。我們這個 pod 是通過前面課程中講解 deployment 創(chuàng)建兩個副本,通過反親和性,將兩個副本調度在不同的 node 上面。
上圖我們可以看一下,兩個Pod所在的宿主機是不一樣的。
如下圖所示:我們登陸到第一個上面,findmnt 看一下它的掛載信息,這個其實就掛載在我聲明的 nas-fs 上,那我們再在下面 touch 個 test.test.test 文件,我們也會登陸到另外一個容器看一下,它有沒有被共享。
我們退出再登陸另外一個 pod(剛才登陸的是第一個,現(xiàn)在登陸第二個)。
如下圖所示:我們也 findmnt 一下,可以看到,這兩個 pod 的遠程掛載路徑一樣,也就是說我們用的是同一個 NAS PV,我們再看一下剛才創(chuàng)建出來的那個是否存在。
可以看到,這個也是存在的,就說明這兩個運行在不同node上的 pod 共享了同一個 nas 存儲。
接下來我們看一下把兩個 pod 刪掉之后的情況。先刪Pod,接著再刪一下對應的 PVC(K8s內部對pvc對象由保護機制,在刪除pvc對象時如果發(fā)現(xiàn)有pod在使用pvc,pvc是刪除不掉的),這個可能要稍等一下。
看一下下圖對應的 PVC 是不是已經(jīng)被刪掉了。
上圖顯示,它已經(jīng)被刪掉了。再看一下,剛才的 nas PV 還是在的,它的狀態(tài)是處在 Released 狀態(tài),也就是說剛才使用它的 PVC 已經(jīng)被刪掉了,然后它被 released 了。又因為我們 RECLAIN POLICY 是 Retain,所以它這個 PV 是被保留下來的。
動態(tài) Provisioning 例子
接下來我們來看第二個例子,動態(tài) Provisioning 的例子。我們先把保留下來的 PV 手動刪掉,可以看到集群中沒有 PV了。接下來演示一下動態(tài) Provisioning。
首先,先去創(chuàng)建一個生成 PV 的模板文件,也就是 storageclass。看一下 storageclass 里面的內容,其實很簡單。
如上圖所示,我事先指定的是我要創(chuàng)建存儲的卷插件(阿里云云盤插件,由阿里云團隊開發(fā)),這個我們已經(jīng)提前部署好了;我們可以看到,parameters部分是創(chuàng)建存儲所需要的一些參數(shù),但是用戶不需要關心這些信息;然后是 reclaimPolicy,也就是說通過這個 storageclass 創(chuàng)建出來的 PV 在給綁定到一起的 PVC 刪除之后,它是要保留還是要刪除。
如上圖所示:現(xiàn)在這個集群中是沒有 PV 的,我們動態(tài)提交一個 PVC 文件,先看一下它的 PVC 文件。它的 accessModes-ReadWriteOnce(因為阿里云云盤其實只能是單node讀寫的,所以我們聲明這樣的方式),它的存儲大小需求是 30G,它的 storageClassName 是 csi-disk,就是我們剛才創(chuàng)建的 storageclass,也就是說它指定要通過這個模板去生成 PV。
這個 PVC 此時正處在 pending 狀態(tài),這就說明它對應的 PV 還在創(chuàng)建過程中。
稍過一會,我們看到已經(jīng)有一個新的 PV 生成,這個 PV 其實就是根據(jù)我們提交的 PVC 以及 PVC 里面指定的storageclass 動態(tài)生成的。之后k8s會將生成的 PV 以及我們提交的 PVC,就是這個 disk PVC 做綁定,之后我們就可以通過創(chuàng)建 pod 來使用了。
再看一下 pod yaml:
pod yaml 很簡單,也是通過 PVC 聲明,表明使用這個 PVC。然后是掛載點,下面我們可以創(chuàng)建看一下。
如下圖所示:我們可以大概看一下 Events,首先被調度器調度,調度完之后,接下來會有個 attachdetach controller,它會去做 disk的attach操作,就是把我們對應的 PV 掛載到調度器調度的 node 上,然后Pod對應的容器才能啟動,啟動容器才能使用對應的盤。
接下來我會把 PVC 刪掉,看一下PV 會不會根據(jù)我們的 reclaimPolicy 隨之刪掉呢?我們先看一下,這個時候 PVC 還是存在的,對應的 PV 也是存在的。
然后刪一下 PVC,刪完之后再看一下:我們的 PV 也被刪了,也就是說根據(jù) reclaimPolicy,我們在刪除 PVC 的同時,PV 也會被刪除掉。
我們的演示部分就到這里了。
架構設計
PV 和 PVC 的處理流程
我們接下來看一下 K8s 中的 PV 和 PVC 體系的完整處理流程。我首先看一下這張圖的右下部分里面提到的 csi。
csi 是什么?csi 的全稱是 container storage interface,它是K8s社區(qū)后面對存儲插件實現(xiàn)(out of tree)的官方推薦方式。csi 的實現(xiàn)大體可以分為兩部分:
- 第一部分是由k8s社區(qū)驅動實現(xiàn)的通用的部分,像我們這張圖中的 csi-provisioner和 csi-attacher controller;
- 另外一種是由云存儲廠商實踐的,對接云存儲廠商的 OpenApi,主要是實現(xiàn)真正的 create/delete/mount/unmount 存儲的相關操作,對應到上圖中的csi-controller-server和csi-node-server。
接下來看一下,當用戶提交 yaml 之后,k8s內部的處理流程。用戶在提交 PVCyaml 的時候,首先會在集群中生成一個 PVC 對象,然后 PVC 對象會被 csi-provisioner controller watch到,csi-provisioner 會結合 PVC 對象以及 PVC 對象中聲明的 storageClass,通過 GRPC 調用 csi-controller-server,然后,到云存儲服務這邊去創(chuàng)建真正的存儲,并最終創(chuàng)建出來 PV 對象。最后,由集群中的 PV controller 將 PVC 和 PV 對象做 bound 之后,這個 PV 就可以被使用了。
用戶在提交 pod 之后,首先會被調度器調度選中某一個合適的node,之后該 node 上面的 kubelet 在創(chuàng)建 pod 流程中會通過首先 csi-node-server 將我們之前創(chuàng)建的 PV 掛載到我們 pod 可以使用的路徑,然后kubelet開始 create && start pod中的所有container。
PV、PVC 以及通過 csi 使用存儲流程
我們接下來通過另一張圖來更加詳細看一下我們 PV、PVC 以及通過 CSI 使用存儲的完整流程。
主要分為三個階段:
- 第一個階段(Create階段)是用戶提交完 PVC,由 csi-provisioner 創(chuàng)建存儲,并生成 PV 對象,之后 PV controller 將 PVC 及生成的 PV 對象做 bound,bound 之后,create 階段就完成了;
- 之后用戶在提交 pod yaml 的時候,首先會被調度選中某一個 合適的node,等 pod 的運行 node 被選出來之后,會被 AD Controller watch 到 pod 選中的 node,它會去查找 pod 中使用了哪些 PV。然后它會生成一個內部的對象叫 VolumeAttachment 對象,從而去觸發(fā) csi-attacher去調用csi-controller-server 去做真正的 attache 操作,attach操作調到云存儲廠商OpenAPI。這個 attach 操作就是將存儲 attach到 pod 將會運行的 node 上面。第二個階段 —— attach階段完成;
- 然后我們接下來看第三個階段。第三個階段 發(fā)生在kubelet 創(chuàng)建 pod的過程中,它在創(chuàng)建 pod 的過程中,首先要去做一個 mount,這里的 mount 操作是為了將已經(jīng)attach到這個 node 上面那塊盤,進一步 mount 到 pod 可以使用的一個具體路徑,之后 kubelet 才開始創(chuàng)建并啟動容器。這就是 PV 加 PVC 創(chuàng)建存儲以及使用存儲的第三個階段 —— mount 階段。
總的來說,有三個階段:第一個 create 階段,主要是創(chuàng)建存儲;第二個 attach 階段,就是將那塊存儲掛載到 node 上面(通常為將存儲load到node的/dev下面);第三個 mount 階段,將對應的存儲進一步掛載到 pod 可以使用的路徑。這就是我們的 PVC、PV、已經(jīng)通過CSI實現(xiàn)的卷從創(chuàng)建到使用的完整流程。
結束語
我們今天的內容大概就到這里,下一節(jié)我將為大家來分享 Volume Snapshot 以及 Volume Topology-aware Scheduling 相關的知識以及具體處理流程,謝謝大家~
本節(jié)總結(需補充)
本節(jié)課的主要內容就到此為止了,這里為大家簡單總結一下。
- K8s Volume是用戶Pod保存業(yè)務數(shù)據(jù)的重要接口和手段
- PVC和PV體系增強了K8s Volumes在多Pod共享/遷移/存儲擴展等場景下的能力
- PV(存儲)的不同供給模式(static and dynamic)可以通過多種方式為集群中的Pod供給所需的存儲
總結
以上是生活随笔為你收集整理的应用存储和持久化数据卷:核心知识的全部內容,希望文章能夠幫你解決所遇到的問題。