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

寶樹吶 發表於 2020-07-10

1. PersistentVolume(PV)簡介

1.1 為什麼需要Persistent Volume(PV)

在講PersistentVolume(PV)之前,我們需要先講一下Volume

Volume詳情可見上一章: kubernetes系列(十三) - 儲存之Volume

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物件包含儲存實現的細節,即NFSiSCSl或特定於雲供應商的儲存系統。

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!!

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


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 資源清單示例

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. 當前,只有NFSHostPath支援Recycle回收策略

最新版本中的Recycle已被廢棄,截圖如下

附:具體官網文件詳細說明連結點選此處

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

  1. AWS EBS、GCE PD、Azure Disk 和Cinder 卷支援Delete刪除策略

6. PersistentVolume(PV)的狀態

PV可以處於以下的某種狀態:

  • Available(可用): 塊空閒資源還沒有被任何宣告繫結
  • Bound(已繫結): 卷已經被宣告繫結, 注意:但是不一定不能繼續被繫結,看accessModes而定
  • Released(已釋放): 宣告被刪除,但是資源還未被叢集重新宣告
  • Failed(失敗): 該卷的自動回收失敗

命令列會顯示繫結到PV的PVC的名稱


7. 實驗-持久化演示說明-NFS

注:以下內容筆者沒有實際嘗試過,僅做記錄使用

7.1 安裝NFS伺服器

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 在其他節點上安裝客戶端

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

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

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域名不會有變化

  1. StatefulSet使用Headless服務來控制Pod的域名,這個域名的FQDN為:S(servicename).$(namespace).svc.cluster.local

其中,“cluster.local”指的是叢集的域名

  1. 根據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

  1. 刪除 Pod 不會刪除其pvc,手動刪除 pvc將自動釋放pv
  2. Statefulset的啟停順序:
    • 有序部署:部罷Statefulset時,如果有多個Pod副本,它們會被順序地建立(從0到N-1)並且,在下一個Pod執行之前所有之前的Pod必須都是Running和Ready狀態。
    • 有序刪除:當Pod被刪除時,它們被終止的順序是從N-1到0。
    • 有序擴充套件:當對Pod執行擴充套件操作時,與部署一樣,它前面的Pod必須都處於Running和Ready狀態。
  3. Statefulset使用場景:
    • 穩定的持久化儲存,即Pod重新排程後還是能訪問到相同的持久化資料,基於PVC 來實現。
    • 穩定的網路識別符號,即Pod 重新排程後其iPodName 和 HostName不變。
    • 有序部署,有序擴充套件,基於init containers 來實現。
    • 有序收縮。