[Kubernetes]PV,PVC,StorageClass之間的關系詳解


在Kubernetes中,容器化一個應用比較麻煩的地方莫過於對其"狀態"的管理,而最常見的"狀態",莫過於存儲狀態.
[Kubernetes]深入理解StatefulSet這篇文章中,稍微提了一下PV(Persistent Volume)和PVC(Persistent Volume Claim),這篇文章詳細說一說.

大概了解

我先大體說一下整個過程,有一個小小的認識,然后我再詳細展開說.
用戶提交請求創建Pod時,Kubernetes發現這個Pod聲明使用了PVC,這時就需要PersistentVolumeController幫它找一個PV來進行配對.如果有的話呢,就直接進行綁定.但是如果沒有呢?就去找對應的StorageClass,幫它新創建一個PV,然后再和PVC進行綁定.但是請注意,此時新創建的PV,只是一個API對象,還需要經過"兩階段"處理變成宿主機上的"持久化Volume"才算是真正有用.這個時候,Pod就可以正常啟動,並將相關文檔掛載到容器內指定的路徑.
我知道你對上面的過程肯定有些懵了,別急,咱們慢慢把這個過程剖析一下.

持久化Volume

比較難理解的應該就是需要經過"兩階段"處理變成宿主機上的"持久化Volume"這部分內容了.
所謂"持久化Volume",指的就是這個宿主機上的目錄,具備"持久性",也就是說:這個目錄里面的內容,既不會因為容器的刪除而被清理掉,也不會和當前的宿主機進行綁定.這樣,當容器被重啟或者在其他節點上重建出來之后,仍然能夠通過掛載這個Volume來訪問到目錄里面的內容.
這里面主要有兩個關鍵點:一,不會因為容器的刪除而清理掉里面的內容,二,不會和當前的宿主機進行綁定.Kubernetes需要做的工作就是達到這兩個目的,從而使得目錄具備"持久性".

Kubernetes在這個准備"持久化"宿主機目錄的過程中,我們可以形象的稱為"兩階段處理":
第一階段:為虛擬機掛載磁盤,把這個階段稱為"Attach".
第二階段:掛載磁盤之后,如果想要使用,還需要將掛載的磁盤進行格式化處理,並掛載到Volume宿主機目錄上,這個階段稱為"Mount",而這個掛載點,正是Volume的宿主機目錄.所以,Mount階段的操作,可以這樣來表示:

# 通過 lsblk 命令獲取磁盤設備 ID
$ sudo lsblk
# 格式化成 ext4 格式
$ sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/< 磁盤設備 ID>
# 掛載到掛載點
$ sudo mkdir -p /var/lib/kubelet/pods/<Pod 的 ID>/volumes/kubernetes.io~<Volume 類型 >/<Volume 名字 >
#如果kubelet需要作為client,將遠端NFS服務器的目錄掛載到Volume的宿主機目錄上,則需要執行以下命令:
$ mount -t nfs <NFS 服務器地址 >:/ /var/lib/kubelet/pods/<Pod 的 ID>/volumes/kubernetes.io~<Volume 類型 >/<Volume 名字 > 

以上兩個階段完成之后,我們在這個目錄里寫入的所有文件,就都會被保存起來,從而實現了對這個Volume宿主機目錄的"持久化".(如果給虛擬機擴充過磁盤的話,對這一部分內容應該是比較容易理解的)
但是對於Kubernetes來說,它是如何定義和區分這兩個階段的呢?
其實很簡單,在具體的Volume插件的實現接口上,Kubernetes分別給這兩個階段提供了兩種不同的參數列表:

  • 對於"Attach":Kubernetes提供的可用參數是nodeName,即宿主機名字.
  • 對於"Mount",Kubernetes提供的可用參數是dir,即Volume的宿主機目錄.
  • 所以,在具體使用時,只需要根據自己的需求進行選擇和實現就可以達到目的了. 這就是Kubernetes的Volume處理機制的相關說明了. 接下來說說另外一個重要的概念:StorageClass
    StorageClass

    PV這個對象的創建,是由運維人員來完成的,但是在大規模的生產環境中,這其實是一個非常麻煩的操作.因為在一個大規模的Kubernetes集群里,可能有成千上萬個PVC,這就意味着運維人員必須實現創建出這個多個PV,此外,隨着項目的需要,會有新的PVC不斷被提交,那么運維人員就需要不斷的添加新的,滿足要求的PV,否則新的Pod就會因為PVC綁定不到PV而導致創建失敗.這在自動化中,肯定是不能被允許的.
    所以,Kubernetes提供了一套可以自動創建PV的機制,即:Dynamic Provisioning.而這個機制的核心在於:StorageClass這個API對象.

  • StorageClass對象會定義下面兩部分內容:
    • 1,PV的屬性.比如,存儲類型,Volume的大小等.
    • 2,創建這種PV需要用到的存儲插件
  • 有了這兩個信息之后,Kubernetes就能夠根據用戶提交的PVC,找到一個對應的StorageClass,之后Kubernetes就會調用該StorageClass聲明的存儲插件,進而創建出需要的PV.
    但是其實使用起來是一件很簡單的事情,你只需要根據自己的需求,編寫YAML文件即可,然后使用kubectl create命令執行即可.

    最后小結

    到這里,講的就差不多了.
    綜上所述呢,PVC描述的是Pod想要使用的持久化存儲的屬性,比如存儲的大小,讀寫權限等.而PV則是一個具體的Volume屬性,比如Volume的類型,掛載目錄等.而StorageClass的作用,則是充當PV的模板,從而可以動態創建需要的PV.
    最后,放一張圖片,描述一下概念之間的關系:
    在這里插入圖片描述

    些許的碎碎念

    最后的最后,寫點兒碎碎念.如果看的進去的話,就看看,看不進去,就算了.
    今天早上打開手機,收到了一條消息:
    在這里插入圖片描述
    在上面介紹StorageClass的時候,我說了,如果想要使用的話,其實是一件很簡單的事情,只需要寫一下YAML文件即可.但是背后的原理如果不去深究,不去學習的話,遇到問題的時候,還是無從下手的.
    還記得當時倒騰k8s,一個月的時間就倒騰的差不多了,項目上線的時候,也是有驚無險的撐了下來.所以呢,如果只是達到會用的層次的話,一個月的時間就差不多了.
    但是如果想要有所提高,想要在遇到問題時,能夠准確定位,還是需要再回來補充理論.
    做技術,前期的實踐固然是不可少,但是后期的理論也要做.絕對不能僅僅停留在會用的層次上面,如果有時間,有精力,最好還是能夠再深入理解一下背后的原理知識.
    這也是我一直堅持的學習方法:基於實踐,補充理論.

    以上內容來自我學習<深入剖析Kubernetes>專欄文章之后的一些見解,有偏頗之處,還望指出.
    感謝您的閱讀~


    免責聲明!

    本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



     
    粵ICP備18138465號   © 2018-2025 CODEPRJ.COM