kubernetes系列(十四) – 存儲之PersistentVolume
- 2020 年 7 月 10 日
- 筆記
- Kubernetes
- 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 來實現。
- 有序收縮。