1. 程式人生 > >kubernetes系列(十四) - 儲存之PersistentVolume

kubernetes系列(十四) - 儲存之PersistentVolume

- [1. PersistentVolume(PV)簡介](#head1) - [1.1 為什麼需要Persistent Volume(PV)](#head2) - [1.2 PersistentVolume(PV)和Volume的區別](#head3) - [1.3 PV和PVC更具體的概念和關係](#head4) - [1.3.1 PersistentVolume(PV)](#head5) - [1.3.2 PersistentVolumeClaim(PVC)](#head6) - [1.3.3 PV和PVC的關係和圖解](#head7) - [2. PersistentVolume(PV)的分類](#head8) - [2.1 靜態PV](#head9) - [2.2 動態PV](#head10) - [3. PersistentVolumeClaim(PVC)的保護](#head11) - [4. PersistentVolume(PV)支援的底層儲存型別](#head12) - [5. PersistentVolume(PV)的資源清單](#head13) - [5.1 資源清單示例](#head14) - [5.2 PV的訪問模式(spec.accessModes)](#head15) - [5.2.1 三種訪問模式](#head16) - [5.2.2 各種底層儲存具體支援的訪問模式](#head17) - [5.3 PV的回收策略(spec.persistentVolumeReclaimPolicy)](#head18) - [5.3.1 回收策略的三種策略](#head19) - [5.3.2 回收策略注意事項](#head20) - [6. PersistentVolume(PV)的狀態](#head21) - [7. 實驗-持久化演示說明-NFS](#head22) - [7.1 安裝NFS伺服器](#head23) - [7.2 在其他節點上安裝客戶端](#head24) - [7.3 部署PV](#head25) - [7.4 建立服務並使用PVC](#head26) - [8. 關於 Statefulset](#head27) ## 1. PersistentVolume(PV)簡介 ### 1.1 為什麼需要Persistent Volume(PV) 在講`PersistentVolume(PV)`之前,我們需要先講一下`Volume` > Volume詳情可見上一章: [kubernetes系列(十三) - 儲存之Volume ](https://www.cnblogs.com/baoshu/p/13269288.html) `Volume`是被定義在pod上的(`emptyDir或者hostPath`),屬於`計算資源`的一部分。所以`Volume`是有侷限性的,因為在實際的運用過程中,我們通常會先定義一個**網路儲存**,然後從中劃出一個網盤並掛接到虛擬機器上。 為了遮蔽底層儲存實現的細節,讓使用者方便使用,同時讓管理員方便管理。==Kubernetes從V1.0版本就引入了`PersistentVolume(PV)`和與之相關聯的`PersistentVolumeClaim(PVC)`兩個**資源物件**來實現對儲存的管理== ---- ### 1.2 PersistentVolume(PV)和Volume的區別 `PV`可以被理解成`kubernetes`叢集中的某個網路儲存對應的一塊儲存,它`與Volume`類似,但是有如下的區別: 1. **PV只能是網路儲存**,不屬於任何`Node`,但是可以在每個`Node`上訪問 2. PV不是被定義在pod上,而是獨立在pod之外被定義的。 - 意味著`pod`被刪除了,`PV`仍然存在,這點與`Volume`不同 ---- ### 1.3 PV和PVC更具體的概念和關係 #### 1.3.1 PersistentVolume(PV) `PersistentVolume(PV)`是由管理員設定的儲存,它是群集的一部分。就像節點是叢集中的資源一樣,PV也是叢集中的資源。PV是Volume之類的卷外掛,但具有獨立於使用PV的Pod的生命週期。此API物件包含儲存實現的細節,即`NFS`、`iSCSl`或特定於雲供應商的儲存系統。 #### 1.3.2 PersistentVolumeClaim(PVC) `PersistentVolumeClaim(PVC)`是使用者儲存的請求。它與Pod相似。Pod消耗節點資源,==`PVC`消耗`PV`資源==。Pod可以請求特定級別的資源(CPU和記憶體)。宣告可以請求特定的大小和訪問模式(例如,可以以讀/寫一次或只讀多次模式掛載) #### 1.3.3 PV和PVC的關係和圖解 `pvc`是一種`pv`的請求方案,PVC定義我當前需要什麼樣型別的PV,然後會自動在**當前存在的pv**中選取一個匹配度最高的pv ==一個`PVC`只能繫結一個`PV`!!== ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1ggm72dfyfij30rd0gdgoj.jpg) ---- ## 2. PersistentVolume(PV)的分類 ### 2.1 靜態PV **簡單來說** 由叢集管理員手動建立的一些PV **完整的概念** 叢集管理員建立一些PV。它們帶有可供群集使用者使用的實際儲存的細節。它們存在於KubernetesAPl中,可用於消費。 ---- ### 2.2 動態PV **簡單來說** 配置了允許動態PV的策略後,如果當前存在的PV無法滿足PVC的要求,則會動態建立PV. > 動態PV瞭解即可 **完整的概念** 當管理員建立的**靜態PV都不匹配使用者的`PersistentVolumeClaim`時**,叢集可能會嘗試動態地為PVC建立卷。此配置基於`StorageClasses`,所以要啟用基於儲存級別的動態儲存配置要求: - PVC必須請求`StorageClasses` - 管理員必須建立並配置`StorageClasses`才能進行動態建立 - 宣告該類為“”可以有效地禁用其動態配置 - 叢集管理員需要啟用`API server`上的`DefaultStorageClass`[准入控制器]。例如,通過確保`DefaultStorageClass`位於`API server` 元件的`--admission-control`標誌,使用逗號分隔的有序值列表中,可以完成此操作 ---- ## 3. PersistentVolumeClaim(PVC)的保護 PVC保護的目的是**確保由pod正在使用的PVC不會從系統中移除**,因為如果被移除的話可能會導致資料丟失 當啟用PVC保護alpha功能時,如果使用者刪除了一個pod正在使用的PVC,則該PVC不會被立即刪除。PVC的刪除將被推遲,直到PVC不再被任何 pod使用 ---- ## 4. PersistentVolume(PV)支援的底層儲存型別 `PersistentVolume`型別以外掛形式實現. `kubernetes`目前支援以下型別(排名不分先後): > 跟上一集中的volume支援的型別差不多 - `GCEPersistentDisk` `AWSElasticBlockStore` `AzureFile` `AzureDisk` `FC(Fibre Channel)` - `FlexVolume` `Flocker` `NFS` `iSCSI` `RBD(Ceph Block Device)` `CephFS` - `Cinder(OpenStack block storage)` `Glusterfs` `VsphereVolume` `Quobyte` `Volumes` - `HostPath` `VMware` `Photon` `Portworx Volumes` `Scalelo Volumes` `StorageOS` ---- ## 5. PersistentVolume(PV)的資源清單 ### 5.1 資源清單示例 ```yaml apiVersion: v1 kind: PersistentVolume metadata: name:pve003 spec: capacity: # 卷的大小為5G storage: 5Gi # 儲存卷的型別為:檔案系統 volumeMode: Filesystem # 訪問策略:該卷可以被單個節點以讀/寫模式掛載 accessModes: - ReadNriteOnce # 回收策略:回收 persistentVolumeReclaimPolicy: Recycle # 對應的具體底層儲存的分級 # 比如有些固態或者其他儲存型別比較快,就可以定義為strong storageClassName: slow # (可選的)掛載選項 mountOptions: - hard - nfsvers=4.1 # 具體對應的真實底層儲存型別為nfs # 掛載到172伺服器下的/tmp目錄 nfs: path: /tmp server: 172.17.0.2 ``` ---- ### 5.2 PV的訪問模式(spec.accessModes) #### 5.2.1 三種訪問模式 訪問模式`accessModes`一共有三種: - `ReadWriteOnce`: 該卷可以被單個節點以讀/寫模式掛載 - `ReadOnlyMany`: 該卷可以被多個節點以只讀模式掛載 - `ReadWriteMany`: 該卷可以被多個節點以讀/寫模式掛載 在命令列cli中,三種訪問模式可以簡寫為: - `RWO` - `ReadWriteOnce` - `ROX` - `ReadOnlyMany` - `RWX` - `ReadWriteMany` **但不是所有的型別的底層儲存都支援以上三種,每種底層儲存型別支援的都不一樣!!** #### 5.2.2 各種底層儲存具體支援的訪問模式
Volume Plugin ReadWriteOnce ReadOnlyMany ReadWriteMany
AWSElasticBlockStore - -
AzureFile
AzureDisk - -
CephFS
Cinder - -
FC -
FlexVolume -
Flocker - -
GCEPersistentDisk -
Glusterfs
HostPath - -
iSCSI -
PhotonPersistentDisk - -
Quobyte
NFS
RBD -
VsphereVolume - -
PortworxVolume -
ScaleIO -
---- ### 5.3 PV的回收策略(spec.persistentVolumeReclaimPolicy) #### 5.3.1 回收策略的三種策略 - `Retain`(保留): pv被刪除後會保留記憶體,手動回收 - `Recycle`(回收): 刪除卷下的所有內容(`rm-rf /thevolume/*`) - `Delete`(刪除): 關聯的儲存資產(例如AWS EBS、GCE PD、Azure Disk 和OpenStack Cinder卷)將被刪除。即直接把卷給刪除了 #### 5.3.2 回收策略注意事項 1. 當前,只有`NFS`和`HostPath`支援`Recycle`回收策略 >
最新版本中的`Recycle`已被廢棄,截圖如下
> 附:具體官網文件詳細說明連結[點選此處](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#reclaiming) ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1ggm90dmqdrj30uy0aljsu.jpg) 2. AWS EBS、GCE PD、Azure Disk 和Cinder 卷支援`Delete`刪除策略 ---- ## 6. PersistentVolume(PV)的狀態 PV可以處於以下的某種狀態: - `Available`(可用): 塊空閒資源還沒有被任何宣告繫結 - `Bound`(已繫結): 卷已經被宣告繫結, 注意:但是不一定不能繼續被繫結,看`accessModes`而定 - `Released`(已釋放): 宣告被刪除,但是資源還未被叢集重新宣告 - `Failed`(失敗): 該卷的自動回收失敗 命令列會顯示繫結到PV的PVC的名稱 ---- ## 7. 實驗-持久化演示說明-NFS > 注:以下內容筆者沒有實際嘗試過,僅做記錄使用 ### 7.1 安裝NFS伺服器 ```shell yum install -y nfs-common nfs-utils rpcbind mkdir /nfsdata chmod 777 /nfsdata chown nfsnobody /nfsdata cat /etc/exports /nfsdata *(rw,no_root_squash,no_all_squash,sync) systemctl start rpcbind systemctl start nfs ``` ### 7.2 在其他節點上安裝客戶端 ```shell yum -y install nfs-utils rpcbind mkdir /test showmount -e 192.168.66.100 mount -t nfs 192.168.66.100:/nfsdata /test/ cd /test/ ls umount /test/ ``` ### 7.3 部署PV ```yaml apiVersion: v1 kind: PersistentVolume metadata: name: nfspv1 spec: capacity: storage: 10Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: nfs nfs: path: /nfsdata server: 192.168.66.100 ``` ### 7.4 建立服務並使用PVC ```yaml apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: selector: matchLabels: app: nginx serviceName: "nginx" replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: k8s.gcr.io/nginx-slim:0.8 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "nfs" resources: requests: storage: 1Gi ``` ## 8. 關於 Statefulset 1. `StatefulSet`為每個Pod副本建立了一個`DNS域`名,這個域名的格式為:`S(podname).(headless servername)` > 也就意味著服務間是通過Pod域名來通訊而非PodIP,因為當Pod所在Node發生故障時,Pod會被飄移到其它 Node上,PodIP會發生變化,但是Pod域名不會有變化 2. `StatefulSet`使用`Headless服務`來控制Pod的域名,這個域名的FQDN為:`S(servicename).$(namespace).svc.cluster.local` > 其中,“cluster.local”指的是叢集的域名 3. 根據`volumeClaimTemplates`,為每個Pod 建立一個pvo,pvc的命名規則匹配模式: `(volumeClaimTemplates.name)-(pod_name)` > 比如上面的 `volumeMounts.name=www,Podname-web-[0-2]`,因此創建出來的PVC是 `www-web-0、www-web-1、 www-web-2` 4. 刪除 Pod 不會刪除其pvc,手動刪除 pvc將自動釋放pv 5. Statefulset的啟停順序: - 有序部署:部罷Statefulset時,如果有多個Pod副本,它們會被順序地建立(從0到N-1)並且,在下一個Pod執行之前所有之前的Pod必須都是Running和Ready狀態。 - 有序刪除:當Pod被刪除時,它們被終止的順序是從N-1到0。 - 有序擴充套件:當對Pod執行擴充套件操作時,與部署一樣,它前面的Pod必須都處於Running和Ready狀態。 6. Statefulset使用場景: - 穩定的持久化儲存,即Pod重新排程後還是能訪問到相同的持久化資料,基於PVC 來實現。 - 穩定的網路識別符號,即Pod 重新排程後其iPodName 和 HostName不變。 - 有序部署,有序擴充套件,基於init containers 來實現。 - 有序收縮。