kubernetes系列(十四) - 儲存之PersistentVolume
- 1. PersistentVolume(PV)簡介
- 2. PersistentVolume(PV)的分類
- 3. PersistentVolumeClaim(PVC)的保護
- 4. PersistentVolume(PV)支援的底層儲存型別
- 5. PersistentVolume(PV)的資源清單
- 6. PersistentVolume(PV)的狀態
- 7. 實驗-持久化演示說明-NFS
- 8. 關於 Statefulset
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
類似,但是有如下的區別:
- PV只能是網路儲存,不屬於任何
Node
,但是可以在每個Node
上訪問 - 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
!!
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 回收策略注意事項
- 當前,只有
NFS
和HostPath
支援Recycle
回收策略
最新版本中的
Recycle
已被廢棄,截圖如下
附:具體官網檔案詳細說明連結點選此處
- 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
StatefulSet
為每個Pod副本建立了一個DNS域
名,這個域名的格式為:S(podname).(headless servername)
也就意味著服務間是通過Pod域名來通訊而非PodIP,因為當Pod所在Node發生故障時,Pod會被飄移到其它 Node上,PodIP會發生變化,但是Pod域名不會有變化
StatefulSet
使用Headless服務
來控制Pod的域名,這個域名的FQDN為:S(servicename).$(namespace).svc.cluster.local
其中,“cluster.local”指的是叢集的域名
- 根據
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
- 刪除 Pod 不會刪除其pvc,手動刪除 pvc將自動釋放pv
- Statefulset的啟停順序:
- 有序部署:部罷Statefulset時,如果有多個Pod副本,它們會被順序地建立(從0到N-1)並且,在下一個Pod執行之前所有之前的Pod必須都是Running和Ready狀態。
- 有序刪除:當Pod被刪除時,它們被終止的順序是從N-1到0。
- 有序擴充套件:當對Pod執行擴充套件操作時,與部署一樣,它前面的Pod必須都處於Running和Ready狀態。
- Statefulset使用場景:
- 穩定的持久化儲存,即Pod重新排程後還是能訪問到相同的持久化資料,基於PVC 來實現。
- 穩定的網路識別符號,即Pod 重新排程後其iPodName 和 HostName不變。
- 有序部署,有序擴充套件,基於init containers 來實現。
- 有序收縮。