到目前為止,我們討論過的所有持久volume類型都要求pod的開發人員了解叢集中可用的實際網路儲存的基礎架構。例如:要建立支援NFS協定的volume,開發人員必須知道NFS server所在的實際位置,這違背了k8s的基本理念,這理念宗旨在於向應用程式與開發人員隱藏實際的基礎設施,使他們不必擔心基礎設備的具體狀態,並使得app可以在大量雲端和地端之間進行服務搬遷。
理想的是,在k8s上部屬app的開發人員不需要知道底層用的是哪種類型的儲存技術,同理他們也不需要了解應該使用哪些類型的實體server來運行pod,與基礎設備相關的事務是叢集管理者獨有的控制領域。
當開發人員需要一定數量的持久化儲存給他們的app使用時,可以向k8s請求,就像在建立pod時可以請求CPU、記憶體跟其他資源一樣。系統管理者可以對叢集進行設定讓它可以為app提供所需的服務。
在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來使用
讓我們重建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
假設現在要部屬一個需要持久化儲存的pod,將要用到之前建立的PV,但是不能直接在pod內使用PV,需要先建立PVC。 聲明一個PV跟建立一個pod是相對獨立的過程,因為你希望透過相同的PVC保持可用,既使pod被重新調度(切記,重新調度意味著先前的pod被刪除了並且建立了一個新的)。