卷
容器中的磁碟檔案是暫時性的,這對於在容器中執行的重要應用程式造成了一些問題。其中一個問題發生在容器崩潰或停止時。容器狀態未儲存,因此在容器生命週期期間建立或修改的所有檔案都會遺失。在崩潰期間,kubelet 會以乾淨的狀態重新啟動容器。另一個問題發生在多個容器在 Pod
中執行且需要共用檔案時。在所有容器之間設定和存取共用檔案系統可能具有挑戰性。Kubernetes 卷抽象化解決了這兩個問題。建議您熟悉 Pod。
背景
Kubernetes 支援多種類型的卷。Pod 可以同時使用任意數量的卷類型。臨時卷類型具有 Pod 的生命週期,但持久卷的存在超出 Pod 的生命週期。當 Pod 不再存在時,Kubernetes 會銷毀臨時卷;但是,Kubernetes 不會銷毀持久卷。對於給定 Pod 中的任何類型的卷,資料都會在容器重新啟動後保留。
卷的核心是一個目錄,可能包含一些資料,Pod 中的容器可以存取它。該目錄的來源、支援它的媒體以及其內容由使用的特定卷類型決定。
若要使用卷,請在 .spec.volumes
中指定要為 Pod 提供的卷,並在 .spec.containers[*].volumeMounts
中宣告在何處將這些卷掛載到容器中。容器中的進程會看到一個檔案系統視圖,該視圖由容器映像檔的初始內容,加上掛載在容器內部的卷(如果已定義)組成。進程會看到一個根檔案系統,該檔案系統最初符合容器映像檔的內容。如果允許,對該檔案系統階層中的任何寫入都會影響該進程在執行後續檔案系統存取時所檢視的內容。卷會掛載在映像檔內的指定路徑。對於 Pod 中定義的每個容器,您都必須獨立指定要掛載容器使用的每個卷的位置。
卷無法掛載在其他卷中(但請參閱使用 subPath 以取得相關機制)。此外,卷不能包含指向不同卷中任何內容的硬連結。
卷類型
Kubernetes 支援多種類型的卷。
awsElasticBlockStore(已棄用)
在 Kubernetes 1.32 中,樹狀結構內 awsElasticBlockStore
類型的所有操作都會重新導向至 ebs.csi.aws.com
CSI 驅動程式。
AWSElasticBlockStore 樹狀結構內儲存驅動程式已在 Kubernetes v1.19 版本中棄用,然後在 v1.27 版本中完全移除。
Kubernetes 專案建議您改用 AWS EBS 第三方儲存驅動程式。
azureDisk(已棄用)
在 Kubernetes 1.32 中,樹狀結構內 azureDisk
類型的所有操作都會重新導向至 disk.csi.azure.com
CSI 驅動程式。
AzureDisk 樹狀結構內儲存驅動程式已在 Kubernetes v1.19 版本中棄用,然後在 v1.27 版本中完全移除。
Kubernetes 專案建議您改用 Azure Disk 第三方儲存驅動程式。
azureFile(已棄用)
Kubernetes v1.21 [已棄用]
azureFile
卷類型將 Microsoft Azure 檔案卷(SMB 2.1 和 3.0)掛載到 Pod 中。
如需更多詳細資訊,請參閱 azureFile
卷外掛程式。
azureFile CSI 遷移
Kubernetes v1.26 [穩定]
啟用 azureFile
的 CSIMigration
功能後,所有外掛程式操作都會從現有的 in-tree 外掛程式重新導向至 file.csi.azure.com
容器儲存介面 (CSI) 驅動程式。 若要使用此功能,必須在叢集上安裝 Azure File CSI 驅動程式,並且必須啟用 CSIMigrationAzureFile
功能閘道。
Azure File CSI 驅動程式不支援對不同 fsgroups 使用相同的磁碟區。如果啟用 CSIMigrationAzureFile
,則完全不支援對不同 fsgroups 使用相同的磁碟區。
azureFile CSI 移轉完成
Kubernetes v1.21 [alpha]
若要停用控制器管理員和 kubelet 載入 azureFile
儲存外掛程式,請將 InTreePluginAzureFileUnregister
旗標設定為 true
。
cephfs (已移除)
Kubernetes 1.32 不包含 cephfs
磁碟區類型。
cephfs
in-tree 儲存驅動程式已在 Kubernetes v1.28 版本中棄用,然後在 v1.31 版本中完全移除。
cinder (已棄用)
在 Kubernetes 1.32 中,in-tree cinder
類型的所有操作都會重新導向至 cinder.csi.openstack.org
CSI 驅動程式。
OpenStack Cinder in-tree 儲存驅動程式已在 Kubernetes v1.11 版本中棄用,然後在 v1.26 版本中完全移除。
Kubernetes 專案建議您改用 OpenStack Cinder 第三方儲存驅動程式。
configMap
ConfigMap 提供了一種將組態資料注入到 Pod 的方法。儲存在 ConfigMap 中的資料可以在 configMap
類型的磁碟區中引用,然後由在 Pod 中執行的容器化應用程式使用。
當引用 ConfigMap 時,您需要在磁碟區中提供 ConfigMap 的名稱。您可以自訂路徑,以用於 ConfigMap 中的特定條目。以下組態顯示如何將 log-config
ConfigMap 掛載到名為 configmap-pod
的 Pod 上
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox:1.28
command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
log-config
ConfigMap 作為磁碟區掛載,並且儲存在其 log_level
條目中的所有內容都會掛載到 Pod 中路徑 /etc/config/log_level
。請注意,此路徑是從磁碟區的 mountPath
和以 log_level
為鍵的路徑衍生而來。
注意
您必須先建立 ConfigMap,才能使用它。
ConfigMap 始終以
readOnly
模式掛載。使用 ConfigMap 作為
subPath
磁碟區掛載的容器將不會收到 ConfigMap 更新。文字資料以 UTF-8 字元編碼格式公開為檔案。對於其他字元編碼,請使用
binaryData
。
downwardAPI
downwardAPI
磁碟區使 downward API 資料可供應用程式使用。在磁碟區中,您可以找到以純文字格式公開為唯讀檔案的資料。
注意
使用 downward API 作為subPath
磁碟區掛載的容器在欄位值變更時不會收到更新。請參閱透過檔案向容器公開 Pod 資訊以了解更多資訊。
emptyDir
對於定義 emptyDir
磁碟區的 Pod,磁碟區會在 Pod 指派給節點時建立。顧名思義,emptyDir
磁碟區最初是空的。Pod 中的所有容器都可以讀取和寫入 emptyDir
磁碟區中的相同檔案,儘管該磁碟區可以掛載在每個容器中的相同或不同路徑。當 Pod 因任何原因從節點中移除時,emptyDir
中的資料將永久刪除。
注意
容器崩潰不會從節點中移除 Pod。emptyDir
磁碟區中的資料在容器崩潰時是安全的。emptyDir
的一些用途包括
- 暫存空間,例如用於基於磁碟的合併排序
- 為從崩潰中恢復而檢查長時間運算的進度
- 保存內容管理容器擷取的檔案,同時 Web 伺服器容器提供資料
emptyDir.medium
欄位控制 emptyDir
磁碟區的儲存位置。預設情況下,emptyDir
磁碟區儲存在任何支援節點的媒介上,例如磁碟、SSD 或網路儲存,具體取決於您的環境。如果您將 emptyDir.medium
欄位設定為 "Memory"
,Kubernetes 會為您掛載 tmpfs(RAM 支援的檔案系統)。雖然 tmpfs 速度非常快,但請注意,與磁碟不同,您寫入的檔案會計入寫入它們的容器的記憶體限制。
可以為預設媒介指定大小限制,這會限制 emptyDir
磁碟區的容量。儲存空間是從節點臨時儲存空間分配的。如果該空間被其他來源(例如,日誌檔案或映像覆蓋層)填滿,則 emptyDir
可能會在達到此限制之前耗盡容量。如果未指定大小,則記憶體支援的磁碟區大小將調整為節點可分配記憶體。
emptyDir 組態範例
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 500Mi
emptyDir 記憶體組態範例
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 500Mi
medium: Memory
fc (光纖通道)
fc
磁碟區類型允許將現有的光纖通道區塊儲存磁碟區掛載到 Pod 中。您可以使用 Volume 組態中的參數 targetWWNs
指定單個或多個目標全球廣域名稱 (WWN)。如果指定了多個 WWN,則 targetWWNs 預期這些 WWN 來自多路徑連線。
注意
您必須事先設定 FC SAN Zoning,將這些 LUN(磁碟區)分配並遮罩給目標 WWN,以便 Kubernetes 主機能夠存取它們。請參閱光纖通道範例以了解更多詳細資訊。
gcePersistentDisk (已棄用)
在 Kubernetes 1.32 中,in-tree gcePersistentDisk
類型的所有操作都會重新導向至 pd.csi.storage.gke.io
CSI 驅動程式。
gcePersistentDisk
in-tree 儲存驅動程式已在 Kubernetes v1.17 版本中棄用,然後在 v1.28 版本中完全移除。
Kubernetes 專案建議您改用 Google Compute Engine Persistent Disk CSI 第三方儲存驅動程式。
gitRepo (已棄用)
警告
gitRepo
磁碟區類型已棄用。
若要佈建具有已掛載 Git 儲存庫的 Pod,您可以將 emptyDir
磁碟區掛載到 init 容器中,該容器使用 Git 克隆儲存庫,然後將 EmptyDir 掛載到 Pod 的容器中。
您可以使用 原則(例如 ValidatingAdmissionPolicy)來限制在叢集中使用 gitRepo
磁碟區。您可以使用以下通用運算式語言 (CEL) 運算式作為原則的一部分,以拒絕使用 gitRepo
磁碟區:!has(object.spec.volumes) || !object.spec.volumes.exists(v, has(v.gitRepo))
。
gitRepo
磁碟區是磁碟區外掛程式的一個範例。此外掛程式會掛載一個空目錄,並將 git 儲存庫克隆到此目錄中,供您的 Pod 使用。
以下是 gitRepo
磁碟區的範例
apiVersion: v1
kind: Pod
metadata:
name: server
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /mypath
name: git-volume
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
glusterfs (已移除)
Kubernetes 1.32 不包含 glusterfs
磁碟區類型。
GlusterFS in-tree 儲存驅動程式已在 Kubernetes v1.25 版本中棄用,然後在 v1.26 版本中完全移除。
hostPath
hostPath
磁碟區會將主機節點檔案系統中的檔案或目錄掛載到您的 Pod 中。這不是大多數 Pod 需要的功能,但它為某些應用程式提供了一個強大的應急方案。
警告
使用 hostPath
磁碟區類型會帶來許多安全性風險。如果可以避免使用 hostPath
磁碟區,則應避免使用。例如,定義一個 local
PersistentVolume,並改用它。
如果您使用準入時間驗證來限制對節點上特定目錄的存取,則只有當您額外要求任何 hostPath
磁碟區的掛載都是唯讀時,該限制才有效。如果您允許不受信任的 Pod 對任何主機路徑進行讀寫掛載,則該 Pod 中的容器可能能夠破壞讀寫主機掛載。
使用 hostPath
磁碟區時要小心,無論這些磁碟區是以唯讀還是讀寫模式掛載,因為
- 存取主機檔案系統可能會洩露特權系統憑證(例如 kubelet 的憑證)或特權 API(例如容器執行階段 socket),這些憑證或 API 可用於容器逃逸或攻擊叢集的其他部分。
- 具有相同組態的 Pod(例如從 PodTemplate 建立的 Pod)在不同節點上的行為可能不同,因為節點上的檔案不同。
hostPath
磁碟區使用量不被視為臨時儲存空間使用量。您需要自行監控磁碟使用量,因為過多的hostPath
磁碟使用量會導致節點上的磁碟壓力。
hostPath
的一些用途包括
- 執行需要存取節點級系統元件的容器(例如將系統日誌傳輸到中央位置的容器,使用
/var/log
的唯讀掛載來存取這些日誌) - 將儲存在主機系統上的組態檔以唯讀方式提供給 靜態 Pod;與一般 Pod 不同,靜態 Pod 無法存取 ConfigMap
hostPath
磁碟區類型
除了必要的 path
屬性之外,您還可以選擇性地為 hostPath
磁碟區指定 type
。
type
的可用值包括
值 | 行為 |
---|---|
"" | 空字串(預設值)是為了向後相容性,這表示在掛載 hostPath 磁碟區之前不會執行任何檢查。 |
DirectoryOrCreate | 如果在給定路徑上不存在任何內容,則會根據需要在此處建立一個空目錄,權限設定為 0755,並具有與 Kubelet 相同的群組和所有權。 |
Directory | 給定路徑上必須存在目錄 |
FileOrCreate | 如果在給定路徑上不存在任何內容,則會根據需要在此處建立一個空檔案,權限設定為 0644,並具有與 Kubelet 相同的群組和所有權。 |
File | 給定路徑上必須存在檔案 |
Socket | 給定路徑上必須存在 UNIX socket |
CharDevice | (僅限 Linux 節點) 給定路徑上必須存在字元裝置 |
BlockDevice | (僅限 Linux 節點) 給定路徑上必須存在區塊裝置 |
注意
FileOrCreate
模式不會建立檔案的父目錄。如果掛載檔案的父目錄不存在,則 Pod 無法啟動。為了確保此模式有效,您可以嘗試分別掛載目錄和檔案,如 FileOrCreate
範例(適用於 hostPath
)所示。在底層主機上建立的某些檔案或目錄可能只能由 root 存取。然後,您需要以 root 身分在特權容器中執行您的程序,或修改主機上的檔案權限,以便能夠從 hostPath
磁碟區讀取(或寫入)。
hostPath 組態範例
---
# This manifest mounts /data/foo on the host as /foo inside the
# single container that runs within the hostpath-example-linux Pod.
#
# The mount into the container is read-only.
apiVersion: v1
kind: Pod
metadata:
name: hostpath-example-linux
spec:
os: { name: linux }
nodeSelector:
kubernetes.io/os: linux
containers:
- name: example-container
image: registry.k8s.io/test-webserver
volumeMounts:
- mountPath: /foo
name: example-volume
readOnly: true
volumes:
- name: example-volume
# mount /data/foo, but only if that directory already exists
hostPath:
path: /data/foo # directory location on host
type: Directory # this field is optional
---
# This manifest mounts C:\Data\foo on the host as C:\foo, inside the
# single container that runs within the hostpath-example-windows Pod.
#
# The mount into the container is read-only.
apiVersion: v1
kind: Pod
metadata:
name: hostpath-example-windows
spec:
os: { name: windows }
nodeSelector:
kubernetes.io/os: windows
containers:
- name: example-container
image: microsoft/windowsservercore:1709
volumeMounts:
- name: example-volume
mountPath: "C:\\foo"
readOnly: true
volumes:
# mount C:\Data\foo from the host, but only if that directory already exists
- name: example-volume
hostPath:
path: "C:\\Data\\foo" # directory location on host
type: Directory # this field is optional
hostPath FileOrCreate 組態範例
以下資訊清單定義了一個 Pod,該 Pod 將 /var/local/aaa
掛載到 Pod 中唯一的容器內。如果節點尚沒有路徑 /var/local/aaa
,則 kubelet 會將其建立為目錄,然後將其掛載到 Pod 中。
如果 /var/local/aaa
已存在但不是目錄,則 Pod 會失敗。此外,kubelet 會嘗試在該目錄內(從主機的角度來看)建立一個名為 /var/local/aaa/1.txt
的檔案;如果該路徑上已存在某些內容且不是常規檔案,則 Pod 會失敗。
以下是範例資訊清單
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
os: { name: linux }
nodeSelector:
kubernetes.io/os: linux
containers:
- name: test-webserver
image: registry.k8s.io/test-webserver:latest
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
# Ensure the file directory is created.
path: /var/local/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
image
Kubernetes v1.31 [alpha]
(預設為停用:false)image
磁碟區來源代表 kubelet 主機上可用的 OCI 物件(容器映像或構件)。
使用 image
磁碟區來源的一個範例是
apiVersion: v1
kind: Pod
metadata:
name: image-volume
spec:
containers:
- name: shell
command: ["sleep", "infinity"]
image: debian
volumeMounts:
- name: volume
mountPath: /volume
volumes:
- name: volume
image:
reference: quay.io/crio/artifact:v1
pullPolicy: IfNotPresent
磁碟區會在 pod 啟動時根據提供的 pullPolicy
值進行解析
Always
- kubelet 始終嘗試提取參考。如果提取失敗,kubelet 會將 Pod 設定為
Failed
。 Never
- kubelet 永遠不會提取參考,而僅使用本機映像或構件。如果映像的任何層未在本機存在,或者該映像的資訊清單尚未快取,則 Pod 會變成
Failed
。 IfNotPresent
- 如果參考在磁碟上尚不存在,則 kubelet 會進行提取。如果參考不存在且提取失敗,則 Pod 會變成
Failed
。
如果刪除並重新建立 pod,則磁碟區會重新解析,這表示新的遠端內容將在 pod 重新建立時可用。在 pod 啟動期間解析或提取映像失敗將會阻止容器啟動,並可能增加顯著的延遲。失敗將使用正常的磁碟區退避重試,並將在 pod 原因和訊息中報告。
此磁碟區可以掛載的物件類型由主機上的容器執行階段實作定義,並且至少必須包含容器映像欄位支援的所有有效類型。OCI 物件會掛載在單個目錄 (spec.containers[*].volumeMounts.mountPath
) 中,並將以唯讀方式掛載。在 Linux 上,容器執行階段通常也會掛載已阻止檔案執行的磁碟區 (noexec
)。
除此之外
- 不支援容器的子路徑掛載 (
spec.containers[*].volumeMounts.subpath
)。 - 欄位
spec.securityContext.fsGroupChangePolicy
對此磁碟區類型沒有影響。 AlwaysPullImages
準入控制器也適用於此磁碟區來源,就像容器映像一樣。
以下欄位可用於 image
類型
reference
- 要使用的構件參考。例如,您可以指定
registry.k8s.io/conformance:v1.32.0
以從 Kubernetes 一致性測試映像載入檔案。行為方式與pod.spec.containers[*].image
相同。提取密碼將以與容器映像相同的方式組裝,方法是查找節點憑證、服務帳戶映像提取密碼和 pod 規格映像提取密碼。此欄位是可選的,允許更高等級的組態管理在工作負載控制器(如 Deployments 和 StatefulSets)中預設或覆蓋容器映像。有關容器映像的更多資訊 pullPolicy
- 提取 OCI 物件的策略。可能的值為:
Always
、Never
或IfNotPresent
。如果指定:latest
標籤,則預設為Always
,否則預設為IfNotPresent
。
請參閱在 Pod 中使用映像磁碟區範例,以取得有關如何使用磁碟區來源的更多詳細資訊。
iscsi
iscsi
磁碟區允許將現有的 iSCSI (IP 上的 SCSI) 磁碟區掛載到您的 Pod 中。與 Pod 移除時會清除的 emptyDir
不同,iscsi
磁碟區的內容會被保留,並且磁碟區僅被解除掛載。這表示 iscsi 磁碟區可以預先填入資料,並且可以在 pod 之間共用該資料。
注意
您必須擁有自己的 iSCSI 伺服器執行,並在可以使用之前建立磁碟區。iSCSI 的一個功能是它可以由多個消費者同時以唯讀模式掛載。這表示您可以預先填入包含資料集的磁碟區,然後從您需要的任意多個 Pod 中並行提供它。遺憾的是,iSCSI 磁碟區只能由單個消費者以讀寫模式掛載。不允許同時寫入。
請參閱iSCSI 範例以了解更多詳細資訊。
local
local
磁碟區代表已掛載的本機儲存裝置,例如磁碟、分割區或目錄。
本機磁碟區只能用作靜態建立的 PersistentVolume。不支援動態佈建。
與 hostPath
磁碟區相比,local
磁碟區以持久且可移植的方式使用,無需手動將 pod 排程到節點。系統會透過查看 PersistentVolume 上的節點親和性來了解磁碟區的節點約束。
但是,local
磁碟區受制於底層節點的可用性,並且不適用於所有應用程式。如果節點變得不健康,則 pod 將無法存取 local
磁碟區。使用此磁碟區的 pod 無法執行。使用 local
磁碟區的應用程式必須能夠容忍這種降低的可用性,以及潛在的資料遺失,具體取決於底層磁碟的持久性特性。
以下範例顯示了使用 local
磁碟區和 nodeAffinity
的 PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
使用 local
磁碟區時,您必須設定 PersistentVolume nodeAffinity
。Kubernetes 排程器使用 PersistentVolume nodeAffinity
將這些 Pod 排程到正確的節點。
PersistentVolume volumeMode
可以設定為 "Block"(而不是預設值 "Filesystem")以將本機磁碟區公開為原始區塊裝置。
使用本機磁碟區時,建議建立一個 volumeBindingMode
設定為 WaitForFirstConsumer
的 StorageClass。如需更多詳細資訊,請參閱本機 StorageClass 範例。延遲磁碟區繫結可確保 PersistentVolumeClaim 繫結決策也將與 Pod 可能具有的任何其他節點約束(例如節點資源需求、節點選取器、Pod 親和性和 Pod 反親和性)一起評估。
可以單獨執行外部靜態佈建器,以改進本機磁碟區生命週期的管理。請注意,此佈建器尚不支援動態佈建。有關如何執行外部本機佈建器的範例,請參閱本機磁碟區佈建器使用者指南。
注意
如果未使用外部靜態佈建器來管理磁碟區生命週期,則本機 PersistentVolume 需要使用者手動清理和刪除。nfs
nfs
磁碟區允許將現有的 NFS (網路檔案系統) 共用掛載到 Pod 中。與 Pod 移除時會清除的 emptyDir
不同,nfs
磁碟區的內容會被保留,並且磁碟區僅被解除掛載。這表示 NFS 磁碟區可以預先填入資料,並且可以在 pod 之間共用該資料。NFS 可以由多個寫入器同時掛載。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /my-nfs-data
name: test-volume
volumes:
- name: test-volume
nfs:
server: my-nfs-server.example.com
path: /my-nfs-volume
readOnly: true
注意
您必須擁有自己的 NFS 伺服器執行,並在可以使用之前匯出共用。
另請注意,您無法在 Pod 規格中指定 NFS 掛載選項。您可以設定伺服器端掛載選項或使用 /etc/nfsmount.conf。您也可以透過 PersistentVolume 掛載 NFS 磁碟區,PersistentVolume 允許您設定掛載選項。
請參閱NFS 範例,以取得使用 PersistentVolume 掛載 NFS 磁碟區的範例。
persistentVolumeClaim
persistentVolumeClaim
磁碟區用於將 PersistentVolume 掛載到 Pod 中。PersistentVolumeClaim 是使用者「聲明」持久儲存空間(例如 iSCSI 磁碟區)的一種方式,而無需了解特定雲端環境的詳細資訊。
請參閱有關 PersistentVolume 的資訊以了解更多詳細資訊。
portworxVolume (已棄用)
Kubernetes v1.25 [已棄用]
portworxVolume
是一個彈性區塊儲存層,與 Kubernetes 超融合執行。Portworx 會對伺服器中的儲存空間進行指紋識別,根據功能分層,並彙總多個伺服器之間的容量。Portworx 在虛擬機器中或裸機 Linux 節點上以訪客身分執行。
portworxVolume
可以透過 Kubernetes 動態建立,也可以預先佈建並在 Pod 內部引用。以下是引用預先佈建的 Portworx 磁碟區的 Pod 範例
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# This Portworx volume must already exist.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
注意
在使用 Pod 中的 PortworxVolume 之前,請確保您已有名為pxvol
的現有 PortworxVolume。如需更多詳細資訊,請參閱Portworx 磁碟區範例。
Portworx CSI 移轉
Kubernetes v1.25 [beta]
預設情況下,Kubernetes 1.32 嘗試移轉舊版 Portworx 磁碟區以使用 CSI。(Portworx 的 CSI 移轉自 Kubernetes v1.23 起已可用,但自 v1.31 版本起才預設啟用)。如果您想要停用自動移轉,可以將 CSIMigrationPortworx
功能閘道設定為 false
;您需要為 kube-controller-manager 和每個相關的 kubelet 進行此變更。
它會將所有外掛程式操作從現有的 in-tree 外掛程式重新導向至 pxd.portworx.com
容器儲存介面 (CSI) 驅動程式。Portworx CSI 驅動程式必須安裝在叢集上。
projected
投影磁碟區將多個現有的磁碟區來源對應到同一個目錄中。如需更多詳細資訊,請參閱投影磁碟區。
rbd (已移除)
Kubernetes 1.32 不包含 rbd
磁碟區類型。
Rados Block Device (RBD) in-tree 儲存驅動程式及其 csi 移轉支援已在 Kubernetes v1.28 版本中棄用,然後在 v1.31 版本中完全移除。
secret
secret
磁碟區用於將機密資訊(例如密碼)傳遞給 Pod。您可以將密碼儲存在 Kubernetes API 中,並將其掛載為檔案供 pod 使用,而無需直接耦合到 Kubernetes。secret
磁碟區由 tmpfs(RAM 支援的檔案系統)支援,因此它們永遠不會寫入非揮發性儲存裝置。
注意
您必須先在 Kubernetes API 中建立 Secret,才能使用它。
Secret 始終以
readOnly
模式掛載。使用 Secret 作為
subPath
磁碟區掛載的容器將不會收到 Secret 更新。
如需更多詳細資訊,請參閱設定 Secret。
vsphereVolume (已棄用)
注意
Kubernetes 專案建議改用 vSphere CSI out-of-tree 儲存驅動程式。vsphereVolume
用於將 vSphere VMDK 磁碟區掛載到您的 Pod 中。磁碟區的內容在解除掛載時會保留。它同時支援 VMFS 和 VSAN 資料存放區。
如需更多資訊,請參閱vSphere 磁碟區範例。
vSphere CSI 移轉
Kubernetes v1.26 [穩定]
在 Kubernetes 1.32 中,in-tree vsphereVolume
類型的所有操作都會重新導向至 csi.vsphere.vmware.com
CSI 驅動程式。
vSphere CSI 驅動程式必須安裝在叢集上。您可以在 VMware 的文件頁面 Migrating In-Tree vSphere Volumes to vSphere Container Storage Plug-in 中找到有關如何移轉 in-tree vsphereVolume
的其他建議。如果未安裝 vSphere CSI 驅動程式,則無法對使用 in-tree vsphereVolume
類型建立的 PV 執行磁碟區操作。
您必須執行 vSphere 7.0u2 或更高版本才能移轉到 vSphere CSI 驅動程式。
如果您執行的 Kubernetes 版本不是 v1.32,請查閱該 Kubernetes 版本的說明文件。
注意
內建 vsphereVolume
外掛程式的以下 StorageClass 參數不受 vSphere CSI 驅動程式支援
diskformat
hostfailurestotolerate
forceprovisioning
cachereservation
diskstripes
objectspacereservation
iopslimit
使用這些參數建立的現有磁碟區將移轉到 vSphere CSI 驅動程式,但由 vSphere CSI 驅動程式建立的新磁碟區將不會遵循這些參數。
vSphere CSI 移轉完成
Kubernetes v1.19 [beta]
若要關閉控制器管理員和 kubelet 載入 vsphereVolume
外掛程式,您需要將 InTreePluginvSphereUnregister
功能旗標設定為 true
。您必須在所有工作節點上安裝 csi.vsphere.vmware.com
CSI 驅動程式。
使用 subPath
有時,在單個 pod 中為多個用途共用一個磁碟區很有用。volumeMounts[*].subPath
屬性指定引用磁碟區內的子路徑,而不是其根目錄。
以下範例顯示如何使用單個共用磁碟區來設定具有 LAMP 堆疊 (Linux Apache MySQL PHP) 的 Pod。此範例 subPath
組態不建議用於生產環境。
PHP 應用程式的程式碼和資產對應到磁碟區的 html
資料夾,而 MySQL 資料庫儲存在磁碟區的 mysql
資料夾中。例如
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
使用具有展開的環境變數的 subPath
Kubernetes v1.17 [stable]
使用 subPathExpr
欄位從 downward API 環境變數建構 subPath
目錄名稱。subPath
和 subPathExpr
屬性是互斥的。
在此範例中,Pod
使用 subPathExpr
在 hostPath
磁碟區 /var/log/pods
中建立目錄 pod1
。hostPath
磁碟區從 downwardAPI
取得 Pod
名稱。主機目錄 /var/log/pods/pod1
掛載在容器中的 /logs
。
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox:1.28
command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
volumeMounts:
- name: workdir1
mountPath: /logs
# The variable expansion uses round brackets (not curly brackets).
subPathExpr: $(POD_NAME)
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods
資源
emptyDir
磁碟區的儲存媒介(例如磁碟或 SSD)由保存 kubelet 根目錄(通常為 /var/lib/kubelet
)的檔案系統的媒介決定。emptyDir
或 hostPath
磁碟區可以消耗多少空間沒有限制,並且容器之間或 pod 之間沒有隔離。
若要了解如何使用資源規格請求空間,請參閱如何管理資源。
Out-of-tree 磁碟區外掛程式
Out-of-tree 磁碟區外掛程式包括容器儲存介面 (CSI) 以及 FlexVolume(已棄用)。這些外掛程式使儲存廠商能夠建立自訂儲存外掛程式,而無需將其外掛程式原始碼新增至 Kubernetes 儲存庫。
以前,所有磁碟區外掛程式都是「in-tree」。 「In-tree」外掛程式是與核心 Kubernetes 二進位檔案一起建置、連結、編譯和發行的。這表示將新的儲存系統新增至 Kubernetes(磁碟區外掛程式)需要將程式碼簽入核心 Kubernetes 程式碼儲存庫。
CSI 和 FlexVolume 都允許獨立於 Kubernetes 程式碼庫開發磁碟區外掛程式,並作為擴充功能部署(安裝)在 Kubernetes 叢集上。
對於希望建立 out-of-tree 磁碟區外掛程式的儲存廠商,請參閱磁碟區外掛程式常見問題。
csi
容器儲存介面 (CSI) 定義了一個標準介面,供容器協調系統(如 Kubernetes)將任意儲存系統公開給其容器工作負載。
請閱讀 CSI 設計提案以了解更多資訊。
注意
Kubernetes v1.13 中已棄用對 CSI 規格版本 0.2 和 0.3 的支援,並將在未來版本中移除。注意
CSI 驅動程式可能不跨所有 Kubernetes 版本相容。請查看特定 CSI 驅動程式的文件,以了解每個 Kubernetes 版本的支援部署步驟和相容性矩陣。一旦在 Kubernetes 叢集上部署了 CSI 相容的磁碟區驅動程式,使用者就可以使用 csi
磁碟區類型來連接或掛載 CSI 驅動程式公開的磁碟區。
csi
磁碟區可以在 Pod 中以三種不同的方式使用
- 透過引用 PersistentVolumeClaim
- 使用通用臨時磁碟區
- 如果驅動程式支援,則使用 CSI 臨時磁碟區
以下欄位可供儲存管理員用於組態 CSI 持久磁碟區
driver
:一個字串值,指定要使用的磁碟區驅動程式的名稱。此值必須與 CSI 驅動程式在 CSI 規格中定義的GetPluginInfoResponse
中傳回的值相對應。Kubernetes 使用它來識別要呼叫哪個 CSI 驅動程式,CSI 驅動程式元件使用它來識別哪些 PV 物件屬於 CSI 驅動程式。volumeHandle
:一個字串值,可唯一識別磁碟區。此值必須與 CSI 驅動程式在CreateVolumeResponse
的volume.id
欄位中傳回的值相對應,如 CSI 規範中所定義。當參照磁碟區時,此值會以volume_id
形式傳遞至 CSI 磁碟區驅動程式的所有呼叫。readOnly
:一個選用的布林值,指示磁碟區是否要以唯讀方式「ControllerPublished」(掛接)。預設值為 false。此值透過ControllerPublishVolumeRequest
中的readonly
欄位傳遞至 CSI 驅動程式。fsType
:如果 PV 的VolumeMode
為Filesystem
,則可以使用此欄位指定應該用於掛載磁碟區的檔案系統。如果磁碟區尚未格式化且支援格式化,則此值將用於格式化磁碟區。此值會透過ControllerPublishVolumeRequest
、NodeStageVolumeRequest
和NodePublishVolumeRequest
的VolumeCapability
欄位傳遞至 CSI 驅動程式。volumeAttributes
:一個字串到字串的映射,用於指定磁碟區的靜態屬性。此映射必須與 CSI 驅動程式在CreateVolumeResponse
的volume.attributes
欄位中傳回的映射相對應,如 CSI 規範中所定義。此映射會透過ControllerPublishVolumeRequest
、NodeStageVolumeRequest
和NodePublishVolumeRequest
中的volume_context
欄位傳遞至 CSI 驅動程式。controllerPublishSecretRef
:對 secret 物件的參照,其中包含要傳遞至 CSI 驅動程式的敏感資訊,以完成 CSIControllerPublishVolume
和ControllerUnpublishVolume
呼叫。此欄位為選用欄位,如果不需要 secret,則可以為空。如果 Secret 包含多個 secret,則會傳遞所有 secret。nodeExpandSecretRef
:對 secret 的參照,其中包含要傳遞至 CSI 驅動程式的敏感資訊,以完成 CSINodeExpandVolume
呼叫。此欄位為選用欄位,如果不需要 secret,則可以為空。如果物件包含多個 secret,則會傳遞所有 secret。當您為節點啟動的磁碟區擴充功能設定 secret 資料時,kubelet 會透過NodeExpandVolume()
呼叫將該資料傳遞至 CSI 驅動程式。所有受支援的 Kubernetes 版本都提供nodeExpandSecretRef
欄位,並且預設情況下可用。v1.25 之前的 Kubernetes 版本不包含此支援。- 為每個 kube-apiserver 和每個節點上的 kubelet 啟用名為
CSINodeExpandSecret
的 功能閘道。由於 Kubernetes 1.27 版起,此功能已預設啟用,因此無需明確啟用功能閘道。您也必須使用在節點啟動的儲存大小調整操作期間支援或需要 secret 資料的 CSI 驅動程式。 nodePublishSecretRef
:對 secret 物件的參照,其中包含要傳遞至 CSI 驅動程式的敏感資訊,以完成 CSINodePublishVolume
呼叫。此欄位為選用欄位,如果不需要 secret,則可以為空。如果 secret 物件包含多個 secret,則會傳遞所有 secret。nodeStageSecretRef
:對 secret 物件的參照,其中包含要傳遞至 CSI 驅動程式的敏感資訊,以完成 CSINodeStageVolume
呼叫。此欄位為選用欄位,如果不需要 secret,則可以為空。如果 Secret 包含多個 secret,則會傳遞所有 secret。
CSI 原始區塊磁碟區支援
Kubernetes v1.18 [穩定]
具有外部 CSI 驅動程式的供應商可以在 Kubernetes 工作負載中實作原始區塊磁碟區支援。
您可以照常設定具有原始區塊磁碟區支援的 PersistentVolume/PersistentVolumeClaim,而無需任何 CSI 特定變更。
CSI 臨時磁碟區
Kubernetes v1.25 [穩定]
您可以直接在 Pod 規格中設定 CSI 磁碟區。以這種方式指定的磁碟區是臨時性的,並且不會在 Pod 重新啟動後持續存在。如需更多資訊,請參閱 臨時磁碟區。
如需有關如何開發 CSI 驅動程式的更多資訊,請參閱 kubernetes-csi 文件
Windows CSI Proxy
Kubernetes v1.22 [穩定]
CSI 節點外掛程式需要執行各種特權操作,例如掃描磁碟裝置和掛載檔案系統。這些操作對於每個主機作業系統都不同。對於 Linux 工作節點,容器化的 CSI 節點外掛程式通常以特權容器的形式部署。對於 Windows 工作節點,容器化 CSI 節點外掛程式的特權操作透過 csi-proxy 支援,這是一個社群管理的獨立二進位檔,需要預先安裝在每個 Windows 節點上。
如需更多詳細資訊,請參閱您希望部署的 CSI 外掛程式的部署指南。
從樹狀結構內外掛程式遷移到 CSI 驅動程式
Kubernetes v1.25 [穩定]
CSIMigration
功能將針對現有樹狀結構內外掛程式的操作導向至對應的 CSI 外掛程式(預期已安裝和設定)。因此,當轉換到取代樹狀結構內外掛程式的 CSI 驅動程式時,運算子無需對現有的儲存類別、PersistentVolume 或 PersistentVolumeClaim(參照樹狀結構內外掛程式)進行任何組態變更。
注意
即使在完成該磁碟區類型的 CSI 遷移之後,甚至在您升級到不具有針對該類儲存的編譯內建支援的 Kubernetes 版本之後,由樹狀結構內磁碟區外掛程式建立的現有 PV 仍然可以在未來使用,而無需任何組態變更。
作為該遷移的一部分,您或其他叢集管理員必須已安裝並設定該儲存的適當 CSI 驅動程式。Kubernetes 的核心不會為您安裝該軟體。
在遷移之後,您也可以定義新的 PVC 和 PV,這些 PVC 和 PV 參照舊版、內建儲存整合。假設您已安裝並設定適當的 CSI 驅動程式,即使對於全新的磁碟區,PV 建立也會繼續運作。實際的儲存管理現在透過 CSI 驅動程式進行。
支援的操作和功能包括:佈建/刪除、連接/中斷連接、掛載/解除掛載和調整磁碟區大小。
支援 CSIMigration
且具有對應 CSI 驅動程式實作的樹狀結構內外掛程式列在 磁碟區類型中。
以下樹狀結構內外掛程式支援 Windows 節點上的永久儲存
flexVolume(已棄用)
Kubernetes v1.23 [已棄用]
FlexVolume 是一個樹狀結構外的外掛程式介面,它使用基於 exec 的模型來與儲存驅動程式介接。FlexVolume 驅動程式二進位檔必須安裝在每個節點以及某些情況下的控制平面節點上的預定義磁碟區外掛程式路徑中。
Pod 透過 flexVolume
樹狀結構內磁碟區外掛程式與 FlexVolume 驅動程式互動。如需更多詳細資訊,請參閱 FlexVolume README 文件。
以下 FlexVolume 外掛程式(以 PowerShell 指令碼的形式部署在主機上)支援 Windows 節點
注意
FlexVolume 已棄用。建議使用樹狀結構外的 CSI 驅動程式來整合外部儲存與 Kubernetes。
FlexVolume 驅動程式的維護者應實作 CSI 驅動程式,並協助將 FlexVolume 驅動程式的使用者遷移到 CSI。FlexVolume 的使用者應將其工作負載移至使用對等的 CSI 驅動程式。
掛載傳播
掛載傳播允許將容器掛載的磁碟區共用給同一個 Pod 中的其他容器,甚至共用給同一個節點上的其他 Pod。
磁碟區的掛載傳播由 containers[*].volumeMounts
中的 mountPropagation
欄位控制。其值為
None
- 此磁碟區掛載將不會接收主機掛載到此磁碟區或其任何子目錄的任何後續掛載。同樣地,容器建立的任何掛載在主機上都不可見。這是預設模式。此模式等於
mount(8)
中描述的rprivate
掛載傳播但是,當
rprivate
傳播不適用時,CRI 執行階段可能會選擇rslave
掛載傳播(即HostToContainer
)。已知 cri-dockerd (Docker) 在掛載來源包含 Docker daemon 的根目錄 (/var/lib/docker
) 時會選擇rslave
掛載傳播。HostToContainer
- 此磁碟區掛載將接收掛載到此磁碟區或其任何子目錄的所有後續掛載。換句話說,如果主機在此磁碟區掛載內掛載任何內容,容器將會看到它掛載在那裡。
同樣地,如果任何具有相同磁碟區
Bidirectional
掛載傳播的 Pod 在那裡掛載任何內容,則具有HostToContainer
掛載傳播的容器將會看到它。此模式等於
mount(8)
中描述的rslave
掛載傳播Bidirectional
- 此磁碟區掛載的行為與HostToContainer
掛載相同。此外,容器建立的所有磁碟區掛載都將傳播回主機以及使用相同磁碟區的所有 Pod 的所有容器。此模式的典型用例是具有 FlexVolume 或 CSI 驅動程式的 Pod,或是需要使用
hostPath
磁碟區在主機上掛載某些內容的 Pod。此模式等於
mount(8)
中描述的rshared
掛載傳播警告
Bidirectional
掛載傳播可能很危險。它可能會損壞主機作業系統,因此僅允許在特權容器中使用。強烈建議熟悉 Linux 核心行為。此外,Pod 中容器建立的任何磁碟區掛載都必須在容器終止時由容器銷毀(解除掛載)。
唯讀掛載
可以透過將 .spec.containers[].volumeMounts[].readOnly
欄位設定為 true
來將掛載設為唯讀。這不會使磁碟區本身成為唯讀,但該特定容器將無法寫入它。Pod 中的其他容器可以將同一個磁碟區掛載為讀寫。
在 Linux 上,預設情況下,唯讀掛載不是遞迴唯讀的。例如,考慮一個 Pod,它將主機的 /mnt
掛載為 hostPath
磁碟區。如果在 /mnt/<SUBMOUNT>
上掛載了另一個讀寫檔案系統(例如 tmpfs、NFS 或 USB 儲存),即使掛載本身被指定為唯讀,掛載到容器中的磁碟區也將具有可寫入的 /mnt/<SUBMOUNT>
。
遞迴唯讀掛載
Kubernetes v1.31 [Beta 版]
(預設啟用:true)可以透過為 kubelet 和 kube-apiserver 設定 RecursiveReadOnlyMounts
功能閘道,並為 Pod 設定 .spec.containers[].volumeMounts[].recursiveReadOnly
欄位來啟用遞迴唯讀掛載。
允許的值為
Disabled
(預設):無效。Enabled
:使掛載成為遞迴唯讀。需要滿足以下所有要求readOnly
設定為true
mountPropagation
未設定,或設定為None
- 主機正在執行 Linux 核心 v5.12 或更高版本
- CRI 層級容器執行階段支援遞迴唯讀掛載
- OCI 層級容器執行階段支援遞迴唯讀掛載。如果任何一個不為真,則會失敗。
IfPossible
:嘗試套用Enabled
,如果核心或執行階段類別不支援該功能,則回復為Disabled
。
範例
apiVersion: v1
kind: Pod
metadata:
name: rro
spec:
volumes:
- name: mnt
hostPath:
# tmpfs is mounted on /mnt/tmpfs
path: /mnt
containers:
- name: busybox
image: busybox
args: ["sleep", "infinity"]
volumeMounts:
# /mnt-rro/tmpfs is not writable
- name: mnt
mountPath: /mnt-rro
readOnly: true
mountPropagation: None
recursiveReadOnly: Enabled
# /mnt-ro/tmpfs is writable
- name: mnt
mountPath: /mnt-ro
readOnly: true
# /mnt-rw/tmpfs is writable
- name: mnt
mountPath: /mnt-rw
當 kubelet 和 kube-apiserver 識別出此屬性時,.status.containerStatuses[].volumeMounts[].recursiveReadOnly
欄位會設定為 Enabled
或 Disabled
。
實作
已知以下容器執行階段支援遞迴唯讀掛載。
CRI 層級
- containerd,自 v2.0 起
- CRI-O,自 v1.30 起
OCI 層級
下一步
遵循使用 永久磁碟區部署 WordPress 和 MySQL 的範例。
此頁面上的項目參照提供 Kubernetes 所需功能的協力廠商產品或專案。Kubernetes 專案作者不對這些協力廠商產品或專案負責。如需更多詳細資訊,請參閱 CNCF 網站指南。
在提出新增額外協力廠商連結的變更之前,您應該閱讀內容指南。