從底層儲存技術解耦pod

到目前為止,我們討論過的所有持久volume類型都要求pod的開發人員了解叢集中可用的實際網路儲存的基礎架構。例如:要建立支援NFS協定的volume,開發人員必須知道NFS server所在的實際位置,這違背了k8s的基本理念,這理念宗旨在於向應用程式與開發人員隱藏實際的基礎設施,使他們不必擔心基礎設備的具體狀態,並使得app可以在大量雲端和地端之間進行服務搬遷。

理想的是,在k8s上部屬app的開發人員不需要知道底層用的是哪種類型的儲存技術,同理他們也不需要了解應該使用哪些類型的實體server來運行pod,與基礎設備相關的事務是叢集管理者獨有的控制領域。

當開發人員需要一定數量的持久化儲存給他們的app使用時,可以向k8s請求,就像在建立pod時可以請求CPU、記憶體跟其他資源一樣。系統管理者可以對叢集進行設定讓它可以為app提供所需的服務。

介紹PV(PersistentVolume)跟PVC(PersistentVolumeClaim)

在k8s叢集中為了使app能夠正常請求儲存資源,同時避免處理基礎設備細節,引入了兩個新資源,分別是PV跟PVC。在pod中使用PV要比使用常規的pod volume複雜一些。 研發人員無須在他們的pod中加入特定技術的volume,而是由叢集管理者設定底層儲存,然後透過k8s API server建立PV並註冊。在建立PV時,管理者可以指定容量大小和支援的存取模式。 當叢集用戶需要在pod中使用持久化儲存時,他們首先建立PVC清單,指定所需要的最低容量要求和存取模式,然後用戶將PVC清單提交給k8s API server,k8s將找到可匹配條件的PV並將PV綁定到PVC。 PVC可以當作pod中的一個volume來使用,其他用戶不能使用同一個的PV,除非先通過刪除PVC綁定來將PV釋放。

圖6.6 持久volume由叢集管理者提供,並被pod透過PVC來使用

圖6.6 持久volume由叢集管理者提供,並被pod透過PVC來使用

建立PV

讓我們重建MongoDB範例,但跟之前操作不同的是,這次不會直接引用在pod中GCE Persistent Disk。相反的,你先擔任叢集管理者腳色,並建立一個使用GCE Persistent Disk的PV。然後,你將承擔開發人員的腳色,首先建立PVC,然後在pod中使用。

以下是建立支援GCE Persistent Disk的PV,mongodb-pv-gcepd.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongodb-pv
spec:
  capacity:         # 定義PV的大小
    storage: 1Gi
  accessModes:      # 定義PV的存取模式
    - ReadWriteOnce
    - ReadOnlyMany
  persistentVolumeReclaimPolicy: Retain    # 定義PV的回收策略,當PVC被釋放後PV將被保留(不清理也不刪除)
  gcePersistentDisk:                       # 這邊的設定跟之前差不多一樣
    pdName: mongodb
    fsType: ext4

如果使用NFS的話,可以建立NFS的PV,mongodb-pv-nfs.yaml,如下

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongodb-pv
spec:
  capacity:         # 定義PV的大小
    storage: 1Gi
  accessModes:      # 定義PV的存取模式
    - ReadWriteOnce
    - ReadOnlyMany
  persistentVolumeReclaimPolicy: Retain  # 定義PV的回收策略,當PVC被釋放後PV將被保留(不清理也不刪除)
  nfs:                                   # 這邊的設定跟之前差不多一樣
    server: 192.168.1.191    # nfs的ip
    path: /nfsshare          # nfs分享的路徑

在建立PV時,管理者需要告訴k8s其對應的容量需求,以及它是否可以由單個節點或者多個節點同時讀取或寫入。管理者還須要告訴k8s如何處理PV,當PV被釋放(當PVC的綁定被刪除時)。最後,無疑也很重要的是,管理者需要指定PV背後的實際儲存類型、位置、和其他屬性。

建立PV

[root@cp200 ch6]# kubectl create -f mongodb-pv-nfs.yaml 
persistentvolume/mongodb-pv created

查看PV

[root@cp200 ch6]# kubectl get pv
NAME         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mongodb-pv   1Gi        RWO,ROX        Retain           Available                                   17s
[root@cp200 ch6]# kubectl describe pv
Name:            mongodb-pv
Labels:          <none>
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    
Status:          Available
Claim:           
Reclaim Policy:  Retain
Access Modes:    RWO,ROX
VolumeMode:      Filesystem
Capacity:        1Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    192.168.1.191
    Path:      /nfsshare
    ReadOnly:  false
Events:        <none>

正如預料的那樣,PV顯示為可用,因為你還沒建立PVC來綁定

注意:PV不屬於任何名稱空間namespace,它跟節點一樣是叢集等級的資源

圖6.7 跟叢集節點一樣,PV不屬於任何一個namespace,區別於pod跟PVC

圖6.7 跟叢集節點一樣,PV不屬於任何一個namespace,區別於pod跟PVC

透過建立PVC來聲明PV

假設現在要部屬一個需要持久化儲存的pod,將要用到之前建立的PV,但是不能直接在pod內使用PV,需要先建立PVC。 聲明一個PV跟建立一個pod是相對獨立的過程,因為你希望透過相同的PVC保持可用,既使pod被重新調度(切記,重新調度意味著先前的pod被刪除了並且建立了一個新的)。