k8s之PV、PVC、StorageClass詳解


導讀

上一篇寫了共享存儲的概述以及一個簡單的案例演示。這一篇就寫一下PV和PVC。

PV是對底層網絡共享存儲的抽象,將共享存儲定義為一種“資源”,比如Node也是容器應用可以消費的資源。PV由管理員創建和配置,與共享存儲的具體實現直接相關。

PVC則是用戶對存儲資源的一個“申請”,就像Pod消費Node資源一樣,PVC能夠消費PV資源。PVC可以申請特定的存儲空間和訪問模式。

StorageClass,用於標記存儲資源的特性和性能,管理員可以將存儲資源定義為某種類別,正如存儲設備對於自身的配置描述(Profile)。根據StorageClass的描述可以直觀的得知各種存儲資源的特性,就可以根據應用對存儲資源的需求去申請存儲資源了。存儲卷可以按需創建。

PV

PV作為存儲資源,主要包括存儲能力、訪問模式、存儲類型、回收策略、后端存儲類型等關鍵信息的設置。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity:  #容量
    storage: 5Gi
  accessModes:  #訪問模式
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle  #回收策略
  storageClassName: slow  
  nfs:
    path: /
    server: 172.17.0.2

  

kubernetes支持的PV類型如下:

◎ AWSElasticBlockStore:AWS公有雲提供的ElasticBlockStore。

◎ AzureFile:Azure公有雲提供的File。

◎ AzureDisk:Azure公有雲提供的Disk。

◎ CephFS:一種開源共享存儲系統。

◎ FC(Fibre Channel):光纖存儲設備。

◎ FlexVolume:一種插件式的存儲機制。

◎ Flocker:一種開源共享存儲系統。

◎ GCEPersistentDisk:GCE公有雲提供的PersistentDisk。

◎ Glusterfs:一種開源共享存儲系統。

◎ HostPath:宿主機目錄,僅用於單機測試。

◎ iSCSI:iSCSI存儲設備。

◎ Local:本地存儲設備,目前可以通過指定塊(Block)設備提供Local PV,或通過社區開發的sig-storage-local-static-provisioner插件( https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner )來管理Local PV的生命周期。

◎ NFS:網絡文件系統。

◎ Portworx Volumes:Portworx提供的存儲服務。

◎ Quobyte Volumes:Quobyte提供的存儲服務。

◎ RBD(Ceph Block Device):Ceph塊存儲。

◎ ScaleIO Volumes:DellEMC的存儲設備。

◎ StorageOS:StorageOS提供的存儲服務。

◎ VsphereVolume:VMWare提供的存儲系統。

關鍵配置參數

1、存儲能力(Capacity)

描述存儲設備具備的能力,支持對存儲空間的設置(storage=xx)

2、存儲卷模式(Volume Mode)

volumeMode=xx,可選項包括Filesystem(文件系統)和Block(塊設備),默認值是FileSystem。

目前有以下PV類型支持塊設備類型:

AWSElasticBlockStore、AzureDisk、FC、GCEPersistentDisk、iSCSI、Local volume、RBD(Ceph Block Device)、VsphereVolume(alpha)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  volumeMode: Block
  fc:
    targetWWNs: ["url"]
    lun: 0
    readOnly: false

  

3、訪問模式(Access Modes)

 

用於描述應用對存儲資源的訪問權限。

◎ ReadWriteOnce(RWO):讀寫權限,並且只能被單個Node掛載。

◎ ReadOnlyMany(ROX):只讀權限,允許被多個Node掛載。

◎ ReadWriteMany(RWX):讀寫權限,允許被多個Node掛載。

 

4、存儲類別(Class)

 

設定存儲的類別,通過storageClassName參數指定給一個StorageClass資源對象的名稱,具有特定類別的PV只能與請求了該類別的PVC進行綁定。未綁定類別的PV則只能與不請求任何類別的PVC進行綁定。

 

5、回收策略(Reclaim Policy)

 

通過persistentVolumeReclaimPolicy字段設置,

◎ Retain 保留:保留數據,需要手工處理。

◎ Recycle 回收空間:簡單清除文件的操作(例如執行rm -rf /thevolume/* 命令)。

◎ Delete 刪除:與PV相連的后端存儲完成Volume的刪除操作

EBS、GCE PD、Azure Disk、OpenStack Cinder等設備的內部Volume清理)。

 

6、掛載參數(Mount Options)

 

在將PV掛載到一個Node上時,根據后端存儲的特點,可能需要設置額外的掛載參數,可根據PV定義中的mountOptions字段進行設置。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  mountOptions:
  - hard
  - nolock
  - nfsvers=3
  gcePersistentDisk:
    fsType: ext4
    pdName: gce-disk-1

  

目前,以下PV類型支持設置掛載參數:

AWSElasticBlockStore、AzureDisk、AzureFile、CephFS、Cinder (OpenStack block storage)、GCEPersistentDisk、Glusterfs、NFS、Quobyte Volumes、RBD (Ceph Block Device)、StorageOS、VsphereVolume、iSCSI

 

7、節點親和性(Node Affinity)

 

限制只能通過某些Node來訪問Volume,可在nodeAffinity字段中設置。使用這些Volume的Pod將被調度到滿足條件的Node上。

此參數僅用於Local存儲卷上。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - my-node

  

PV生命周期的各個階段

◎ Available:可用狀態,還未與某個PVC綁定。

◎ Bound:已與某個PVC綁定。

◎ Released:綁定的PVC已經刪除,資源已釋放,但沒有被集群回收。

◎ Failed:自動資源回收失敗。

PVC

PVC作為用戶對存儲資源的需求申請,主要包括存儲空間請求、訪問模式、PV選擇條件和存儲類別等信息的設置。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
spec:
  accessModes:  #訪問模式
  - ReadWriteOnce
  resources: #申請資源,8Gi存儲空間
    requests:
      storage: 8Gi
  storageClassName: slow #存儲類別
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
    - {key: environment, operator: In, values: [dev]}

  

關鍵配置

1、資源請求(Resources)

描述對存儲資源的請求,目前僅支持request.storage的設置,即是存儲空間的大小

2、訪問模式(AccessModes)

用於描述對存儲資源的訪問權限,與PV設置相同

3、存儲卷模式(Volume Modes)

用於描述希望使用的PV存儲卷模式,包括文件系統和塊設備。

4、PV選擇條件(Selector)

通過對Label Selector的設置,可使PVC對於系統中已存在的各種PV進行篩選。

選擇條件可以使用matchLabels和matchExpressions進行設置,如果兩個字段都設置了,則Selector的邏輯將是兩組條件同時滿足才能完成匹配

5、存儲類別(Class)

PVC 在定義時可以設定需要的后端存儲的類別(通過storageClassName字段指定),以減少對后端存儲特性的詳細信息的依賴。只有設置了該Class的PV才能被系統選出,並與該PVC進行綁定

PVC也可以不設置Class需求。如果storageClassName字段的值被設置為空(storageClassName=""),則表示該PVC不要求特定的Class,系統將只選擇未設定Class的PV與之匹配和綁定。PVC也可以完全不設置storageClassName字段,此時將根據系統是否啟用了名為DefaultStorageClass的admission controller進行相應的操作

6、未啟用DefaultStorageClass

等效於PVC設置storageClassName的值為空(storageClassName=""),即只能選擇未設定Class的PV與之匹配和綁定。

7、啟用DefaultStorageClass

要求集群管理員已定義默認的StorageClass。如果在系統中不存在默認StorageClass,則等效於不啟用DefaultStorageClass的情況。如果存在默認的StorageClass,則系統將自動為PVC創建一個PV(使用默認StorageClass的后端存儲),並將它們進行綁定。集群管理員設置默認StorageClass的方法為,在StorageClass的定義中加上一個annotation“storageclass.kubernetes.io/is-default-class= true”。如果管理員將多個StorageClass都定義為default,則由於不唯一,系統將無法為PVC創建相應的PV。

PVC和PV都受限於Namespace,PVC在選擇PV時受到Namespace的限制,只有相同Namespace中的PV才可能與PVC綁定。Pod在引用PVC時同樣受Namespace的限制,只有相同Namespace中的PVC才能掛載到Pod內。

當Selector和Class都進行了設置時,系統將選擇兩個條件同時滿足的PV與之匹配。

另外,如果資源供應使用的是動態模式,即管理員沒有預先定義PV,僅通過StorageClass交給系統自動完成PV的動態創建,那么PVC再設定Selector時,系統將無法為其供應任何存儲資源。

在啟用動態供應模式的情況下,一旦用戶刪除了PVC,與之綁定的PV也將根據其默認的回收策略“Delete”被刪除。如果需要保留PV(用戶數據),則在動態綁定成功后,用戶需要將系統自動生成PV的回收策略從“Delete”改成“Retain”。

PV和PVC的生命周期

 

將PV看作可用的存儲資源,PVC則是對存儲資源的需求。

(1)資源供應

k8s支持兩種資源的供應模式:靜態模式(Static)和動態模式(Dynamic)。資源供應的結果就是創建好的PV。

靜態模式:集群管理員手工創建許多PV,在定義PV時需要將后端存儲的特性進行設置。

動態模式:集群管理員無需手工創建PV,而是通過StorageClass的設置對后端存儲進行描述,標記為某種類型。此時要求PVC對存儲的類型進行聲明,系統將自動完成PV的創建及與PVC的綁定。PVC可以聲明Class為"",說明該PVC禁止使用動態模式。

(2)資源綁定

在定義好PVC之后,系統將根據PVC對存儲資源的要求(存儲空間和訪問模式)在已存在的PV中選擇一個滿足PVC要求的PV,一旦找到,就將該PV與定義的PVC進行綁定,應用就可以使用這個PVC了。如果系統中沒有這個PV,則PVC則會一直處理Pending狀態,直到系統中有符合條件的PV。PV一旦綁定到PVC上,就會被PVC獨占,不能再與其他PVC進行綁定。當PVC申請的存儲空間比PV的少時,整個PV的空間就都能夠為PVC所用,可能會造成資源的浪費。如果資源供應使用的是動態模式,則系統在為PVC找到合適的StorageClass后,將自動創建一個PV並完成與PVC的綁定。

(3)資源使用

Pod使用Volume定義,將PVC掛載到容器內的某個路徑進行使用。Volume的類型為Persistent VolumeClaim,在容器掛載了一個PVC后,就能被持續獨占使用。多個Pod可以掛載到同一個PVC上。

volumes:
  - name: pv
    persistentVolumeClaim:
      claimName: pvc

  

(4)資源釋放

當存儲資源使用完畢后,可以刪除PVC,與該PVC綁定的PV會被標記為“已釋放”,但還不能立刻與其他PVC進行綁定。通過之前PVC寫入的數據可能還被保留在存儲設備上,只有在清除之后該PV才能被再次使用。

(5)資源回收

對於PV,管理員可以設定回收策略,用於設置與之綁定的PVC釋放資源之后如何處理遺留數據的問題。只有PV的存儲空間完成回收,才能供新的PVC綁定和使用。

通過兩張圖分別對在靜態資源供應模式和動態資源供應模式下,PV、PVC、StorageClass及Pod使用PVC的原理進行說明。

在靜態資源供應模式下,通過PV和PVC完成綁定,並供Pod使用的存儲管理機制

 

在動態資源供應模式下,通過StorageClass和PVC完成資源動態綁定(系統自動生成PV),並供Pod使用的存儲管理機制

 

StorageClass

StorageClass作為對存儲資源的抽象定義,對用戶設置的PVC申請屏蔽后端存儲的細節,一方面減少了用戶對存儲資源細節的關注,另一方面減少了管理員手工管理PV的工作,由系統自動完成PV的創建和綁定,實現了動態的資源供應。

StorageClass的定義主要包括名稱、后端存儲的提供者(privisioner)和后端存儲的相關參數配置。StorageClass一旦被創建,就無法修改,如需修改,只能刪除重建。

下例定義了一個名為standard的StorageClass,提供者為aws-ebs,其參數設置了一個type,值為gp2:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
privisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2

  

關鍵配置

1、提供者(Privisioner)

描述存儲資源的提供者,也可以看作后端存儲驅動。

2、參數(Parameters)

后端存儲資源提供者的參數設置,不同的Provisioner包括不同的參數設置。某些參數可以不顯示設定,Provisioner將使用其默認值。

設置默認的StorageClass

首先需要啟用名為DefaultStorageClass的admission controller,即在kube-apiserver的命令行參數--admission-control中增加

--admission-control=...,DefaultStorageClass

  

然后,在StorageClass的定義中設置一個annotation:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
  annotations:
    storageclass.beta.kubernetes.io/is-default-class="true"
privisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd

  

通過kubectl create命令創建成功后,查看StorageClass列表,可以看到名為gold的StorageClass被標記為default:

kubectl get sc

  

CSI存儲機制

Container Storage Interface(CSI)機制,用於在kubenetes和外部存儲系統之間建立一套標准的存儲管理接口,通過該接口為容器提供存儲服務。

CSI存儲插件的關鍵組件和部署架構

 

主要包括兩個組件:CSI Controller和CSI Node

1、CSI Controller

提供存儲服務視角對存儲資源和存儲進行管理和操作,在k8s中建議部署為單實例Pod,可以使用StatefulSet和Deployment控制器進行部署,設置副本數為1,保證為一種存儲插件只運行一個控制器實例。

在此Pod內部署兩個容器:

(1)與Master(kubernetes Controller Manager)通信的輔助sidecar容器,

在sidecar容器內又可以包含extenal-attacher和extenal-privisioner兩個容器,功能如下:

◎ external-attacher:監控VolumeAttachment資源對象的變更,觸發針對CSI端點的ControllerPublish和ControllerUnpublish操作。

◎ external-provisioner:監控PersistentVolumeClaim資源對象的變更,觸發針對CSI端點的CreateVolume和DeleteVolume操作

(2)CSI Driver存儲驅動容器,第三方提供,需實現上述接口

這兩個容器使用本地Socket(Unix Domain Socket,UDS),並使用gPRC協議進行通信,sidecar容器通過socket調用CSI Driver容器的CSI接口,CSI Driver容器負責具體的存儲卷操作。

2、CSI Node

對主機(Node)上的Volume進行管理和操作,建議使用DaemonSet,每個Node上都運行一個Pod。

在此Pod上部署如下兩個容器:

(1)與kubelet通信的輔助sidecar容器node-driver-register,主要功能是將存儲驅動注冊到kubelet中。

(2)CSI Driver存儲驅動容器,由第三方存儲提供商提供,主要功能是接收kubelet的調用,需要實現一系列與Node相關的CSI接口,例如NodePublishVolume接口(用於將Volume掛載到容器內的目標路徑)、NodeUnpublishVolume接口(用於從容器中卸載Volume),等等。

node-driver-register容器與kubelet通過Node主機的一個hostPath目錄下的unix Socket進行通信,CSI Driver容器與kubelet通過Node主機的另一個hostPath目錄下的unix Socket進行通信,同時需要將kubelet的工作目錄(/var/lib/kubelet)掛載到CSI Driver容器,用於為Pod進行Volume的管理操作(包括mount,unmount等)。

 

===============================

我是Liusy,一個喜歡健身的程序員。

獲取更多干貨以及最新消息,請關注公眾號:上古偽神

如果對您有幫助,點個關注就是對我最大的支持!!!


免責聲明!

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



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