容器中的磁碟檔案是暫時性的,這對於在容器中執行的重要應用程式造成了一些問題。其中一個問題發生在容器崩潰或停止時。容器狀態未儲存,因此在容器生命週期期間建立或修改的所有檔案都會遺失。在崩潰期間,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 [穩定]

啟用 azureFileCSIMigration 功能後,所有外掛程式操作都會從現有的 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 為鍵的路徑衍生而來。

downwardAPI

downwardAPI 磁碟區使 downward API 資料可供應用程式使用。在磁碟區中,您可以找到以純文字格式公開為唯讀檔案的資料。

請參閱透過檔案向容器公開 Pod 資訊以了解更多資訊。

emptyDir

對於定義 emptyDir 磁碟區的 Pod,磁碟區會在 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 來自多路徑連線。

請參閱光纖通道範例以了解更多詳細資訊。

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 使用。

以下是 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 的一些用途包括

  • 執行需要存取節點級系統元件的容器(例如將系統日誌傳輸到中央位置的容器,使用 /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 節點) 給定路徑上必須存在區塊裝置

在底層主機上建立的某些檔案或目錄可能只能由 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 物件的策略。可能的值為:AlwaysNeverIfNotPresent。如果指定 :latest 標籤,則預設為 Always,否則預設為 IfNotPresent

請參閱在 Pod 中使用映像磁碟區範例,以取得有關如何使用磁碟區來源的更多詳細資訊。

iscsi

iscsi 磁碟區允許將現有的 iSCSI (IP 上的 SCSI) 磁碟區掛載到您的 Pod 中。與 Pod 移除時會清除的 emptyDir 不同,iscsi 磁碟區的內容會被保留,並且磁碟區僅被解除掛載。這表示 iscsi 磁碟區可以預先填入資料,並且可以在 pod 之間共用該資料。

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 反親和性)一起評估。

可以單獨執行外部靜態佈建器,以改進本機磁碟區生命週期的管理。請注意,此佈建器尚不支援動態佈建。有關如何執行外部本機佈建器的範例,請參閱本機磁碟區佈建器使用者指南

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 範例,以取得使用 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>"

如需更多詳細資訊,請參閱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 支援的檔案系統)支援,因此它們永遠不會寫入非揮發性儲存裝置。

如需更多詳細資訊,請參閱設定 Secret

vsphereVolume (已棄用)

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 版本的說明文件。

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 目錄名稱。subPathsubPathExpr 屬性是互斥的。

在此範例中,Pod 使用 subPathExprhostPath 磁碟區 /var/log/pods 中建立目錄 pod1hostPath 磁碟區從 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)的檔案系統的媒介決定。emptyDirhostPath 磁碟區可以消耗多少空間沒有限制,並且容器之間或 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 叢集上部署了 CSI 相容的磁碟區驅動程式,使用者就可以使用 csi 磁碟區類型來連接或掛載 CSI 驅動程式公開的磁碟區。

csi 磁碟區可以在 Pod 中以三種不同的方式使用

以下欄位可供儲存管理員用於組態 CSI 持久磁碟區

  • driver:一個字串值,指定要使用的磁碟區驅動程式的名稱。此值必須與 CSI 驅動程式在 CSI 規格中定義的 GetPluginInfoResponse 中傳回的值相對應。Kubernetes 使用它來識別要呼叫哪個 CSI 驅動程式,CSI 驅動程式元件使用它來識別哪些 PV 物件屬於 CSI 驅動程式。
  • volumeHandle:一個字串值,可唯一識別磁碟區。此值必須與 CSI 驅動程式在 CreateVolumeResponsevolume.id 欄位中傳回的值相對應,如 CSI 規範中所定義。當參照磁碟區時,此值會以 volume_id 形式傳遞至 CSI 磁碟區驅動程式的所有呼叫。
  • readOnly:一個選用的布林值,指示磁碟區是否要以唯讀方式「ControllerPublished」(掛接)。預設值為 false。此值透過 ControllerPublishVolumeRequest 中的 readonly 欄位傳遞至 CSI 驅動程式。
  • fsType:如果 PV 的 VolumeModeFilesystem,則可以使用此欄位指定應該用於掛載磁碟區的檔案系統。如果磁碟區尚未格式化且支援格式化,則此值將用於格式化磁碟區。此值會透過 ControllerPublishVolumeRequestNodeStageVolumeRequestNodePublishVolumeRequestVolumeCapability 欄位傳遞至 CSI 驅動程式。
  • volumeAttributes:一個字串到字串的映射,用於指定磁碟區的靜態屬性。此映射必須與 CSI 驅動程式在 CreateVolumeResponsevolume.attributes 欄位中傳回的映射相對應,如 CSI 規範中所定義。此映射會透過 ControllerPublishVolumeRequestNodeStageVolumeRequestNodePublishVolumeRequest 中的 volume_context 欄位傳遞至 CSI 驅動程式。
  • controllerPublishSecretRef:對 secret 物件的參照,其中包含要傳遞至 CSI 驅動程式的敏感資訊,以完成 CSI ControllerPublishVolumeControllerUnpublishVolume 呼叫。此欄位為選用欄位,如果不需要 secret,則可以為空。如果 Secret 包含多個 secret,則會傳遞所有 secret。
  • nodeExpandSecretRef:對 secret 的參照,其中包含要傳遞至 CSI 驅動程式的敏感資訊,以完成 CSI NodeExpandVolume 呼叫。此欄位為選用欄位,如果不需要 secret,則可以為空。如果物件包含多個 secret,則會傳遞所有 secret。當您為節點啟動的磁碟區擴充功能設定 secret 資料時,kubelet 會透過 NodeExpandVolume() 呼叫將該資料傳遞至 CSI 驅動程式。所有受支援的 Kubernetes 版本都提供 nodeExpandSecretRef 欄位,並且預設情況下可用。v1.25 之前的 Kubernetes 版本不包含此支援。
  • 為每個 kube-apiserver 和每個節點上的 kubelet 啟用名為 CSINodeExpandSecret功能閘道。由於 Kubernetes 1.27 版起,此功能已預設啟用,因此無需明確啟用功能閘道。您也必須使用在節點啟動的儲存大小調整操作期間支援或需要 secret 資料的 CSI 驅動程式。
  • nodePublishSecretRef:對 secret 物件的參照,其中包含要傳遞至 CSI 驅動程式的敏感資訊,以完成 CSI NodePublishVolume 呼叫。此欄位為選用欄位,如果不需要 secret,則可以為空。如果 secret 物件包含多個 secret,則會傳遞所有 secret。
  • nodeStageSecretRef:對 secret 物件的參照,其中包含要傳遞至 CSI 驅動程式的敏感資訊,以完成 CSI NodeStageVolume 呼叫。此欄位為選用欄位,如果不需要 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(參照樹狀結構內外掛程式)進行任何組態變更。

支援的操作和功能包括:佈建/刪除、連接/中斷連接、掛載/解除掛載和調整磁碟區大小。

支援 CSIMigration 且具有對應 CSI 驅動程式實作的樹狀結構內外掛程式列在 磁碟區類型中。

以下樹狀結構內外掛程式支援 Windows 節點上的永久儲存

flexVolume(已棄用)

功能狀態: Kubernetes v1.23 [已棄用]

FlexVolume 是一個樹狀結構外的外掛程式介面,它使用基於 exec 的模型來與儲存驅動程式介接。FlexVolume 驅動程式二進位檔必須安裝在每個節點以及某些情況下的控制平面節點上的預定義磁碟區外掛程式路徑中。

Pod 透過 flexVolume 樹狀結構內磁碟區外掛程式與 FlexVolume 驅動程式互動。如需更多詳細資訊,請參閱 FlexVolume README 文件。

以下 FlexVolume 外掛程式(以 PowerShell 指令碼的形式部署在主機上)支援 Windows 節點

掛載傳播

掛載傳播允許將容器掛載的磁碟區共用給同一個 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 掛載傳播

唯讀掛載

可以透過將 .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 欄位會設定為 EnabledDisabled

實作

已知以下容器執行階段支援遞迴唯讀掛載。

CRI 層級

OCI 層級

  • runc,自 v1.1 起
  • crun,自 v1.8.6 起

下一步

遵循使用 永久磁碟區部署 WordPress 和 MySQL 的範例。

此頁面上的項目參照提供 Kubernetes 所需功能的協力廠商產品或專案。Kubernetes 專案作者不對這些協力廠商產品或專案負責。如需更多詳細資訊,請參閱 CNCF 網站指南

在提出新增額外協力廠商連結的變更之前,您應該閱讀內容指南

上次修改時間:2024 年 11 月 23 日下午 2:59 PST:Fix sample CEL expression in volumes.md (38e7774e77)