轉載自 https://blog.csdn.net/dkfajsldfsdfsd/article/details/81319735
ConfigMap、Secret、emptyDir、hostPath等屬於臨時性存儲,當pod被調度到某個節點上時,它們隨pod的創建而創建,臨時占用節點存儲資源,當pod離開節點時,存儲資源被交還給節點,pod一旦離開它們就失效,不具備持久化存儲數據的能力。與此相反,持久化存儲擁有獨立的生命周期,具備持久化存儲能力,其后端一般是獨立的存儲系統如NFS、iSCSI、cephfs、glusterfs等。
PV與PVC
Kubernetes中的node代表計算資源,而PersistentVolume(PV)則代表存儲資源,它是對各種諸如NFS、iSCSI、雲存儲等各種存儲后端所提供存儲塊的統一抽象,通過它屏蔽低層實現細節。與普通volume不同,PV擁有完全獨立的生命周期。
因為PV表示的是集群能力,它是一種集群資源,所以用戶不能直接使用PV,就像不能直接使用內存一樣,需要先向系統申請。Kubernetes通過PersistentVolumeClaim(PVC)代理用戶行為,用戶通過對PVC的操作實現對PV申請、使用、釋放等操作,PVC是用戶層面的資源。
靜態PV與動態PV
靜態PV由系統管理員負責創建、提供、維護,系統管理員為用戶屏蔽真正提供存儲的后端及其實現細節,普通用戶作為消費者,只需通過PVC申請、使用此類資源。
當用戶通過PVC申請PV時,如果系統無法從靜態PV為用戶分配資源,則嘗試創建動態PV。前提條件是用戶需要在PVC中給出“storage class”名稱,指示系統創建動態PV的具體方式。“storage class”可以理解成某種具體的后端存儲,它也是Kubernetes集群中的一種資源,當然在使用之前,需要先由集群管理員負責創建、配置。如果用戶的PVC中“storage class”的值為"",則表示不能為此PVC動態創建PV。
想要開啟基於“storage class”的動態存儲供應功能,需要為apiServer啟用"DefaultStorageClass"入口控制器,具體方法為在apiServer選項--enable-admission-plugins中包含"DefaultStorageClass"字符串。
PV與PVC綁定
用戶創建包含容量、訪問模式等信息的PVC,向系統請求存儲資源。系統查找已存在PV或者監控新創建PV,如果與PVC匹配則將兩者綁定。如果PVC創建動態PV,則系統將一直將兩者綁定。PV與PVC的綁定是一一對應關系,不能重復綁定與被綁定。如果系統一直沒有為PVC找到匹配PV,則PVC無限期維持在"unbound"狀態,直到系統找到匹配PV。實際綁定的PV容量可能大於PVC中申請的容量。
在POD中使用PVC
當系統為用戶創建的PVC綁定PV后,表明用戶成功申請了存儲資源。用戶在pod中定義PVC類型的volume,當創建POD實例時系統將與PVC綁定的PV掛載到POD實例。如果PV支持多種訪問模式,用戶需要pod的PVC volume中指定期望的類型。注意,pod與PVC必需位於相同namespace之下。
存儲對象使用中保護
如果啟用了存儲對象使用中保護特性,則不允許將正在被pod使用的活動PVC或者綁定到PVC的PV從系統中移除,防止數據丟失。活動PVC指使用PVC的pod處於pending狀態並且已經被指派節點或者處於running狀態。
如果已經啟用存儲對象使用中保護特性,且用戶刪除正在被pod使用的活動PVC,不會立即刪除PVC,而是延后到其狀態變成非活動。同樣如果用戶刪除已經綁定的PV,則刪除動作延后到PV解除綁定后。
當PVC處於保護中時,其狀態為"Terminating"並且其"Finalizers"包含"kubernetes.io/pvc-protection":
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
...
正處在保護中的PV,其狀態為"Terminating"且"Finalizers"包含"kubernetes.io/pv-protection":
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Available
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
Reclaiming
用戶刪除PVC釋放對PV的占用后,系統根據PV的"reclaim policy"決定對PV執行何種回收操作。 目前,"reclaim policy"有三種方式:Retained、Recycled、Deleted。
Retained
保護被PVC釋放的PV及其上數據,並將PV狀態改成"released",不將被其它PVC綁定。集群管理員手動通過如下步驟釋放存儲資源:
- 手動刪除PV,但與其相關的后端存儲資源如(AWS EBS, GCE PD, Azure Disk, or Cinder volume)仍然存在。
- 手動清空后端存儲volume上的數據。
- 手動刪除后端存儲volume,或者重復使用后端volume,為其創建新的PV。
Delete
刪除被PVC釋放的PV及其后端存儲volume。對於動態PV其"reclaim policy"繼承自其"storage class",默認是Delete。集群管理員負責將"storage class"的"reclaim policy"設置成用戶期望的形式,否則需要用戶手動為創建后的動態PV編輯"reclaim policy"。
Recycle
保留PV,但清空其上數據,已廢棄
RESIZING
PVC
FEATURE STATE: Kubernetes v1.8
alpha
FEATURE STATE: Kubernetes v1.11
beta
此特性默認啟用。支持PVC擴容的的volume類型:
- gcePersistentDisk
- awsElasticBlockStore
- Cinder
- glusterfs
- rbd
- Azure File
- Azure Disk
- Portworx
如果對PVC擴容,則其對應的"storage class"中allowVolumeExpansion字段需要設置成true:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
編輯PVC為其指定更大容量,自動觸發與其綁定的PV的擴容,不是創建新的PV,而是在原有基礎上resize。
PV
只能對包含XFS, Ext3, or Ext4文件系統的PV執行resize操作,並且resize操作不會立即生效,只有當新pod通過ReadWrite模式的PVC使用PV,真正的resize才會生效。所以當為雲存儲供應商提供的PV執行resize后,必需刪除舊pod並創建新pod后,resize才會生效。查看PVC是否正在等待resize:
kubectl describe pvc <pvc_name>
當PVC的狀態為"FileSystemResizePending"時,刪除舊的pod並用PVC創建新pod是安全的,也就是不會丟失數據。
PV類型
Kubernetes通過插件支持各種PV類型,目前支持的插件有:
- 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 (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
- Portworx Volumes
- ScaleIO Volumes
- StorageOS
PV對象
PV對象與POD對象類似,包含spec與status兩部分:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
Capacity
.spec.capacity字段,目前只包含表示PV容量的storage字段,未來可能增加IOPS、throughput等。
Volume Mode
在1.9及之前的版本中,所有的volume插件都會在PV上創建文件系統(什么類型的文件系統?)。1.9以后的版本,此字段可以設置成"raw",則此時創建的PV為raw類型的存儲塊設備。如果此字段省略,默認為"Filesystem"。
Access Modes
不同存儲后端支持的訪問模式不同,同一種存儲后端的不同PV也可以各自設置訪問模式。如NFS支持多客端read/write,但其某一個具體PV的訪問模式可能是read-only。每個PV的訪問模式取決於其PV對象中accessModes字段設置。
具體的訪問模式有:
- ReadWriteOnce – volume可以被單節點以read-write模式掛開。
- ReadOnlyMany – volume可以被多節點以read-only模式掛載。
- ReadWriteMany – volume可以被多個節點以read-write模式掛載。
Volume可以同時支持多種訪問模式,但是在具體掛載時只能使用一種,這一點需要在pod中定義PVC類型的volume時說明。命令行支持縮寫:
- RWO - ReadWriteOnce
- ROX - ReadOnlyMany
- RWX - ReadWriteMany
不同存儲后端對訪問模式的支持:
Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
---|---|---|---|
AWSElasticBlockStore | ✓ | - | - |
AzureFile | ✓ | ✓ | ✓ |
AzureDisk | ✓ | - | - |
CephFS | ✓ | ✓ | ✓ |
Cinder | ✓ | - | - |
FC | ✓ | ✓ | - |
FlexVolume | ✓ | ✓ | - |
Flocker | ✓ | - | - |
GCEPersistentDisk | ✓ | ✓ | - |
Glusterfs | ✓ | ✓ | ✓ |
HostPath | ✓ | - | - |
iSCSI | ✓ | ✓ | - |
Quobyte | ✓ | ✓ | ✓ |
NFS | ✓ | ✓ | ✓ |
RBD | ✓ | ✓ | - |
VsphereVolume | ✓ | - | - (works when pods are collocated) |
PortworxVolume | ✓ | - | ✓ |
ScaleIO | ✓ | ✓ | - |
StorageOS | ✓ | - | - |
Class
"storageClassName"的值為某個"storage class"的名稱,表示PV由那個具體的存儲后端提供。特定"storage class"的PV只能被綁定給具有相同"storage class"的PVC。如果PV不包含"storage class",則這種類型的PV只能被綁定給同樣不包含"storage class"的PVC。
以前,使用注解"volume.beta.kubernetes.io/storage-class"存儲"storage class"而非"storageClassName",目前前一種方式仍然可以工作,但在將來的Kubernetes版本中將會完全廢棄。
Reclaim Policy
前文提到過,有三種:
- Retain – manual reclamation
- Recycle – basic scrub (rm -rf /thevolume/*)
- Delete – associated storage asset such as AWS EBS, GCE PD, Azure Disk, or OpenStack Cinder volume is deleted
目前只有NFS與hostPath支持Recycle, AWS EBS, GCE PD, Azure Disk, and Cinder支持Delete。
Mount Options
由集群管理員為PV指定的,當PV掛載到node的選項(動態PV如何指定?從storage class繼承嗎?)
支持掛載選項的后端存儲類型:
- GCEPersistentDisk
- AWSElasticBlockStore
- AzureFile
- AzureDisk
- NFS
- iSCSI
- RBD (Ceph Block Device)
- CephFS
- Cinder (OpenStack block storage)
- Glusterfs
- VsphereVolume
- Quobyte Volumes
系統不驗證掛載選項的可用性,如果設置錯誤,則僅僅返回掛載失敗。
以前,用注解volume.beta.kubernetes.io/mount-options表示掛載選項,目前仍然工作,但在將來版本中會被完全廢棄。
Phase
PV可能的phase:
- Available – 沒有綁定的free資源。
- Bound – 已經被PVC綁定。
- Released – PVC被刪除,但PV被保留,並且不可以被新PVC綁定。
- Failed – reclaim policy執行失敗。
可以通過命令行查看綁定PV的PVC。
PVC對象
同樣,一個PVC對象也包括spec與status兩部分:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
Access Modes
與PV含義相同,應該是PV與PVC相匹配才可以綁定。
Volume Modes
與PV含義相同,應該是PV與PVC相匹配才可以綁定。
Resources
指明所請求PV的大小。
Selector
選擇器PVC通過選擇器進一步過濾可選PV,支持matchLabels與matchExpressions兩種匹配表達式。
Class
含義與PV相同,只有此字段相同的PV與PVC可以相互綁定。但是如果PVC中完全沒有出現此字段,結果取決於:
DefaultStorageClass入口管理器是否被打開:
如果此入口管理器被管理員打開並指定了默認的storage class,則為PVC指定此默認storage class,如果打開入口控制器但沒有設置默認storage則與沒有打開效果相同。如果有多個默認storage class,禁止所有PVC創建。
如果沒有打開此入口控制器,則PVC中完此字段與將此字段設置成""等效。