k8s之PV、PVC、StorageClass詳解

導讀

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

PV是對底層網絡共享存儲的抽象,將共享存儲定義爲一種「資源」,好比Node也是容器應用能夠消費的資源。PV由管理員建立和配置,與共享存儲的具體實現直接相關。git

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

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

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類型以下:api

◎ AWSElasticBlockStore:AWS公有云提供的ElasticBlockStore。bash

◎ AzureFile:Azure公有云提供的File。網絡

◎ AzureDisk:Azure公有云提供的Disk。架構

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

◎ 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提供的存儲系統。

關鍵配置參數

一、存儲能力(Capacity)

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

二、存儲卷模式(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

  

三、訪問模式(Access Modes)

 

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

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

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

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

 

四、存儲類別(Class)

 

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

 

五、回收策略(Reclaim Policy)

 

經過persistentVolumeReclaimPolicy字段設置,

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

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

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

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

 

六、掛載參數(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

 

七、節點親和性(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]}

  

關鍵配置

一、資源請求(Resources)

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

二、訪問模式(AccessModes)

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

三、存儲卷模式(Volume Modes)

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

四、PV選擇條件(Selector)

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

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

五、存儲類別(Class)

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

PVC也能夠不設置Class需求。若是storageClassName字段的值被設置爲空(storageClassName=""),則表示該PVC不要求特定的Class,系統將只選擇未設定Class的PV與之匹配和綁定。PVC也能夠徹底不設置storageClassName字段,此時將根據系統是否啓用了名爲DefaultStorageClass的admission controller進行相應的操做

六、未啓用DefaultStorageClass

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

七、啓用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

  

關鍵配置

一、提供者(Privisioner)

描述存儲資源的提供者,也能夠看做後端存儲驅動。

二、參數(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

一、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容器負責具體的存儲卷操做。

二、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,一個喜歡健身的程序員。

獲取更多幹貨以及最新消息,請關注公衆號:上古僞神

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

相關文章
相關標籤/搜索