臨時卷
本文件描述了 Kubernetes 中的**臨時卷**。建議熟悉卷,特別是 PersistentVolumeClaim 和 PersistentVolume。
某些應用程式需要額外的儲存,但並不關心這些資料是否在重啟後持久儲存。例如,快取服務通常受到記憶體大小的限制,可以將不經常使用的資料移動到比記憶體慢的儲存中,對整體效能影響很小。
其他應用程式期望一些只讀輸入資料以檔案形式存在,例如配置資料或金鑰。
**臨時卷**正是為這些用例設計的。由於卷遵循 Pod 的生命週期,與 Pod 一起建立和刪除,因此 Pod 可以停止和重新啟動,而不受限於某個持久卷是否可用。
臨時卷在 Pod 規約中**內聯**指定,這簡化了應用程式的部署和管理。
臨時卷的型別
Kubernetes 支援幾種不同型別的臨時卷,用於不同目的:
- emptyDir:Pod 啟動時為空,儲存來自 kubelet 的本地基本目錄(通常是根磁碟)或 RAM。
- configMap、downwardAPI、secret:將不同種類的 Kubernetes 資料注入 Pod。
- image:允許將容器映象檔案或工件直接掛載到 Pod。
- CSI 臨時卷:類似於之前的卷型別,但由特殊的 CSI 驅動程式提供,這些驅動程式專門支援此功能。
- 通用臨時卷:可以由所有支援持久卷的儲存驅動程式提供。
emptyDir
、configMap
、downwardAPI
、secret
作為本地臨時儲存提供。它們由每個節點上的 kubelet 管理。
CSI 臨時卷**必須**由第三方 CSI 儲存驅動程式提供。
通用臨時卷**可以**由第三方 CSI 儲存驅動程式提供,也可以由任何其他支援動態配置的儲存驅動程式提供。某些 CSI 驅動程式專門為 CSI 臨時卷編寫,不支援動態配置:這些驅動程式不能用於通用臨時卷。
使用第三方驅動程式的優勢在於它們可以提供 Kubernetes 本身不支援的功能,例如具有與 kubelet 管理的磁碟不同的效能特徵的儲存,或注入不同的資料。
CSI 臨時卷
Kubernetes v1.25 [穩定]
注意
CSI 臨時卷僅由 CSI 驅動程式的一個子集支援。Kubernetes CSI 驅動程式列表顯示了哪些驅動程式支援臨時卷。從概念上講,CSI 臨時卷類似於 configMap
、downwardAPI
和 secret
卷型別:儲存在每個節點上進行本地管理,並與 Pod 排程到節點後的其他本地資源一起建立。在此階段,Kubernetes 不再有重新排程 Pod 的概念。卷建立必須不太可能失敗,否則 Pod 啟動將停滯。特別是,這些卷**不支援**儲存容量感知 Pod 排程。它們目前也不受 Pod 儲存資源使用限制的約束,因為這是 kubelet 只能對其自身管理的儲存強制執行的。
以下是使用 CSI 臨時儲存的 Pod 示例清單:
kind: Pod
apiVersion: v1
metadata:
name: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/data"
name: my-csi-inline-vol
command: [ "sleep", "1000000" ]
volumes:
- name: my-csi-inline-vol
csi:
driver: inline.storage.kubernetes.io
volumeAttributes:
foo: bar
volumeAttributes
決定了驅動程式準備什麼卷。這些屬性是每個驅動程式特有的,而不是標準化的。有關更多說明,請參閱每個 CSI 驅動程式的文件。
CSI 驅動程式限制
CSI 臨時卷允許使用者將 volumeAttributes
直接作為 Pod 規約的一部分提供給 CSI 驅動程式。允許 volumeAttributes
通常僅限於管理員使用的 CSI 驅動程式不適合在內聯臨時卷中使用。例如,通常在 StorageClass 中定義的引數不應透過使用內聯臨時卷暴露給使用者。
需要限制允許在 Pod 規約中用作內聯卷的 CSI 驅動程式的叢集管理員可以透過以下方式實現:
- 從 CSIDriver 規約中的
volumeLifecycleModes
中刪除Ephemeral
,這會阻止該驅動程式用作內聯臨時卷。 - 使用准入 Webhook 來限制此驅動程式的使用方式。
通用臨時卷
Kubernetes v1.23 [stable]
通用臨時卷類似於 emptyDir
卷,因為它們為暫存資料提供了每個 Pod 的目錄,該目錄在配置後通常是空的。但它們也可能具有其他功能:
- 儲存可以是本地的或網路附加的。
- 卷可以具有 Pod 無法超出的固定大小。
- 卷可能具有一些初始資料,具體取決於驅動程式和引數。
- 假設驅動程式支援,則支援捲上的典型操作,包括快照、克隆、調整大小和儲存容量跟蹤。
示例
kind: Pod
apiVersion: v1
metadata:
name: my-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/scratch"
name: scratch-volume
command: [ "sleep", "1000000" ]
volumes:
- name: scratch-volume
ephemeral:
volumeClaimTemplate:
metadata:
labels:
type: my-frontend-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "scratch-storage-class"
resources:
requests:
storage: 1Gi
生命週期和 PersistentVolumeClaim
關鍵設計思想是允許在 Pod 的卷源中包含卷宣告的引數。支援標籤、註解和 PersistentVolumeClaim 的所有欄位集。當這樣的 Pod 被建立時,臨時卷控制器會在與 Pod 相同的名稱空間中建立一個實際的 PersistentVolumeClaim 物件,並確保當 Pod 被刪除時,PersistentVolumeClaim 也被刪除。
這會觸發卷繫結和/或配置,如果 StorageClass 使用即時卷繫結,則立即觸發;或者當 Pod 暫時排程到節點上時(WaitForFirstConsumer
卷繫結模式)觸發。對於通用臨時卷,推薦後者,因為這樣排程器可以自由選擇適合 Pod 的節點。如果使用即時繫結,排程器將被迫選擇一個一旦卷可用就能訪問該卷的節點。
就資源所有權而言,具有通用臨時儲存的 Pod 是提供該臨時儲存的 PersistentVolumeClaim(s) 的所有者。當 Pod 被刪除時,Kubernetes 垃圾回收器會刪除 PVC,這通常會觸發卷的刪除,因為儲存類的預設回收策略是刪除卷。你可以使用回收策略為 retain
的 StorageClass 建立準臨時本地儲存:儲存會比 Pod 壽命長,在這種情況下,你需要確保卷清理單獨進行。
當這些 PVC 存在時,它們可以像任何其他 PVC 一樣使用。特別是,它們可以作為卷克隆或快照的資料來源引用。PVC 物件還包含卷的當前狀態。
PersistentVolumeClaim 命名
自動建立的 PVC 的命名是確定的:名稱是 Pod 名稱和卷名稱的組合,中間用連字元(-
)連線。在上面的示例中,PVC 名稱將是 my-app-scratch-volume
。這種確定的命名使得與 PVC 互動變得更容易,因為一旦 Pod 名稱和卷名稱已知,就不必再搜尋它。
確定的命名也引入了不同 Pod 之間(名為 "pod-a" 的 Pod 帶有卷 "scratch",另一個名為 "pod" 的 Pod 帶有卷 "a-scratch",它們都以相同的 PVC 名稱 "pod-a-scratch" 結束)以及 Pod 與手動建立的 PVC 之間的潛在衝突。
這些衝突會被檢測到:PVC 僅在為 Pod 建立時才用於臨時卷。此檢查基於所有權關係。現有 PVC 不會被覆蓋或修改。但這並不能解決衝突,因為沒有正確的 PVC,Pod 就無法啟動。
注意
在同一名稱空間中命名 Pod 和卷時要小心,以免發生這些衝突。安全
使用通用臨時卷允許使用者間接建立 PVC,如果他們可以建立 Pod,即使他們沒有直接建立 PVC 的許可權。叢集管理員必須意識到這一點。如果這不符合他們的安全模型,他們應該使用准入 Webhook 來拒絕具有通用臨時卷的 Pod 等物件。
對 PVC 的常規名稱空間配額仍然適用,因此即使允許使用者使用這種新機制,他們也不能用它來規避其他策略。
下一步
由 kubelet 管理的臨時卷
請參閱本地臨時儲存。
CSI 臨時卷
- 有關設計的更多資訊,請參閱臨時內聯 CSI 卷 KEP。
- 有關此功能進一步開發的更多資訊,請參閱增強跟蹤問題 #596。
通用臨時卷
- 有關設計的更多資訊,請參閱通用臨時內聯卷 KEP。