儲存類
本文件描述了 Kubernetes 中 StorageClass 的概念。建議熟悉卷和持久卷。
StorageClass 為管理員提供了一種描述他們所提供的儲存“類別”的方式。不同的類別可能對映到服務質量級別、備份策略或由叢集管理員確定的任意策略。Kubernetes 本身對這些類別代表什麼沒有固定的看法。
Kubernetes 中儲存類的概念類似於某些其他儲存系統設計中的“配置檔案”。
StorageClass 物件
每個 StorageClass 都包含 `provisioner`、`parameters` 和 `reclaimPolicy` 欄位,這些欄位用於在需要動態提供屬於該類的 PersistentVolume 以滿足 PersistentVolumeClaim (PVC) 時。
StorageClass 物件的名稱很重要,它決定了使用者如何請求特定類。管理員在首次建立 StorageClass 物件時設定類的名稱和其他引數。
作為管理員,你可以指定一個預設 StorageClass,它適用於任何未請求特定類的 PVC。有關更多詳細資訊,請參閱PersistentVolumeClaim 概念。
以下是一個 StorageClass 示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: low-latency
annotations:
storageclass.kubernetes.io/is-default-class: "false"
provisioner: csi-driver.example-vendor.example
reclaimPolicy: Retain # default value is Delete
allowVolumeExpansion: true
mountOptions:
- discard # this might enable UNMAP / TRIM at the block storage layer
volumeBindingMode: WaitForFirstConsumer
parameters:
guaranteedReadWriteLatency: "true" # provider-specific
預設 StorageClass
你可以將一個 StorageClass 標記為叢集的預設 StorageClass。有關設定預設 StorageClass 的說明,請參閱更改預設 StorageClass。
當 PVC 未指定 `storageClassName` 時,將使用預設 StorageClass。
如果你的叢集中有多個 StorageClass 的`storageclass.kubernetes.io/is-default-class` 註解設定為 true,然後你建立了一個未設定 `storageClassName` 的 PersistentVolumeClaim,Kubernetes 將使用最近建立的預設 StorageClass。
注意
你應該嘗試在叢集中只保留一個標記為預設的 StorageClass。Kubernetes 允許你有多個預設 StorageClass 的原因是為了實現無縫遷移。你可以建立 PersistentVolumeClaim 而不為新的 PVC 指定 `storageClassName`,即使叢集中不存在預設 StorageClass 也可以。在這種情況下,新的 PVC 將按照你定義的方式建立,並且該 PVC 的 `storageClassName` 將保持未設定狀態,直到預設 StorageClass 可用。
你可以擁有一個沒有任何預設 StorageClass 的叢集。如果你沒有將任何 StorageClass 標記為預設(並且例如,雲提供商也沒有為你設定一個),那麼 Kubernetes 無法為需要預設 StorageClass 的 PersistentVolumeClaim 應用該預設值。
如果或當預設 StorageClass 可用時,控制平面會識別任何現有的沒有 `storageClassName` 的 PVC。對於 `storageClassName` 值為空或沒有此鍵的 PVC,控制平面會更新這些 PVC 以將 `storageClassName` 設定為與新的預設 StorageClass 匹配。如果你有一個現有的 PVC,其 `storageClassName` 為 `""`,並且你配置了一個預設 StorageClass,則此 PVC 不會被更新。
為了繼續繫結到 `storageClassName` 設定為 `""` 的 PV(在存在預設 StorageClass 的情況下),你需要將關聯的 PVC 的 `storageClassName` 設定為 `""`。
製備器
每個 StorageClass 都有一個製備器,它決定了用於製備 PV 的卷外掛。此欄位必須指定。
卷外掛 | 內部製備器 | 配置示例 |
---|---|---|
AzureFile | ✓ | Azure 檔案 |
CephFS | - | - |
FC | - | - |
FlexVolume | - | - |
iSCSI | - | - |
Local | - | Local |
NFS | - | NFS |
PortworxVolume | ✓ | Portworx 卷 |
RBD | - | Ceph RBD |
VsphereVolume | ✓ | vSphere |
你不僅限於指定此處列出的“內部”製備器(其名稱以“kubernetes.io”為字首並隨 Kubernetes 一起釋出)。你還可以執行和指定外部製備器,它們是遵循 Kubernetes 定義的規範的獨立程式。外部製備器的作者對其程式碼的儲存位置、製備器的釋出方式、執行方式、使用的卷外掛(包括 Flex)等擁有完全的自由裁量權。倉庫 kubernetes-sigs/sig-storage-lib-external-provisioner 包含一個用於編寫實現大部分規範的外部製備器的庫。一些外部製備器列在倉庫 kubernetes-sigs/sig-storage-lib-external-provisioner 下。
例如,NFS 沒有提供內部製備器,但可以使用外部製備器。第三方儲存廠商提供自己的外部製備器的情況也存在。
回收策略
由 StorageClass 動態建立的 PersistentVolumes 將具有在該類的 `reclaimPolicy` 欄位中指定的回收策略,該策略可以是 `Delete` 或 `Retain`。如果在建立 StorageClass 物件時未指定 `reclaimPolicy`,則預設為 `Delete`。
手動建立並透過 StorageClass 管理的 PersistentVolumes 將具有在建立時分配的任何回收策略。
卷擴容
PersistentVolumes 可以配置為可擴容。這允許你透過編輯相應的 PVC 物件並請求新的更大儲存量來調整卷大小。
當底層 StorageClass 將 `allowVolumeExpansion` 欄位設定為 true 時,以下卷型別支援卷擴容。
卷型別 | 卷擴容所需的 Kubernetes 版本 |
---|---|
Azure 檔案 | 1.11 |
CSI | 1.24 |
FlexVolume | 1.13 |
Portworx | 1.11 |
rbd | 1.11 |
注意
你只能使用卷擴容功能來增加捲,而不能縮小卷。掛載選項
由 StorageClass 動態建立的 PersistentVolumes 將具有在該類的 `mountOptions` 欄位中指定的掛載選項。
如果卷外掛不支援掛載選項但指定了掛載選項,則製備將失敗。掛載選項在類或 PV 上均不進行驗證。如果掛載選項無效,則 PV 掛載失敗。
卷繫結模式
`volumeBindingMode` 欄位控制卷繫結和動態製備何時發生。未設定時,預設為 `Immediate` 模式。
`Immediate` 模式表示一旦 PersistentVolumeClaim 建立,就會發生卷繫結和動態製備。對於受拓撲限制且無法從叢集中所有節點全域性訪問的儲存後端,PersistentVolumes 將在不知道 Pod 排程要求的情況下進行繫結或製備。這可能導致 Pod 無法排程。
叢集管理員可以透過指定 `WaitForFirstConsumer` 模式來解決此問題,該模式將延遲 PersistentVolume 的繫結和製備,直到建立使用 PersistentVolumeClaim 的 Pod。PersistentVolumes 將根據 Pod 排程約束指定的拓撲進行選擇或製備。這些約束包括但不限於資源要求、節點選擇器、Pod 親和性與反親和性以及汙點和容忍度。
以下外掛支援帶有動態製備的 `WaitForFirstConsumer`
- CSI 卷,前提是特定的 CSI 驅動程式支援此功能
以下外掛支援帶有預建立 PersistentVolume 繫結的 `WaitForFirstConsumer`
- CSI 卷,前提是特定的 CSI 驅動程式支援此功能
本地
注意
如果你選擇使用 `WaitForFirstConsumer`,請不要在 Pod 規約中使用 `nodeName` 來指定節點親和性。如果在此情況下使用 `nodeName`,排程器將被繞過,PVC 將保持 `pending` 狀態。
相反,你可以使用 `kubernetes.io/hostname` 的節點選擇器
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
nodeSelector:
kubernetes.io/hostname: kube-01
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
允許的拓撲
當叢集操作員指定 `WaitForFirstConsumer` 卷繫結模式時,在大多數情況下不再需要將製備限制到特定拓撲。但是,如果仍然需要,可以指定 `allowedTopologies`。
此示例演示瞭如何將已製備卷的拓撲限制到特定區域,並應作為受支援外掛的 `zone` 和 `zones` 引數的替代品。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: example.com/example
parameters:
type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: topology.kubernetes.io/zone
values:
- us-central-1a
- us-central-1b
引數
StorageClass 具有描述屬於該儲存類的卷的引數。根據 `provisioner` 的不同,可能會接受不同的引數。當省略引數時,將使用一些預設值。
一個 StorageClass 最多可以定義 512 個引數。引數物件的總長度(包括其鍵和值)不能超過 256 KiB。
AWS EBS
Kubernetes 1.34 不包含 `awsElasticBlockStore` 卷型別。
AWSElasticBlockStore 樹記憶體儲驅動程式在 Kubernetes v1.19 版本中被棄用,然後在 v1.27 版本中完全移除。
Kubernetes 專案建議你使用樹外 AWS EBS 儲存驅動程式。
以下是 AWS EBS CSI 驅動程式的 StorageClass 示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
csi.storage.k8s.io/fstype: xfs
type: io1
iopsPerGB: "50"
encrypted: "true"
tagSpecification_1: "key1=value1"
tagSpecification_2: "key2=value2"
allowedTopologies:
- matchLabelExpressions:
- key: topology.ebs.csi.aws.com/zone
values:
- us-east-2c
`tagSpecification`: 帶有此字首的標籤將應用於動態製備的 EBS 卷。
AWS EFS
要配置 AWS EFS 儲存,你可以使用樹外 AWS_EFS_CSI_DRIVER。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: fs-92107410
directoryPerms: "700"
- `provisioningMode`: 由 Amazon EFS 製備的卷型別。目前,僅支援基於接入點的製備(`efs-ap`)。
- `fileSystemId`: 建立接入點所在的 檔案系統。
- `directoryPerms`: 接入點建立的根目錄的目錄許可權。
有關更多詳細資訊,請參閱 AWS_EFS_CSI_Driver 動態製備 文件。
NFS
要配置 NFS 儲存,你可以使用樹內驅動程式或 Kubernetes 的 NFS CSI 驅動程式(推薦)。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-nfs
provisioner: example.com/external-nfs
parameters:
server: nfs-server.example.com
path: /share
readOnly: "false"
- `server`: 伺服器是 NFS 伺服器的主機名或 IP 地址。
- `path`: NFS 伺服器匯出的路徑。
- `readOnly`: 一個標誌,指示儲存是否以只讀方式掛載(預設為 false)。
Kubernetes 不包含內部 NFS 製備器。你需要使用外部製備器為 NFS 建立 StorageClass。以下是一些示例
vSphere
vSphere 儲存類有兩種製備器:
樹內製備器已棄用。有關 CSI 製備器的更多資訊,請參見Kubernetes vSphere CSI 驅動程式和vSphereVolume CSI 遷移。
CSI 製備器
vSphere CSI StorageClass 製備器與 Tanzu Kubernetes 叢集配合使用。有關示例,請參閱 vSphere CSI 倉庫。
vCP 製備器
以下示例使用 VMware Cloud Provider (vCP) StorageClass 製備器。
建立一個具有使用者指定磁碟格式的 StorageClass。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick
`diskformat`:`thin`、`zeroedthick` 和 `eagerzeroedthick`。預設值:`"thin"`。
在使用者指定的資料儲存上建立一個具有磁碟格式的 StorageClass。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick datastore: VSANDatastore
`datastore`: 使用者還可以在 StorageClass 中指定資料儲存。卷將建立在 StorageClass 中指定的資料儲存上,在本例中為 `VSANDatastore`。此欄位是可選的。如果未指定資料儲存,則卷將建立在用於初始化 vSphere Cloud Provider 的 vSphere 配置檔案中指定的資料儲存上。
Kubernetes 內的儲存策略管理
使用現有 vCenter SPBM 策略
vSphere 儲存管理最重要的功能之一是基於策略的管理。儲存策略基於管理 (SPBM) 是一種儲存策略框架,可在廣泛的資料服務和儲存解決方案中提供統一的控制平面。SPBM 使 vSphere 管理員能夠克服前期儲存製備挑戰,例如容量規劃、差異化服務級別和管理容量餘量。
SPBM 策略可以使用 `storagePolicyName` 引數在 StorageClass 中指定。
Kubernetes 中對 Virtual SAN 策略的支援
vSphere 基礎設施 (VI) 管理員將能夠在動態卷製備期間指定自定義 Virtual SAN 儲存能力。你現在可以在動態卷製備期間以儲存能力的形式定義儲存要求,例如效能和可用性。儲存能力要求將轉換為 Virtual SAN 策略,然後在建立持久卷(虛擬磁碟)時將其推送到 Virtual SAN 層。虛擬磁碟分佈在 Virtual SAN 資料儲存上以滿足要求。
你可以檢視基於儲存策略的捲動態製備以獲取有關如何使用儲存策略進行持久卷管理的更多詳細資訊。
有幾個vSphere 示例,你可以嘗試在 Kubernetes 中為 vSphere 進行持久卷管理。
Ceph RBD (已棄用)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/rbd # This provisioner is deprecated
parameters:
monitors: 198.19.254.105:6789
adminId: kube
adminSecretName: ceph-secret
adminSecretNamespace: kube-system
pool: kube
userId: kube
userSecretName: ceph-secret-user
userSecretNamespace: default
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
`monitors`: Ceph 監視器,逗號分隔。此引數是必需的。
`adminId`: 能夠在池中建立映像的 Ceph 客戶端 ID。預設為 "admin"。
`adminSecretName`: `adminId` 的 Secret 名稱。此引數是必需的。提供的 Secret 必須具有 "kubernetes.io/rbd" 型別。
`adminSecretNamespace`: `adminSecretName` 的名稱空間。預設為 "default"。
`pool`: Ceph RBD 池。預設為 "rbd"。
`userId`: 用於對映 RBD 映像的 Ceph 客戶端 ID。預設為與 `adminId` 相同。
`userSecretName`: 用於對映 RBD 映像的 `userId` 的 Ceph Secret 名稱。它必須與 PVC 位於同一名稱空間中。此引數是必需的。提供的 Secret 必須具有 "kubernetes.io/rbd" 型別,例如透過以下方式建立
kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ --namespace=kube-system
`userSecretNamespace`: `userSecretName` 的名稱空間。
`fsType`: Kubernetes 支援的 fsType。預設值:`"ext4"`。
`imageFormat`: Ceph RBD 映像格式,"1" 或 "2"。預設為 "2"。
`imageFeatures`: 此引數是可選的,僅當您將 `imageFormat` 設定為 "2" 時才應使用。目前支援的功能僅為 `layering`。預設為 "",並且未啟用任何功能。
Azure 磁碟
Kubernetes 1.34 不包含 `azureDisk` 卷型別。
`azureDisk` 樹記憶體儲驅動程式在 Kubernetes v1.19 版本中被棄用,然後在 v1.27 版本中完全移除。
Kubernetes 專案建議你使用 Azure Disk 第三方儲存驅動程式。
Azure 檔案 (已棄用)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azurefile
provisioner: kubernetes.io/azure-file
parameters:
skuName: Standard_LRS
location: eastus
storageAccount: azure_storage_account_name # example value
- `skuName`: Azure 儲存帳戶 SKU 層。預設值為空。
- `location`: Azure 儲存帳戶位置。預設值為空。
- `storageAccount`: Azure 儲存帳戶名稱。預設為空。如果未提供儲存帳戶,則會搜尋與資源組關聯的所有儲存帳戶,以查詢與 `skuName` 和 `location` 匹配的儲存帳戶。如果提供了儲存帳戶,它必須與叢集位於同一資源組中,並且 `skuName` 和 `location` 將被忽略。
- `secretNamespace`: 包含 Azure 儲存帳戶名稱和金鑰的 Secret 名稱空間。預設為 Pod 所在的名稱空間。
- `secretName`: 包含 Azure 儲存帳戶名稱和金鑰的 Secret 名稱。預設為 `azure-storage-account-
-secret` - `readOnly`: 一個標誌,指示儲存是否以只讀方式掛載。預設為 false,表示讀/寫掛載。此設定也將影響 VolumeMounts 中的 `ReadOnly` 設定。
在儲存製備期間,將為掛載憑據建立一個名為 `secretName` 的 Secret。如果叢集同時啟用了 RBAC 和 控制器角色,請為叢集角色 `system:controller:persistent-volume-binder` 新增資源 `secret` 的 `create` 許可權。
在多租戶環境中,強烈建議顯式設定 `secretNamespace` 的值,否則儲存帳戶憑據可能會被其他使用者讀取。
Portworx 卷 (已棄用)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: portworx-io-priority-high
provisioner: kubernetes.io/portworx-volume # This provisioner is deprecated
parameters:
repl: "1"
snap_interval: "70"
priority_io: "high"
- `fs`: 要佈局的檔案系統:`none/xfs/ext4`(預設:`ext4`)。
- `block_size`: 塊大小,以 Kbytes 為單位(預設值:`32`)。
- `repl`: 要提供的同步副本數量,以複製因子 `1..3` 的形式(預設值:`1`)。此處預期為字串,即 `"1"` 而非 `1`。
- `priority_io`: 決定卷是從高效能儲存還是低優先順序儲存建立 `high/medium/low`(預設值:`low`)。
- `snap_interval`: 觸發快照的時間間隔,以分鐘為單位。快照是基於與之前快照的差異的增量快照,0 表示停用快照(預設值:`0`)。此處預期為字串,即 `"70"` 而非 `70`。
- `aggregation_level`: 指定卷將分發的塊數,0 表示非聚合卷(預設值:`0`)。此處預期為字串,即 `"0"` 而非 `0`
- `ephemeral`: 指定卷在解除安裝後是否應清除或應持久化。`emptyDir` 用例可以將此值設定為 true,而 `persistent volumes` 用例(例如 Cassandra 等資料庫)應設定為 false,`true/false`(預設值 `false`)。此處預期為字串,即 `"true"` 而非 `true`。
Local
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner # indicates that this StorageClass does not support automatic provisioning
volumeBindingMode: WaitForFirstConsumer
Kubernetes 1.34 中的本地卷不支援動態製備;但是,仍應建立 StorageClass 以延遲卷繫結,直到 Pod 實際排程到適當的節點。這由 `WaitForFirstConsumer` 卷繫結模式指定。
延遲卷繫結允許排程器在為 PersistentVolumeClaim 選擇合適的 PersistentVolume 時考慮 Pod 的所有排程約束。