Pod掛載LocalStoragePv過程理解


 1處的控制循環Control Loop應該是:VolumeManagerReconciler

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Local Persistent Volume: 利用pv&pvc這種松耦合機制來實現直接使用宿主機上的本地磁盤目錄,而不依賴於遠程存儲服務,來提供“持久化”的容器 Volume

設計lpv過程需要考慮的兩個問題:

1. 如何把本地磁盤抽象成 PV(一個 PV 一塊盤):pv對應的目錄所掛載的磁盤不應該是宿主機根目錄使用的硬盤,因為一旦pv不使用獨立的磁盤,將會變成完全不可控,比如磁盤很容易被其他進程應用寫滿,甚至造成整個宿主機宕機。而且同一個磁盤的不同的目錄之間也缺乏最基礎的 I/O 隔離機制.

2.  Pod 能被正確地調度到lpv 對應節點上(延遲綁定):常規的pv記錄的是與節點無關的遠程共享存儲,而lpv則與某些節點關聯在一起.

考慮這樣的場景:

假設我的集群中有3個節點,分別是node1、node2、node3,其中node1和node2具有diskType=ssd的標簽,且node1和node2已經使用獨立的磁盤掛載到/mnt/disks/volA目錄,node3使用獨立的磁盤掛載到/mnt/disks/volB目錄

假設我的集群已經創建好了兩個pv,分別是pvA和pvB

pvA.yaml如下。字段nodeAffinity表明想要使用這個pv的pod只能被調度到帶diskType=ssd標簽的節點上,也就是node1、node2

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pvA
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  local: #local字段表明這是一個Local Persistent Volume的pv
    path: /mnt/disks/volA
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: diskType
          operator: In
          values:
          - ssd

 pvB.yaml如下。字段nodeAffinity表明想要使用這個pv的pod只能被調度到帶node3

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pvB
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  local: local字段表明這是一個Local Persistent Volume的pv
    path: /mnt/disks/volB
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node3

 

pvc.yaml文件如下

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: example-local-claim
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: local-storage

 

創建一個pod聲明使用example-local-claim這個pvc,如果按照常規pv的處理模式來說,當pvc一旦創建,就會被volumeController的PersistentVolumeController控制循環檢測到,並嘗試尋找合適的pv進行綁定。Kubernetes將先調度 Pod 到某個節點上,然后,根據pv上定義的信息,通過“兩階段處理”來“持久化”這台機器上的 Volume 目錄,進而完成 Volume 目錄與容器的綁定掛載(將一個目錄掛載到掛載點目錄,而不是將一個設備掛載到掛載點目錄)。在lpv上就不能通過這種方式處理了,因為如果pvc一經創建就選擇一個pv綁定,在上面的例子中,如果pvc和pvB綁定,那么使用這個pvc的pod也就被限制在node3節點,如果pod這邊又通過NodeAffinity節點親和性或nodeSelector強制pod調度到節點node2,此時就會出現沖突,這個pod也就會一直pending了。

k8s的lpv是通過pvc和pv的延遲綁定來解決這個沖突的:創建一個storageClass,配置volumeBindingMode為WaitForFirstConsumer,且在pvA和pvB中聲明使用這個storageClass

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

 WaitForFirstConsumer表示第一個使用這個pvc的pod在調度過程中才決策合適的pv進行綁定。這樣一來,k8s就可以綜合考慮pod對Node的要求和pv對Node的要求,最終pvc選擇和pvA進行綁定。

參考資料:

當前k8s支持的存儲插件:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes


免責聲明!

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



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