上一篇寫了共享存儲的概述以及一個簡單的案例演示。這一篇就寫一下PV和PVC。node
PV是對底層網絡共享存儲的抽象,將共享存儲定義爲一種「資源」,好比Node也是容器應用能夠消費的資源。PV由管理員建立和配置,與共享存儲的具體實現直接相關。git
PVC則是用戶對存儲資源的一個「申請」,就像Pod消費Node資源同樣,PVC可以消費PV資源。PVC能夠申請特定的存儲空間和訪問模式。程序員
StorageClass,用於標記存儲資源的特性和性能,管理員能夠將存儲資源定義爲某種類別,正如存儲設備對於自身的配置描述(Profile)。根據StorageClass的描述能夠直觀的得知各類存儲資源的特性,就能夠根據應用對存儲資源的需求去申請存儲資源了。存儲卷能夠按需建立。github
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
◎ Available:可用狀態,還未與某個PVC綁定。
◎ Bound:已與某個PVC綁定。
◎ Released:綁定的PVC已經刪除,資源已釋放,但沒有被集羣回收。
◎ Failed:自動資源回收失敗。
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則是對存儲資源的需求。
(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做爲對存儲資源的抽象定義,對用戶設置的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
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,一個喜歡健身的程序員。
獲取更多幹貨以及最新消息,請關注公衆號:上古僞神
若是對您有幫助,點個關注就是對我最大的支持!!!