Kubernetes 卷

2022-05-07 10:45 更新

Container 中的文件在磁盤上是臨時(shí)存放的,這給 Container 中運(yùn)行的較重要的應(yīng)用程序帶來一些問題。 問題之一是當(dāng)容器崩潰時(shí)文件丟失。 kubelet 會(huì)重新啟動(dòng)容器,但容器會(huì)以干凈的狀態(tài)重啟。 第二個(gè)問題會(huì)在同一 ?Pod ?中運(yùn)行多個(gè)容器并共享文件時(shí)出現(xiàn)。 Kubernetes 卷(Volume) 這一抽象概念能夠解決這兩個(gè)問題。

背景 

Docker 也有 卷(Volume) 的概念,但對(duì)它只有少量且松散的管理。 Docker 卷是磁盤上或者另外一個(gè)容器內(nèi)的一個(gè)目錄。 Docker 提供卷驅(qū)動(dòng)程序,但是其功能非常有限。

Kubernetes 支持很多類型的卷。 Pod 可以同時(shí)使用任意數(shù)目的卷類型。 臨時(shí)卷類型的生命周期與 Pod 相同,但持久卷可以比 Pod 的存活期長(zhǎng)。 當(dāng) Pod 不再存在時(shí),Kubernetes 也會(huì)銷毀臨時(shí)卷;不過 Kubernetes 不會(huì)銷毀持久卷。 對(duì)于給定 Pod 中任何類型的卷,在容器重啟期間數(shù)據(jù)都不會(huì)丟失。

卷的核心是一個(gè)目錄,其中可能存有數(shù)據(jù),Pod 中的容器可以訪問該目錄中的數(shù)據(jù)。 所采用的特定的卷類型將決定該目錄如何形成的、使用何種介質(zhì)保存數(shù)據(jù)以及目錄中存放的內(nèi)容。

使用卷時(shí), 在 ?.spec.volumes? 字段中設(shè)置為 Pod 提供的卷,并在 ?.spec.containers[*].volumeMounts? 字段中聲明卷在容器中的掛載位置。 容器中的進(jìn)程看到的文件系統(tǒng)視圖是由它們的 容器鏡像 的初始內(nèi)容以及掛載在容器中的卷(如果定義了的話)所組成的。 其中根文件系統(tǒng)同容器鏡像的內(nèi)容相吻合。 任何在該文件系統(tǒng)下的寫入操作,如果被允許的話,都會(huì)影響接下來容器中進(jìn)程訪問文件系統(tǒng)時(shí)所看到的內(nèi)容。

卷掛載在鏡像中的指定路徑下。 Pod 配置中的每個(gè)容器必須獨(dú)立指定各個(gè)卷的掛載位置。

卷不能掛載到其他卷之上(不過存在一種使用 subPath 的相關(guān)機(jī)制),也不能與其他卷有硬鏈接。

卷類型 

Kubernetes 支持下列類型的卷:

awsElasticBlockStore

?awsElasticBlockStore ?卷將 Amazon Web服務(wù)(AWS)EBS 卷 掛載到你的 Pod 中。與 ?emptyDir ?在 Pod 被刪除時(shí)也被刪除不同,EBS 卷的內(nèi)容在刪除 Pod 時(shí)會(huì)被保留,卷只是被卸載掉了。 這意味著 EBS 卷可以預(yù)先填充數(shù)據(jù),并且該數(shù)據(jù)可以在 Pod 之間共享。

你在使用 EBS 卷之前必須使用 ?aws ec2 create-volume? 命令或者 AWS API 創(chuàng)建該卷。

使用 ?awsElasticBlockStore ?卷時(shí)有一些限制:

  • Pod 運(yùn)行所在的節(jié)點(diǎn)必須是 AWS EC2 實(shí)例。
  • 這些實(shí)例需要與 EBS 卷在相同的地域(Region)和可用區(qū)(Availability-Zone)。
  • EBS 卷只支持被掛載到單個(gè) EC2 實(shí)例上。

創(chuàng)建 EBS 卷

在將 EBS 卷用到 Pod 上之前,你首先要?jiǎng)?chuàng)建它。

aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2

確保該區(qū)域與你的群集所在的區(qū)域相匹配。還要檢查卷的大小和 EBS 卷類型都適合你的用途。

AWS EBS 配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-ebs
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-ebs
      name: test-volume
  volumes:
  - name: test-volume
    # 此 AWS EBS 卷必須已經(jīng)存在
    awsElasticBlockStore:
      volumeID: "<volume-id>"
      fsType: ext4

如果 EBS 卷是分區(qū)的,你可以提供可選的字段 ?partition: "<partition number>"? 來指定要掛載到哪個(gè)分區(qū)上。

AWS EBS CSI 卷遷移

FEATURE STATE: Kubernetes v1.17 [beta]

如果啟用了對(duì) ?awsElasticBlockStore ?的 ?CSIMigration ?特性支持,所有插件操作都不再指向樹內(nèi)插件(In-Tree Plugin),轉(zhuǎn)而指向 ?ebs.csi.aws.com? 容器存儲(chǔ)接口(Container Storage Interface,CSI)驅(qū)動(dòng)。 為了使用此特性,必須在集群中安裝  AWS EBS CSI 驅(qū)動(dòng), 并確保 ?CSIMigration ?和 ?CSIMigrationAWS ?Beta 功能特性被啟用。

AWS EBS CSI 遷移結(jié)束

FEATURE STATE: Kubernetes v1.17 [alpha]

要禁止控制器管理器和 kubelet 加載 ?awsElasticBlockStore ?存儲(chǔ)插件, 請(qǐng)將 ?InTreePluginAWSUnregister ?標(biāo)志設(shè)置為 ?true?。

azureDisk

?azureDisk ?卷類型用來在 Pod 上掛載 Microsoft Azure 數(shù)據(jù)盤(Data Disk) 。 若需了解更多詳情,請(qǐng)參考 azureDisk 卷插件。

azureDisk 的 CSI 遷移 

FEATURE STATE: Kubernetes v1.19 [beta]

啟用 ??azureDisk ??的 ??CSIMigration ??功能后,所有插件操作從現(xiàn)有的樹內(nèi)插件重定向到 ?disk.csi.azure.com? 容器存儲(chǔ)接口(CSI)驅(qū)動(dòng)程序。 為了使用此功能,必須在集群中安裝 ?Azure 磁盤 CSI 驅(qū)動(dòng)?程序, 并且 ?CSIMigration ?和 ?CSIMigrationAzureDisk ?功能必須被啟用。

azureDisk CSI 遷移完成

FEATURE STATE: Kubernetes v1.21 [alpha]

要禁止控制器管理器和 kubelet 加載 ?azureDisk ?存儲(chǔ)插件, 請(qǐng)將 ?InTreePluginAzureDiskUnregister ?標(biāo)志設(shè)置為 ?true?。

azureFile

?azureFile ?卷類型用來在 Pod 上掛載 Microsoft Azure 文件卷(File Volume)(SMB 2.1 和 3.0)。 更多詳情請(qǐng)參考 azureFile 卷插件

azureFile CSI 遷移 

FEATURE STATE: Kubernetes v1.21 [beta]

啟用 ?azureFile ?的 ?CSIMigration ?功能后,所有插件操作將從現(xiàn)有的樹內(nèi)插件重定向到 ?file.csi.azure.com? 容器存儲(chǔ)接口(CSI)驅(qū)動(dòng)程序。要使用此功能,必須在集群中安裝 Azure 文件 CSI 驅(qū)動(dòng)程序, 并且 ?CSIMigration ?和 ?CSIMigrationAzureFile ?特性門控 必須被啟用。

Azure 文件 CSI 驅(qū)動(dòng)尚不支持為同一卷設(shè)置不同的 fsgroup。 如果 AzureFile CSI 遷移被啟用,用不同的 fsgroup 來使用同一卷也是不被支持的。

azureDisk CSI 遷移完成

FEATURE STATE: Kubernetes v1.21 [alpha]

要禁止控制器管理器和 kubelet 加載 ?azureDisk ?存儲(chǔ)插件, 請(qǐng)將 ?InTreePluginAzureDiskUnregister ?標(biāo)志設(shè)置為 ?true?。

cephfs

?cephfs ?卷允許你將現(xiàn)存的 CephFS 卷掛載到 Pod 中。 不像 ?emptyDir ?那樣會(huì)在 Pod 被刪除的同時(shí)也會(huì)被刪除,?cephfs ?卷的內(nèi)容在 Pod 被刪除時(shí)會(huì)被保留,只是卷被卸載了。 這意味著 ?cephfs ?卷可以被預(yù)先填充數(shù)據(jù),且這些數(shù)據(jù)可以在 Pod 之間共享。同一 ?cephfs ?卷可同時(shí)被多個(gè)寫者掛載。

在使用 Ceph 卷之前,你的 Ceph 服務(wù)器必須已經(jīng)運(yùn)行并將要使用的 share 導(dǎo)出(exported)。

更多信息請(qǐng)參考 CephFS 示例。

cinder

Kubernetes 必須配置了 OpenStack Cloud Provider。

?cinder ?卷類型用于將 OpenStack Cinder 卷掛載到 Pod 中。

Cinder 卷示例配置

apiVersion: v1
kind: Pod
metadata:
  name: test-cinder
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-cinder-container
    volumeMounts:
    - mountPath: /test-cinder
      name: test-volume
  volumes:
  - name: test-volume
    # 此 OpenStack 卷必須已經(jīng)存在
    cinder:
      volumeID: "<volume-id>"
      fsType: ext4

OpenStack CSI 遷移

FEATURE STATE: Kubernetes v1.21 [beta]

Cinder 的 ?CSIMigration ?功能在 Kubernetes 1.21 版本中是默認(rèn)被啟用的。 此特性會(huì)將插件的所有操作從現(xiàn)有的樹內(nèi)插件重定向到 ?cinder.csi.openstack.org? 容器存儲(chǔ)接口(CSI)驅(qū)動(dòng)程序。 為了使用此功能,必須在集群中安裝 OpenStack Cinder CSI 驅(qū)動(dòng)程序, 你可以通過設(shè)置 ?CSIMigrationOpenStack ?特性門控 為 ?false ?來禁止 Cinder CSI 遷移。 如果你禁用了 ?CSIMigrationOpenStack ?功能特性,則樹內(nèi)的 Cinder 卷插件 會(huì)負(fù)責(zé) Cinder 卷存儲(chǔ)管理的方方面面。

configMap

?configMap ?卷提供了向 Pod 注入配置數(shù)據(jù)的方法。 ConfigMap 對(duì)象中存儲(chǔ)的數(shù)據(jù)可以被 ?configMap ?類型的卷引用,然后被 Pod 中運(yùn)行的容器化應(yīng)用使用。

引用 configMap 對(duì)象時(shí),你可以在 volume 中通過它的名稱來引用。 你可以自定義 ConfigMap 中特定條目所要使用的路徑。 下面的配置顯示了如何將名為 ?log-config? 的 ConfigMap 掛載到名為 ?configmap-pod? 的 Pod 中:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox:1.28
      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 以卷的形式掛載,并且存儲(chǔ)在 ?log_level ?條目中的所有內(nèi)容都被掛載到 Pod 的 ?/etc/config/log_level? 路徑下。 請(qǐng)注意,這個(gè)路徑來源于卷的 ?mountPath ?和 ?log_level ?鍵對(duì)應(yīng)的 ?path?。

  • 在使用 ConfigMap 之前你首先要?jiǎng)?chuàng)建它。
  • 容器以 subPath 卷掛載方式使用 ConfigMap 時(shí),將無法接收 ConfigMap 的更新。
  • 文本數(shù)據(jù)掛載成文件時(shí)采用 UTF-8 字符編碼。如果使用其他字符編碼形式,可使用 ?binaryData ?字段。

downwardAPI

?downwardAPI ?卷用于使 downward API 數(shù)據(jù)對(duì)應(yīng)用程序可用。 這種卷類型掛載一個(gè)目錄并在純文本文件中寫入所請(qǐng)求的數(shù)據(jù)。

容器以 subPath 卷掛載方式使用 downwardAPI 時(shí),將不能接收到它的更新。

emptyDir

當(dāng) Pod 分派到某個(gè) Node 上時(shí),?emptyDir ?卷會(huì)被創(chuàng)建,并且在 Pod 在該節(jié)點(diǎn)上運(yùn)行期間,卷一直存在。 就像其名稱表示的那樣,卷最初是空的。 盡管 Pod 中的容器掛載 ?emptyDir ?卷的路徑可能相同也可能不同,這些容器都可以讀寫 ?emptyDir ?卷中相同的文件。 當(dāng) Pod 因?yàn)槟承┰虮粡墓?jié)點(diǎn)上刪除時(shí),?emptyDir ?卷中的數(shù)據(jù)也會(huì)被永久刪除。

容器崩潰并不會(huì)導(dǎo)致 Pod 被從節(jié)點(diǎn)上移除,因此容器崩潰期間 ?emptyDir ?卷中的數(shù)據(jù)是安全的。

?emptyDir ?的一些用途:

  • 緩存空間,例如基于磁盤的歸并排序。
  • 為耗時(shí)較長(zhǎng)的計(jì)算任務(wù)提供檢查點(diǎn),以便任務(wù)能方便地從崩潰前狀態(tài)恢復(fù)執(zhí)行。
  • 在 Web 服務(wù)器容器服務(wù)數(shù)據(jù)時(shí),保存內(nèi)容管理器容器獲取的文件。

取決于你的環(huán)境,?emptyDir ?卷存儲(chǔ)在該節(jié)點(diǎn)所使用的介質(zhì)上;這里的介質(zhì)可以是磁盤或 SSD 或網(wǎng)絡(luò)存儲(chǔ)。但是,你可以將 ?emptyDir.medium? 字段設(shè)置為 ?"Memory"?,以告訴 Kubernetes 為你掛載 tmpfs(基于 RAM 的文件系統(tǒng))。 雖然 tmpfs 速度非???,但是要注意它與磁盤不同。 tmpfs 在節(jié)點(diǎn)重啟時(shí)會(huì)被清除,并且你所寫入的所有文件都會(huì)計(jì)入容?的內(nèi)存消耗,受容?內(nèi)存限制約束。

當(dāng)啟用 ?SizeMemoryBackedVolumes ?特性門控 時(shí),你可以為基于內(nèi)存提供的卷指定大小。 如果未指定大小,則基于內(nèi)存的卷的大小為 Linux 主機(jī)上內(nèi)存的 50%。

emptyDir 配置示例 

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

fc (光纖通道)

?fc ?卷類型允許將現(xiàn)有的光纖通道塊存儲(chǔ)卷掛載到 Pod 中。 可以使用卷配置中的參數(shù) ?targetWWNs ?來指定單個(gè)或多個(gè)目標(biāo) WWN(World Wide Names)。 如果指定了多個(gè) WWN,targetWWNs 期望這些 WWN 來自多路徑連接。

你必須配置 FC SAN Zoning,以便預(yù)先向目標(biāo) WWN 分配和屏蔽這些 LUN(卷),這樣 Kubernetes 主機(jī)才可以訪問它們。

更多詳情請(qǐng)參考 FC 示例

flocker (已棄用)

Flocker 是一個(gè)開源的、集群化的容?數(shù)據(jù)卷管理?。 Flocker 提供了由各種存儲(chǔ)后端所支持的數(shù)據(jù)卷的管理和編排。

使用 ?flocker ?卷可以將一個(gè) Flocker 數(shù)據(jù)集掛載到 Pod 中。 如果數(shù)據(jù)集在 Flocker 中不存在,則需要首先使用 Flocker CLI 或 Flocker API 創(chuàng)建數(shù)據(jù)集。 如果數(shù)據(jù)集已經(jīng)存在,那么 Flocker 將把它重新附加到 Pod 被調(diào)度的節(jié)點(diǎn)。 這意味著數(shù)據(jù)可以根據(jù)需要在 Pod 之間共享。

在使用 Flocker 之前你必須先安裝運(yùn)行自己的 Flocker。

更多詳情請(qǐng)參考 Flocker 示例。

gcePersistentDisk

?gcePersistentDisk ?卷能將谷歌計(jì)算引擎 (GCE) 持久盤(PD) 掛載到你的 Pod 中。 不像 ?emptyDir ?那樣會(huì)在 Pod 被刪除的同時(shí)也會(huì)被刪除,持久盤卷的內(nèi)容在刪除 Pod 時(shí)會(huì)被保留,卷只是被卸載了。 這意味著持久盤卷可以被預(yù)先填充數(shù)據(jù),并且這些數(shù)據(jù)可以在 Pod 之間共享。

在使用 PD 前,你必須使用 ?gcloud ?或者 GCE API 或 UI 創(chuàng)建它。

使用 ?gcePersistentDisk ?時(shí)有一些限制:

  • 運(yùn)行 Pod 的節(jié)點(diǎn)必須是 GCE VM
  • 這些 VM 必須和持久盤位于相同的 GCE 項(xiàng)目和區(qū)域(zone)

GCE PD 的一個(gè)特點(diǎn)是它們可以同時(shí)被多個(gè)消費(fèi)者以只讀方式掛載。 這意味著你可以用數(shù)據(jù)集預(yù)先填充 PD,然后根據(jù)需要并行地在盡可能多的 Pod 中提供該數(shù)據(jù)集。 不幸的是,PD 只能由單個(gè)使用者以讀寫模式掛載 —— 即不允許同時(shí)寫入。

在由 ReplicationController 所管理的 Pod 上使用 GCE PD 將會(huì)失敗,除非 PD 是只讀模式或者副本的數(shù)量是 0 或 1。

創(chuàng)建 GCE 持久盤(PD) 

在 Pod 中使用 GCE 持久盤之前,你首先要?jiǎng)?chuàng)建它。

gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk

GCE 持久盤配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    # 此 GCE PD 必須已經(jīng)存在
    gcePersistentDisk:
      pdName: my-data-disk
      fsType: ext4

區(qū)域持久盤 

區(qū)域持久盤 功能允許你創(chuàng)建能在同一區(qū)域的兩個(gè)可用區(qū)中使用的持久盤。 要使用這個(gè)功能,必須以持久卷(PersistentVolume)的方式提供卷;直接從 Pod 引用這種卷是不可以的。

手動(dòng)供應(yīng)基于區(qū)域 PD 的 PersistentVolume

使用為 GCE PD 定義的存儲(chǔ)類 可以實(shí)現(xiàn)動(dòng)態(tài)供應(yīng)。在創(chuàng)建 PersistentVolume 之前,你首先要?jiǎng)?chuàng)建 PD。

gcloud beta compute disks create --size=500GB my-data-disk
    --region us-central1
    --replica-zones us-central1-a,us-central1-b

PersistentVolume 示例:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: test-volume
  labels:
    failure-domain.beta.kubernetes.io/zone: us-central1-a__us-central1-b
spec:
  capacity:
    storage: 400Gi
  accessModes:
  - ReadWriteOnce
  gcePersistentDisk:
    pdName: my-data-disk
    fsType: ext4
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        # failure-domain.beta.kubernetes.io/zone 應(yīng)在 1.21 之前使用
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - us-central1-a
          - us-central1-b

GCE CSI 遷移 

FEATURE STATE: Kubernetes v1.17 [beta]

啟用 GCE PD 的 ?CSIMigration ?功能后,所有插件操作將從現(xiàn)有的樹內(nèi)插件重定向到 ?pd.csi.storage.gke.io? 容器存儲(chǔ)接口( CSI )驅(qū)動(dòng)程序。 為了使用此功能,必須在集群中上安裝 GCE PD CSI驅(qū)動(dòng)程序, 并且 ?CSIMigration ?和 ?CSIMigrationGCE ?Beta 功能必須被啟用。

GCE CSI 遷移完成

FEATURE STATE: Kubernetes v1.21 [alpha]

要禁止控制器管理器和 kubelet 加載 ?gcePersistentDisk ?存儲(chǔ)插件,請(qǐng)將 ?InTreePluginGCEUnregister ?標(biāo)志設(shè)置為 ?true?。

gitRepo (已棄用) 

?gitRepo ?卷類型已經(jīng)被廢棄。如果需要在容?中提供 git 倉庫,請(qǐng)將一個(gè) EmptyDir 卷掛載到 InitContainer 中,使用 git 命令完成倉庫的克隆操作,然后將 EmptyDir 卷掛載到 Pod 的容器中。

?gitRepo ?卷是一個(gè)卷插件的例子。 該查卷掛載一個(gè)空目錄,并將一個(gè) Git 代碼倉庫克隆到這個(gè)目錄中供 Pod 使用。

下面給出一個(gè) ?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

?glusterfs ?卷能將 Glusterfs (一個(gè)開源的網(wǎng)絡(luò)文件系統(tǒng)) 掛載到你的 Pod 中。不像 ?emptyDir ?那樣會(huì)在刪除 Pod 的同時(shí)也會(huì)被刪除,?glusterfs ?卷的內(nèi)容在刪除 Pod 時(shí)會(huì)被保存,卷只是被卸載。 這意味著 ?glusterfs ?卷可以被預(yù)先填充數(shù)據(jù),并且這些數(shù)據(jù)可以在 Pod 之間共享。 GlusterFS 可以被多個(gè)寫者同時(shí)掛載。

在使用前你必須先安裝運(yùn)行自己的 GlusterFS。

更多詳情請(qǐng)參考 GlusterFS 示例

hostPath

HostPath 卷存在許多安全風(fēng)險(xiǎn),最佳做法是盡可能避免使用 HostPath。 當(dāng)必須使用 HostPath 卷時(shí),它的范圍應(yīng)僅限于所需的文件或目錄,并以只讀方式掛載。
如果通過 AdmissionPolicy 限制 HostPath 對(duì)特定目錄的訪問,則必須要求 ?volumeMounts ?使用 ?readOnly ?掛載以使策略生效。

?hostPath ?卷能將主機(jī)節(jié)點(diǎn)文件系統(tǒng)上的文件或目錄掛載到你的 Pod 中。 雖然這不是大多數(shù) Pod 需要的,但是它為一些應(yīng)用程序提供了強(qiáng)大的逃生艙。

例如,?hostPath ?的一些用法有:

  • 運(yùn)行一個(gè)需要訪問 Docker 內(nèi)部機(jī)制的容器;可使用 ?hostPath ?掛載 ?/var/lib/docker? 路徑。
  • 在容器中運(yùn)行 cAdvisor 時(shí),以 ?hostPath ?方式掛載 ?/sys?。
  • 允許 Pod 指定給定的 ?hostPath ?在運(yùn)行 Pod 之前是否應(yīng)該存在,是否應(yīng)該創(chuàng)建以及應(yīng)該以什么方式存在。

除了必需的 ?path ?屬性之外,用戶可以選擇性地為 ?hostPath ?卷指定 ?type?。

支持的 ?type ?值如下:

取值 行為
空字符串(默認(rèn))用于向后兼容,這意味著在安裝 hostPath 卷之前不會(huì)執(zhí)行任何檢查。
DirectoryOrCreate 如果在給定路徑上什么都不存在,那么將根據(jù)需要?jiǎng)?chuàng)建空目錄,權(quán)限設(shè)置為 0755,具有與 kubelet 相同的組和屬主信息。
Directory 在給定路徑上必須存在的目錄。
FileOrCreate 如果在給定路徑上什么都不存在,那么將在那里根據(jù)需要?jiǎng)?chuàng)建空文件,權(quán)限設(shè)置為 0644,具有與 kubelet 相同的組和所有權(quán)。
File 在給定路徑上必須存在的文件。
Socket 在給定路徑上必須存在的 UNIX 套接字。
CharDevice 在給定路徑上必須存在的字符設(shè)備。
BlockDevice 在給定路徑上必須存在的塊設(shè)備。

當(dāng)使用這種類型的卷時(shí)要小心,因?yàn)椋?/p>

  • HostPath 卷可能會(huì)暴露特權(quán)系統(tǒng)憑據(jù)(例如 Kubelet)或特權(quán) API(例如容器運(yùn)行時(shí)套接字),可用于容器逃逸或攻擊集群的其他部分。
  • 具有相同配置(例如基于同一 PodTemplate 創(chuàng)建)的多個(gè) Pod 會(huì)由于節(jié)點(diǎn)上文件的不同而在不同節(jié)點(diǎn)上有不同的行為。
  • 下層主機(jī)上創(chuàng)建的文件或目錄只能由 root 用戶寫入。你需要在 特權(quán)容器 中以 root 身份運(yùn)行進(jìn)程,或者修改主機(jī)上的文件權(quán)限以便容?能夠?qū)懭?nbsp;?hostPath ?卷。

hostPath 配置示例: 

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # 宿主上目錄位置
      path: /data
      # 此字段為可選
      type: Directory

?FileOrCreate ?模式不會(huì)負(fù)責(zé)創(chuàng)建文件的父目錄。 如果欲掛載的文件的父目錄不存在,Pod 啟動(dòng)會(huì)失敗。 為了確保這種模式能夠工作,可以嘗試把文件和它對(duì)應(yīng)的目錄分開掛載,如 FileOrCreate 配置 所示。

hostPath FileOrCreate 配置示例 

apiVersion: v1
kind: Pod
metadata:
  name: test-webserver
spec:
  containers:
  - name: test-webserver
    image: k8s.gcr.io/test-webserver:latest
    volumeMounts:
    - mountPath: /var/local/aaa
      name: mydir
    - mountPath: /var/local/aaa/1.txt
      name: myfile
  volumes:
  - name: mydir
    hostPath:
      # 確保文件所在目錄成功創(chuàng)建。
      path: /var/local/aaa
      type: DirectoryOrCreate
  - name: myfile
    hostPath:
      path: /var/local/aaa/1.txt
      type: FileOrCreate

iscsi

?iscsi ?卷能將 iSCSI (基于 IP 的 SCSI) 卷掛載到你的 Pod 中。 不像 ?emptyDir ?那樣會(huì)在刪除 Pod 的同時(shí)也會(huì)被刪除,?iscsi ?卷的內(nèi)容在刪除 Pod 時(shí)會(huì)被保留,卷只是被卸載。 這意味著 ?iscsi ?卷可以被預(yù)先填充數(shù)據(jù),并且這些數(shù)據(jù)可以在 Pod 之間共享。

在使用 iSCSI 卷之前,你必須擁有自己的 iSCSI 服務(wù)器,并在上面創(chuàng)建卷。

iSCSI 的一個(gè)特點(diǎn)是它可以同時(shí)被多個(gè)用戶以只讀方式掛載。 這意味著你可以用數(shù)據(jù)集預(yù)先填充卷,然后根據(jù)需要在盡可能多的 Pod 上使用它。 不幸的是,iSCSI 卷只能由單個(gè)使用者以讀寫模式掛載。不允許同時(shí)寫入。

更多詳情請(qǐng)參考 iSCSI 示例。

local

?local ?卷所代表的是某個(gè)被掛載的本地存儲(chǔ)設(shè)備,例如磁盤、分區(qū)或者目錄。

?local ?卷只能用作靜態(tài)創(chuàng)建的持久卷。尚不支持動(dòng)態(tài)配置。

與 ?hostPath ?卷相比,?local ?卷能夠以持久和可移植的方式使用,而無需手動(dòng)將 Pod 調(diào)度到節(jié)點(diǎn)。系統(tǒng)通過查看 PersistentVolume 的節(jié)點(diǎn)親和性配置,就能了解卷的節(jié)點(diǎn)約束。

然而,?local ?卷仍然取決于底層節(jié)點(diǎn)的可用性,并不適合所有應(yīng)用程序。 如果節(jié)點(diǎn)變得不健康,那么 ?local ?卷也將變得不可被 Pod 訪問。使用它的 Pod 將不能運(yùn)行。 使用 ?local ?卷的應(yīng)用程序必須能夠容忍這種可用性的降低,以及因底層磁盤的耐用性特征而帶來的潛在的數(shù)據(jù)丟失風(fēng)險(xiǎn)。

下面是一個(gè)使用 ?local ?卷和 ?nodeAffinity ?的持久卷示例:

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 ?卷時(shí),你需要設(shè)置 PersistentVolume 對(duì)象的 ?nodeAffinity ?字段。 Kubernetes 調(diào)度?使用 PersistentVolume 的 ?nodeAffinity ?信息來將使用 ?local ?卷的 Pod 調(diào)度到正確的節(jié)點(diǎn)。

PersistentVolume 對(duì)象的 ?volumeMode ?字段可被設(shè)置為 "Block" (而不是默認(rèn)值 "Filesystem"),以將 ?local ?卷作為原始?jí)K設(shè)備暴露出來。

使用 ?local ?卷時(shí),建議創(chuàng)建一個(gè) StorageClass 并將其 ?volumeBindingMode ?設(shè)置為 ?WaitForFirstConsumer?。要了解更多詳細(xì)信息,請(qǐng)參考 local StorageClass 示例。 延遲卷綁定的操作可以確保 Kubernetes 在為 PersistentVolumeClaim 作出綁定決策時(shí),會(huì)評(píng)估 Pod 可能具有的其他節(jié)點(diǎn)約束,例如:如節(jié)點(diǎn)資源需求、節(jié)點(diǎn)選擇?、Pod親和性和 Pod 反親和性。

你可以在 Kubernetes 之外單獨(dú)運(yùn)行靜態(tài)驅(qū)動(dòng)以改進(jìn)對(duì) local 卷的生命周期管理。 請(qǐng)注意,此驅(qū)動(dòng)尚不支持動(dòng)態(tài)配置。 有關(guān)如何運(yùn)行外部 ?local ?卷驅(qū)動(dòng),請(qǐng)參考 local 卷驅(qū)動(dòng)用戶指南。

如果不使用外部靜態(tài)驅(qū)動(dòng)來管理卷的生命周期,用戶需要手動(dòng)清理和刪除 local 類型的持久卷。

nfs

?nfs ?卷能將 NFS (網(wǎng)絡(luò)文件系統(tǒng)) 掛載到你的 Pod 中。 不像 ?emptyDir ?那樣會(huì)在刪除 Pod 的同時(shí)也會(huì)被刪除,?nfs ?卷的內(nèi)容在刪除 Pod 時(shí)會(huì)被保存,卷只是被卸載。 這意味著 ?nfs ?卷可以被預(yù)先填充數(shù)據(jù),并且這些數(shù)據(jù)可以在 Pod 之間共享。

在使用 NFS 卷之前,你必須運(yùn)行自己的 NFS 服務(wù)?并將目標(biāo) share 導(dǎo)出備用。

要了解更多詳情請(qǐng)參考 NFS 示例。

persistentVolumeClaim

?persistentVolumeClaim ?卷用來將持久卷(PersistentVolume)掛載到 Pod 中。 持久卷申領(lǐng)(PersistentVolumeClaim)是用戶在不知道特定云環(huán)境細(xì)節(jié)的情況下“申領(lǐng)”持久存儲(chǔ)(例如 GCE PersistentDisk 或者 iSCSI 卷)的一種方法。

portworxVolume

?portworxVolume ?是一個(gè)可伸縮的塊存儲(chǔ)層,能夠以超融合(hyperconverged)的方式與 Kubernetes 一起運(yùn)行。 Portworx 支持對(duì)服務(wù)?上存儲(chǔ)的指紋處理、基于存儲(chǔ)能力進(jìn)行分層以及跨多個(gè)服務(wù)?整合存儲(chǔ)容量。 Portworx 可以以 in-guest 方式在虛擬機(jī)中運(yùn)行,也可以在裸金屬 Linux 節(jié)點(diǎn)上運(yùn)行。

?portworxVolume ?類型的卷可以通過 Kubernetes 動(dòng)態(tài)創(chuàng)建,也可以預(yù)先配備并在 Kubernetes Pod 內(nèi)引用。 下面是一個(gè)引用預(yù)先配備的 PortworxVolume 的示例 Pod:

apiVersion: v1
kind: Pod
metadata:
  name: test-portworx-volume-pod
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /mnt
      name: pxvol
  volumes:
  - name: pxvol
    # 此 Portworx 卷必須已經(jīng)存在
    portworxVolume:
      volumeID: "pxvol"
      fsType: "<fs-type>"

在 Pod 中使用 portworxVolume 之前,你要確保有一個(gè)名為 ?pxvol ?的 PortworxVolume 存在。

更多詳情可以參考 Portworx 卷。

projected (投射)

投射卷能將若干現(xiàn)有的卷來源映射到同一目錄上。

quobyte (已棄用)

?quobyte ?卷允許將現(xiàn)有的 Quobyte 卷掛載到你的 Pod 中。

在使用 Quobyte 卷之前,你首先要進(jìn)行安裝 Quobyte 并創(chuàng)建好卷。

Quobyte 支持容器存儲(chǔ)接口(CSI)。 推薦使用 CSI 插件以在 Kubernetes 中使用 Quobyte 卷。 Quobyte 的 GitHub 項(xiàng)目包含以 CSI 形式部署 Quobyte 的 說明 及使用示例。

rbd

?rbd ?卷允許將 Rados 塊設(shè)備卷掛載到你的 Pod 中。 不像 ?emptyDir ?那樣會(huì)在刪除 Pod 的同時(shí)也會(huì)被刪除,?rbd ?卷的內(nèi)容在刪除 Pod 時(shí)會(huì)被保存,卷只是被卸載。 這意味著 ?rbd ?卷可以被預(yù)先填充數(shù)據(jù),并且這些數(shù)據(jù)可以在 Pod 之間共享。

在使用 RBD 之前,你必須安裝運(yùn)行 Ceph。

RBD 的一個(gè)特性是它可以同時(shí)被多個(gè)用戶以只讀方式掛載。 這意味著你可以用數(shù)據(jù)集預(yù)先填充卷,然后根據(jù)需要在盡可能多的 Pod 中并行地使用卷。 不幸的是,RBD 卷只能由單個(gè)使用者以讀寫模式安裝。不允許同時(shí)寫入。

更多詳情請(qǐng)參考 RBD 示例

RBD CSI 遷移

FEATURE STATE: Kubernetes v1.23 [alpha]

啟用 RBD 的 ?CSIMigration ?功能后,所有插件操作從現(xiàn)有的樹內(nèi)插件重定向到 ?rbd.csi.ceph.com? CSI 驅(qū)動(dòng)程序。 要使用該功能,必須在集群內(nèi)安裝 Ceph CSI 驅(qū)動(dòng),并啟用 ?CSIMigration ?和 ?csiMigrationRBD ?特性門控。

作為一位管理存儲(chǔ)的 Kubernetes 集群操作者,在嘗試遷移到 RBD CSI 驅(qū)動(dòng)前,你必須完成下列先決事項(xiàng):
  • 你必須在集群中安裝 v3.5.0 或更高版本的 Ceph CSI 驅(qū)動(dòng)(?rbd.csi.ceph.com?)。
  • 因?yàn)?nbsp;?clusterID ?是 CSI 驅(qū)動(dòng)程序必需的參數(shù),而樹內(nèi)存儲(chǔ)類又將 ?monitors ?作為一個(gè)必需的參數(shù),所以 Kubernetes 存儲(chǔ)管理者需要根據(jù) ?monitors ?的哈希值(例:?#echo -n '<monitors_string>' | md5sum?)來創(chuàng)建 ?clusterID?,并保持該 ?monitors ?存在于該 ?clusterID ?的配置中。
  • 同時(shí),如果樹內(nèi)存儲(chǔ)類的 ?adminId ?的值不是 ?admin?,那么其 ?adminSecretName ?就需要被修改成 ?adminId ?參數(shù)的 base64 編碼值。

secret

?secret ?卷用來給 Pod 傳遞敏感信息,例如密碼。你可以將 Secret 存儲(chǔ)在 Kubernetes API 服務(wù)器上,然后以文件的形式掛在到 Pod 中,無需直接與 Kubernetes 耦合。 ?secret ?卷由 tmpfs(基于 RAM 的文件系統(tǒng))提供存儲(chǔ),因此它們永遠(yuǎn)不會(huì)被寫入非易失性(持久化的)存儲(chǔ)器。

使用前你必須在 Kubernetes API 中創(chuàng)建 secret。

容器以 subPath 卷掛載方式掛載 Secret 時(shí),將感知不到 Secret 的更新。

storageOS (已棄用)

?storageos ?卷允許將現(xiàn)有的 StorageOS 卷掛載到你的 Pod 中。

StorageOS 在 Kubernetes 環(huán)境中以容?的形式運(yùn)行,這使得應(yīng)用能夠從 Kubernetes 集群中的任何節(jié)點(diǎn)訪問本地的或掛接的存儲(chǔ)。為應(yīng)對(duì)節(jié)點(diǎn)失效狀況,可以復(fù)制數(shù)據(jù)。 若需提高利用率和降低成本,可以考慮瘦配置(Thin Provisioning)和數(shù)據(jù)壓縮。

作為其核心能力之一,StorageOS 為容?提供了可以通過文件系統(tǒng)訪問的塊存儲(chǔ)。

StorageOS 容器需要 64 位的 Linux,并且沒有其他的依賴關(guān)系。 StorageOS 提供免費(fèi)的開發(fā)者授權(quán)許可。

你必須在每個(gè)希望訪問 StorageOS 卷的或者將向存儲(chǔ)資源池貢獻(xiàn)存儲(chǔ)容量的節(jié)點(diǎn)上運(yùn)行 StorageOS 容器。有關(guān)安裝說明,請(qǐng)參閱 StorageOS 文檔。

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: redis
    role: master
  name: test-storageos-redis
spec:
  containers:
    - name: master
      image: kubernetes/redis:v1
      env:
        - name: MASTER
          value: "true"
      ports:
        - containerPort: 6379
      volumeMounts:
        - mountPath: /redis-master-data
          name: redis-data
  volumes:
    - name: redis-data
      storageos:
        # `redis-vol01` 卷必須在 StorageOS 中存在,并位于 `default` 名字空間內(nèi)
        volumeName: redis-vol01
        fsType: ext4

關(guān)于 StorageOS 的進(jìn)一步信息、動(dòng)態(tài)供應(yīng)和持久卷申領(lǐng)等等,請(qǐng)參考 StorageOS 示例。

vsphereVolume

你必須配置 Kubernetes 的 vSphere 云驅(qū)動(dòng)。云驅(qū)動(dòng)的配置方法請(qǐng)參考 vSphere 使用指南。

?vsphereVolume ?用來將 vSphere VMDK 卷掛載到你的 Pod 中。 在卸載卷時(shí),卷的內(nèi)容會(huì)被保留。 vSphereVolume 卷類型支持 VMFS 和 VSAN 數(shù)據(jù)倉庫。

在掛載到 Pod 之前,你必須用下列方式之一創(chuàng)建 VMDK。

創(chuàng)建 VMDK 卷 

選擇下列方式之一創(chuàng)建 VMDK。

  • 使用 vmkfstools 創(chuàng)建
  • 首先 ssh 到 ESX,然后使用下面的命令來創(chuàng)建 VMDK:

    vmkfstools -c 2G /vmfs/volumes/DatastoreName/volumes/myDisk.vmdk
    
  • 使用 vmware-vdiskmanager 創(chuàng)建
  • 使用下面的命令創(chuàng)建 VMDK:

    vmware-vdiskmanager -c -t 0 -s 40GB -a lsilogic myDisk.vmdk
    

vSphere VMDK 配置示例 

apiVersion: v1
kind: Pod
metadata:
  name: test-vmdk
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-vmdk
      name: test-volume
  volumes:
  - name: test-volume
    # 此 VMDK 卷必須已經(jīng)存在
    vsphereVolume:
      volumePath: "[DatastoreName] volumes/myDisk"
      fsType: ext4

進(jìn)一步信息可參考 vSphere 卷。

vSphere CSI 遷移 

FEATURE STATE: Kubernetes v1.19 [beta]

當(dāng) ?vsphereVolume ?的 ?CSIMigration ?特性被啟用時(shí),所有插件操作都被從樹內(nèi)插件重定向到 ?csi.vsphere.vmware.com? CSI 驅(qū)動(dòng)。 為了使用此功能特性,必須在集群中安裝 vSphere CSI 驅(qū)動(dòng),并啟用 ?CSIMigration ?和 ?CSIMigrationvSphere ?特性門控。

此特性還要求 vSphere vCenter/ESXi 的版本至少為 7.0u1,且 HW 版本至少為 VM version 15。

vSphere CSI 驅(qū)動(dòng)不支持內(nèi)置 ?vsphereVolume ?的以下 StorageClass 參數(shù):
  • ?diskformat?
  • ?hostfailurestotolerate?
  • ?forceprovisioning?
  • ?cachereservation?
  • ?diskstripes?
  • ?objectspacereservation?
  • ?iopslimit?
使用這些參數(shù)創(chuàng)建的現(xiàn)有卷將被遷移到 vSphere CSI 驅(qū)動(dòng),不過使用 vSphere CSI 驅(qū)動(dòng)所創(chuàng)建的新卷都不會(huì)理會(huì)這些參數(shù)。

vSphere CSI 遷移完成 

FEATURE STATE: Kubernetes v1.19 [beta]

為了避免控制器管理器和 kubelet 加載 ?vsphereVolume ?插件,你需要將 ?InTreePluginvSphereUnregister ?特性設(shè)置為 ?true?。你還必須在所有工作節(jié)點(diǎn)上安裝 ?csi.vsphere.vmware.com? CSI 驅(qū)動(dòng)。

Portworx CSI 遷移

FEATURE STATE: Kubernetes v1.23 [alpha]

Kubernetes 1.23 中加入了 Portworx 的 ?CSIMigration ?功能,但默認(rèn)不會(huì)啟用,因?yàn)樵摴δ苋蕴幱?nbsp;alpha 階段。 該功能會(huì)將所有的插件操作從現(xiàn)有的樹內(nèi)插件重定向到 ?pxd.portworx.com? 容器存儲(chǔ)接口(Container Storage Interface, CSI)驅(qū)動(dòng)程序。 集群中必須安裝  Portworx CSI 驅(qū)動(dòng)。 要啟用此功能,請(qǐng)?jiān)?nbsp;kube-controller-manager 和 kubelet 中設(shè)置 ?CSIMigrationPortworx=true?。

使用 subPath 

有時(shí),在單個(gè) Pod 中共享卷以供多方使用是很有用的。 ?volumeMounts.subPath? 屬性可用于指定所引用的卷內(nèi)的子路徑,而不是其根路徑。

下面例子展示了如何配置某包含 LAMP 堆棧(Linux Apache MySQL PHP)的 Pod 使用同一共享卷。 此示例中的 ?subPath ?配置不建議在生產(chǎn)環(huán)境中使用。 PHP 應(yīng)用的代碼和相關(guān)數(shù)據(jù)映射到卷的 ?html ?文件夾,MySQL 數(shù)據(jù)庫存儲(chǔ)在卷的 ?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
        

使用帶有擴(kuò)展環(huán)境變量的 subPath 

FEATURE STATE: Kubernetes v1.17 [stable]

使用 ?subPathExpr ?字段可以基于 Downward API 環(huán)境變量來構(gòu)造 ?subPath ?目錄名。 ?subPath ?和 ?subPathExpr ?屬性是互斥的。

在這個(gè)示例中,Pod 使用 ?subPathExpr ?來 hostPath 卷 ?/var/log/pods? 中創(chuàng)建目錄 ?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
      # 包裹變量名的是小括號(hào),而不是大括號(hào)
      subPathExpr: $(POD_NAME)
  restartPolicy: Never
  volumes:
  - name: workdir1
    hostPath:
      path: /var/log/pods
            

資源 

?emptyDir ?卷的存儲(chǔ)介質(zhì)(磁盤、SSD 等)是由保存 kubelet 數(shù)據(jù)的根目錄(通常是 ?/var/lib/kubelet?)的文件系統(tǒng)的介質(zhì)確定。 Kubernetes 對(duì) ?emptyDir ?卷或者 ?hostPath ?卷可以消耗的空間沒有限制,容器之間或 Pod 之間也沒有隔離。

樹外(Out-of-Tree)卷插件 

Out-of-Tree 卷插件包括 容器存儲(chǔ)接口(CSI) 和 FlexVolume(已棄用)。 它們使存儲(chǔ)供應(yīng)商能夠創(chuàng)建自定義存儲(chǔ)插件,而無需將插件源碼添加到 Kubernetes 代碼倉庫。

以前,所有卷插件(如上面列出的卷類型)都是“樹內(nèi)(In-Tree)”的。 “樹內(nèi)”插件是與 Kubernetes 的核心組件一同構(gòu)建、鏈接、編譯和交付的。 這意味著向 Kubernetes 添加新的存儲(chǔ)系統(tǒng)(卷插件)需要將代碼合并到 Kubernetes 核心代碼庫中。

CSI 和 FlexVolume 都允許獨(dú)立于 Kubernetes 代碼庫開發(fā)卷插件,并作為擴(kuò)展部署(安裝)在 Kubernetes 集群上。

對(duì)于希望創(chuàng)建樹外(Out-Of-Tree)卷插件的存儲(chǔ)供應(yīng)商,請(qǐng)參考 卷插件常見問題。

CSI

容器存儲(chǔ)接口 (CSI) 為容器編排系統(tǒng)(如 Kubernetes)定義標(biāo)準(zhǔn)接口,以將任意存儲(chǔ)系統(tǒng)暴露給它們的容器工作負(fù)載。

更多詳情請(qǐng)閱讀 CSI 設(shè)計(jì)方案。

Kubernetes v1.13 廢棄了對(duì) CSI 規(guī)范版本 0.2 和 0.3 的支持,并將在以后的版本中刪除。

CSI 驅(qū)動(dòng)可能并非兼容所有的 Kubernetes 版本。 請(qǐng)查看特定 CSI 驅(qū)動(dòng)的文檔,以了解各個(gè) Kubernetes 版本所支持的部署步驟以及兼容性列表。

一旦在 Kubernetes 集群上部署了 CSI 兼容卷驅(qū)動(dòng)程序,用戶就可以使用 ?csi ?卷類型來掛接、掛載 CSI 驅(qū)動(dòng)所提供的卷。

?csi ?卷可以在 Pod 中以三種方式使用:

  • 通過 PersistentVolumeClaim(#persistentvolumeclaim) 對(duì)象引用
  • 使用一般性的臨時(shí)卷 (Alpha 特性)
  • 使用 CSI 臨時(shí)卷, 前提是驅(qū)動(dòng)支持這種用法(Beta 特性)

存儲(chǔ)管理員可以使用以下字段來配置 CSI 持久卷:

  • ?driver?:指定要使用的卷驅(qū)動(dòng)名稱的字符串值。 這個(gè)值必須與 CSI 驅(qū)動(dòng)程序在 ?GetPluginInfoResponse ?中返回的值相對(duì)應(yīng);該接口定義在 CSI 規(guī)范中。 Kubernetes 使用所給的值來標(biāo)識(shí)要調(diào)用的 CSI 驅(qū)動(dòng)程序;CSI 驅(qū)動(dòng)程序也使用該值來辨識(shí)哪些 PV 對(duì)象屬于該 CSI 驅(qū)動(dòng)程序。
  • ?volumeHandle?:唯一標(biāo)識(shí)卷的字符串值。 該值必須與 CSI 驅(qū)動(dòng)在 ?CreateVolumeResponse ?的 ?volume_id ?字段中返回的值相對(duì)應(yīng);接口定義在 CSI 規(guī)范 中。 在所有對(duì) CSI 卷驅(qū)動(dòng)程序的調(diào)用中,引用該 CSI 卷時(shí)都使用此值作為 ?volume_id ?參數(shù)。
  • ?readOnly?:一個(gè)可選的布爾值,指示通過 ?ControllerPublished ?關(guān)聯(lián)該卷時(shí)是否設(shè)置該卷為只讀。默認(rèn)值是 false。 該值通過 ?ControllerPublishVolumeRequest ?中的 ?readonly ?字段傳遞給 CSI 驅(qū)動(dòng)。
  • ?fsType?:如果 PV 的 ?VolumeMode ?為 ?Filesystem?,那么此字段指定掛載卷時(shí)應(yīng)該使用的文件系統(tǒng)。 如果卷尚未格式化,并且支持格式化,此值將用于格式化卷。 此值可以通過 ?ControllerPublishVolumeRequest?、?NodeStageVolumeRequest ?和 ?NodePublishVolumeRequest ?的 ?VolumeCapability ?字段傳遞給 CSI 驅(qū)動(dòng)。
  • ?volumeAttributes?:一個(gè)字符串到字符串的映射表,用來設(shè)置卷的靜態(tài)屬性。 該映射必須與 CSI 驅(qū)動(dòng)程序返回的 ?CreateVolumeResponse ?中的 ?volume.attributes? 字段的映射相對(duì)應(yīng); CSI 規(guī)范 中有相應(yīng)的定義。 該映射通過?ControllerPublishVolumeRequest?、?NodeStageVolumeRequest?、和 ?NodePublishVolumeRequest ?中的 ?volume_attributes ?字段傳遞給 CSI 驅(qū)動(dòng)。
  • ?controllerPublishSecretRef?:對(duì)包含?感信息的 Secret 對(duì)象的引用; 該?感信息會(huì)被傳遞給 CSI 驅(qū)動(dòng)來完成 CSI ?ControllerPublishVolume ?和 ?ControllerUnpublishVolume ?調(diào)用。 此字段是可選的;在不需要 Secret 時(shí)可以是空的。 如果 Secret 對(duì)象包含多個(gè) Secret 條目,則所有的 Secret 條目都會(huì)被傳遞。
  • ?nodeStageSecretRef?:對(duì)包含敏感信息的 Secret 對(duì)象的引用。 該信息會(huì)傳遞給 CSI 驅(qū)動(dòng)來完成 CSI ?NodeStageVolume ?調(diào)用。 此字段是可選的,如果不需要 Secret,則可能是空的。 如果 Secret 對(duì)象包含多個(gè) Secret 條目,則傳遞所有 Secret 條目。
  • ?nodePublishSecretRef?:對(duì)包含敏感信息的 Secret 對(duì)象的引用。 該信息傳遞給 CSI 驅(qū)動(dòng)來完成 CSI ?NodePublishVolume ?調(diào)用。 此字段是可選的,如果不需要 Secret,則可能是空的。 如果 Secret 對(duì)象包含多個(gè) Secret 條目,則傳遞所有 Secret 條目。

CSI 原始?jí)K卷支持 

FEATURE STATE: Kubernetes v1.18 [stable]

具有外部 CSI 驅(qū)動(dòng)程序的供應(yīng)商能夠在 Kubernetes 工作負(fù)載中實(shí)現(xiàn)原始?jí)K卷支持。

你可以和以前一樣,安裝自己的 帶有原始?jí)K卷支持的 PV/PVC, 采用 CSI 對(duì)此過程沒有影響。

CSI 臨時(shí)卷 

FEATURE STATE: Kubernetes v1.16 [beta]

你可以直接在 Pod 規(guī)約中配置 CSI 卷。采用這種方式配置的卷都是臨時(shí)卷, 無法在 Pod 重新啟動(dòng)后繼續(xù)存在。 進(jìn)一步的信息可參閱臨時(shí)卷。

有關(guān)如何開發(fā) CSI 驅(qū)動(dòng)的更多信息,請(qǐng)參考 kubernetes-csi 文檔。

從樹內(nèi)插件遷移到 CSI 驅(qū)動(dòng)程序 

FEATURE STATE: Kubernetes v1.17 [beta]

啟用 ?CSIMigration ?功能后,針對(duì)現(xiàn)有樹內(nèi)插件的操作會(huì)被重定向到相應(yīng)的 CSI 插件(應(yīng)已安裝和配置)。 因此,操作員在過渡到取代樹內(nèi)插件的 CSI 驅(qū)動(dòng)時(shí),無需對(duì)現(xiàn)有存儲(chǔ)類、PV 或 PVC(指樹內(nèi)插件)進(jìn)行任何配置更改。

所支持的操作和功能包括:配備(Provisioning)/刪除、掛接(Attach)/解掛(Detach)、 掛載(Mount)/卸載(Unmount)和調(diào)整卷大小。

上面的卷類型節(jié)列出了支持 ?CSIMigration ?并已實(shí)現(xiàn)相應(yīng) CSI 驅(qū)動(dòng)程序的樹內(nèi)插件。

flexVolume

FEATURE STATE: Kubernetes v1.23 [deprecated]

FlexVolume 是一個(gè)使用基于 exec 的模型來與驅(qū)動(dòng)程序?qū)拥臉渫獠寮涌凇?nbsp;用戶必須在每個(gè)節(jié)點(diǎn)上的預(yù)定義卷插件路徑中安裝 FlexVolume 驅(qū)動(dòng)程序可執(zhí)行文件,在某些情況下,控制平面節(jié)點(diǎn)中也要安裝。

Pod 通過 ?flexvolume ?樹內(nèi)插件與 FlexVolume 驅(qū)動(dòng)程序交互。 更多詳情請(qǐng)參考 FlexVolume README 文檔。

FlexVolume 已棄用。推薦使用樹外 CSI 驅(qū)動(dòng)來將外部存儲(chǔ)整合進(jìn) Kubernetes。
FlexVolume 驅(qū)動(dòng)的維護(hù)者應(yīng)開發(fā)一個(gè) CSI 驅(qū)動(dòng)并幫助用戶從 FlexVolume 驅(qū)動(dòng)遷移到 CSI。 FlexVolume 用戶應(yīng)遷移工作負(fù)載以使用對(duì)等的 CSI 驅(qū)動(dòng)。

掛載卷的傳播 

掛載卷的傳播能力允許將容器安裝的卷共享到同一 Pod 中的其他容器,甚至共享到同一節(jié)點(diǎn)上的其他 Pod。

卷的掛載傳播特性由 ?Container.volumeMounts? 中的 ?mountPropagation ?字段控制。 它的值包括:

  • ?None ?- 此卷掛載將不會(huì)感知到主機(jī)后續(xù)在此卷或其任何子目錄上執(zhí)行的掛載變化。 類似的,容?所創(chuàng)建的卷掛載在主機(jī)上是不可見的。這是默認(rèn)模式。
  • 該模式等同于 Linux 內(nèi)核文檔 中描述的 ?private ?掛載傳播選項(xiàng)。
  • ?HostToContainer ?- 此卷掛載將會(huì)感知到主機(jī)后續(xù)針對(duì)此卷或其任何子目錄的掛載操作。
  • 換句話說,如果主機(jī)在此掛載卷中掛載任何內(nèi)容,容器將能看到它被掛載在那里。 類似的,配置了 ?Bidirectional ?掛載傳播選項(xiàng)的 Pod 如果在同一卷上掛載了內(nèi)容,掛載傳播設(shè)置為 ?HostToContainer ?的容?都將能看到這一變化。 該模式等同于 Linux 內(nèi)核文檔 中描述的 rslave 掛載傳播選項(xiàng)。
  • ?Bidirectional ?- 這種卷掛載和 ?HostToContainer ?掛載表現(xiàn)相同。 另外,容?創(chuàng)建的卷掛載將被傳播回至主機(jī)和使用同一卷的所有 Pod 的所有容?。
  • 該模式等同于 Linux 內(nèi)核文檔 中描述的 ?rshared ?掛載傳播選項(xiàng)。

?Bidirectional ?形式的掛載傳播可能比較危險(xiǎn)。 它可以破壞主機(jī)操作系統(tǒng),因此它只被允許在特權(quán)容器中使用。 強(qiáng)烈建議你熟悉 Linux 內(nèi)核行為。 此外,由 Pod 中的容器創(chuàng)建的任何卷掛載必須在終止時(shí)由容器銷毀(卸載)。

配置 

在某些部署環(huán)境中,掛載傳播正常工作前,必須在 Docker 中正確配置掛載共享(mount share),如下所示。

編輯你的 Docker ?systemd ?服務(wù)文件,按下面的方法設(shè)置 ?MountFlags?:

MountFlags=shared

或者,如果存在 ?MountFlags=slave? 就刪除掉。然后重啟 Docker 守護(hù)進(jìn)程:

sudo systemctl daemon-reload
sudo systemctl restart docker


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)