K8S-PV和PVC簡介


官網文檔:https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/

默認情況下容器中的磁盤文件是非持久化的,對於運行在容器中的應用來說面臨兩個問題,第一:當容器掛掉
kubelet將重啟啟動它時,文件將會丟失;第二:當Pod中同時運行多個容器,容器之間需要共享文件時,
Kubernetes的Volume解決了這兩個問題。

介紹 

存儲的管理是一個與計算實例的管理完全不同的問題。PersistentVolume 子系統為用戶 和管理員提供了一組 API,將存儲如何供應的細節從其如何被使用中抽象出來。 為了實現這點,我們引入了兩個新的 API 資源:PersistentVolume 和 PersistentVolumeClaim。

持久卷(PersistentVolume,PV)是集群中的一塊存儲,可以由管理員事先供應,或者 使用存儲類(Storage Class)來動態供應。 持久卷是集群資源,就像節點也是集群資源一樣。PV 持久卷和普通的 Volume 一樣,也是使用 卷插件來實現的,只是它們擁有獨立於任何使用 PV 的 Pod 的生命周期。 此 API 對象中記述了存儲的實現細節,無論其背后是 NFS、iSCSI 還是特定於雲平台的存儲系統。PV是由管理員添加的的一個存儲的描述,是一個全局資源即不隸屬於任何namespace,包含存儲的類型,存儲的大小和訪問模式等,它的生命周期獨立於Pod,例如當使用它的Pod銷毀時對PV沒有影響。

持久卷申領(PersistentVolumeClaim,PVC)表達的是用戶對存儲的請求。概念上與 Pod 類似。 Pod 會耗用節點資源,而 PVC 申領會耗用 PV 資源。Pod 可以請求特定數量的資源(CPU 和內存);同樣 PVC 申領也可以請求特定的大小和訪問模式 (例如,可以要求 PV 卷能夠以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一來掛載,參見訪問模式)。PVC是namespace中的資源,可以設置特定的空間大小和訪問模式。

盡管 PersistentVolumeClaim 允許用戶消耗抽象的存儲資源,常見的情況是針對不同的 問題用戶需要的是具有不同屬性(如,性能)的 PersistentVolume 卷。 集群管理員需要能夠提供不同性質的 PersistentVolume,並且這些 PV 卷之間的差別不 僅限於卷大小和訪問模式,同時又不能將卷是如何實現的這些細節暴露給用戶。 為了滿足這類需求,就有了 存儲類(StorageClass) 資源。

卷和申領的生命周期 

PV 卷是集群中的資源。PVC 申領是對這些資源的請求,也被用來執行對資源的申領檢查。 PV 卷和 PVC 申領之間的互動遵循如下生命周期:

供應 

PV 卷的供應有兩種方式:靜態供應或動態供應。

靜態供應 

集群管理員創建若干 PV 卷。這些卷對象帶有真實存儲的細節信息,並且對集群 用戶可用(可見)。PV 卷對象存在於 Kubernetes API 中,可供用戶消費(使用)。

動態供應 

如果管理員所創建的所有靜態 PV 卷都無法與用戶的 PersistentVolumeClaim 匹配, 集群可以嘗試為該 PVC 申領動態供應一個存儲卷。 這一供應操作是基於 StorageClass 來實現的:PVC 申領必須請求某個 存儲類,同時集群管理員必須 已經創建並配置了該類,這樣動態供應卷的動作才會發生。 如果 PVC 申領指定存儲類為 "",則相當於為自身禁止使用動態供應的卷。

為了基於存儲類完成動態的存儲供應,集群管理員需要在 API 服務器上啟用 DefaultStorageClass 准入控制器。 舉例而言,可以通過保證 DefaultStorageClass 出現在 API 服務器組件的 --enable-admission-plugins 標志值中實現這點;該標志的值可以是逗號 分隔的有序列表。關於 API 服務器標志的更多信息,可以參考 kube-apiserver 文檔。

綁定 

用戶創建一個帶有特定存儲容量和特定訪問模式需求的 PersistentVolumeClaim 對象; 在動態供應場景下,這個 PVC 對象可能已經創建完畢。 主控節點中的控制回路監測新的 PVC 對象,尋找與之匹配的 PV 卷(如果可能的話), 並將二者綁定到一起。 如果為了新的 PVC 申領動態供應了 PV 卷,則控制回路總是將該 PV 卷綁定到這一 PVC 申領。 否則,用戶總是能夠獲得他們所請求的資源,只是所獲得的 PV 卷可能會超出所請求的配置。 一旦綁定關系建立,則 PersistentVolumeClaim 綁定就是排他性的,無論該 PVC 申領是 如何與 PV 卷建立的綁定關系。 PVC 申領與 PV 卷之間的綁定是一種一對一的映射,實現上使用 ClaimRef 來記述 PV 卷 與 PVC 申領間的雙向綁定關系。

如果找不到匹配的 PV 卷,PVC 申領會無限期地處於未綁定狀態。 當與之匹配的 PV 卷可用時,PVC 申領會被綁定。 例如,即使某集群上供應了很多 50 Gi 大小的 PV 卷,也無法與請求 100 Gi 大小的存儲的 PVC 匹配。當新的 100 Gi PV 卷被加入到集群時,該 PVC 才有可能被綁定。

使用 

Pod 將 PVC 申領當做存儲卷來使用。集群會檢視 PVC 申領,找到所綁定的卷,並 為 Pod 掛載該卷。對於支持多種訪問模式的卷,用戶要在 Pod 中以卷的形式使用申領 時指定期望的訪問模式。

一旦用戶有了申領對象並且該申領已經被綁定,則所綁定的 PV 卷在用戶仍然需要它期間 一直屬於該用戶。用戶通過在 Pod 的 volumes 塊中包含 persistentVolumeClaim 節區來調度 Pod,訪問所申領的 PV 卷。 相關細節可參閱使用申領作為卷

保護使用中的存儲對象 

保護使用中的存儲對象(Storage Object in Use Protection)這一功能特性的目的 是確保仍被 Pod 使用的 PersistentVolumeClaim(PVC)對象及其所綁定的 PersistentVolume(PV)對象在系統中不會被刪除,因為這樣做可能會引起數據丟失。

說明: 當使用某 PVC 的 Pod 對象仍然存在時,認為該 PVC 仍被此 Pod 使用。

如果用戶刪除被某 Pod 使用的 PVC 對象,該 PVC 申領不會被立即移除。 PVC 對象的移除會被推遲,直至其不再被任何 Pod 使用。 此外,如果管理員刪除已綁定到某 PVC 申領的 PV 卷,該 PV 卷也不會被立即移除。 PV 對象的移除也要推遲到該 PV 不再綁定到 PVC。

你可以看到當 PVC 的狀態為 Terminating 且其 Finalizers 列表中包含 kubernetes.io/pvc-protection 時,PVC 對象是處於被保護狀態的。

kubectl describe pvc hostpath

Name:          hostpath
Namespace:     default
StorageClass:  example-hostpath
Status:        Terminating
Volume:
Labels:        <none>
Annotations:   volume.beta.kubernetes.io/storage-class=example-hostpath
               volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers:    [kubernetes.io/pvc-protection]
...

你也可以看到當 PV 對象的狀態為 Terminating 且其 Finalizers 列表中包含 kubernetes.io/pv-protection 時,PV 對象是處於被保護狀態的。

kubectl describe pv task-pv-volume

Name:            task-pv-volume
Labels:          type=local
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    standard
Status:          Terminating
Claim:
Reclaim Policy:  Delete
Access Modes:    RWO
Capacity:        1Gi
Message:
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /tmp/data
    HostPathType:
Events:            <none>

回收 

當用戶不再使用其存儲卷時,他們可以從 API 中將 PVC 對象刪除,從而允許 該資源被回收再利用。PersistentVolume 對象的回收策略告訴集群,當其被 從申領中釋放時如何處理該數據卷。 目前,數據卷可以被 Retained(保留)、Recycled(回收)或 Deleted(刪除)。

保留(Retain) 

回收策略 Retain 使得用戶可以手動回收資源。當 PersistentVolumeClaim 對象 被刪除時,PersistentVolume 卷仍然存在,對應的數據卷被視為"已釋放(released)"。 由於卷上仍然存在這前一申領人的數據,該卷還不能用於其他申領。 管理員可以通過下面的步驟來手動回收該卷:

  1. 刪除 PersistentVolume 對象。與之相關的、位於外部基礎設施中的存儲資產 (例如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)在 PV 刪除之后仍然存在。
  2. 根據情況,手動清除所關聯的存儲資產上的數據。
  3. 手動刪除所關聯的存儲資產。

如果你希望重用該存儲資產,可以基於存儲資產的定義創建新的 PersistentVolume 卷對象。

刪除(Delete) 

對於支持 Delete 回收策略的卷插件,刪除動作會將 PersistentVolume 對象從 Kubernetes 中移除,同時也會從外部基礎設施(如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)中移除所關聯的存儲資產。 動態供應的卷會繼承其 StorageClass 中設置的回收策略,該策略默認 為 Delete。 管理員需要根據用戶的期望來配置 StorageClass;否則 PV 卷被創建之后必須要被 編輯或者修補。參閱更改 PV 卷的回收策略.

回收(Recycle) 

  警告: 回收策略 Recycle 已被廢棄。取而代之的建議方案是使用動態供應。
  如果下層的卷插件支持,回收策略  Recycle  會在卷上執行一些基本的 擦除( rm -rf /thevolume/* )操作,之后允許該卷用於新的 PVC 申領。

不過,管理員可以按 參考資料 中所述,使用 Kubernetes 控制器管理器命令行參數來配置一個定制的回收器(Recycler) Pod 模板。此定制的回收器 Pod 模板必須包含一個 volumes 規約,如下例所示:

apiVersion: v1
kind: Pod
metadata:
  name: pv-recycler
  namespace: default
spec:
  restartPolicy: Never
  volumes:
  - name: vol
    hostPath:
      path: /any/path/it/will/be/replaced
  containers:
  - name: pv-recycler
    image: "k8s.gcr.io/busybox"
    command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/*  && test -z \"$(ls -A /scrub)\" || exit 1"]
    volumeMounts:
    - name: vol
      mountPath: /scrub

定制回收器 Pod 模板中在 volumes 部分所指定的特定路徑要替換為 正被回收的卷的路徑。

預留 PersistentVolume 

通過在 PersistentVolumeClaim 中指定 PersistentVolume,你可以聲明該特定 PV 與 PVC 之間的綁定關系。如果該 PersistentVolume 存在且未被通過其 claimRef 字段預留給 PersistentVolumeClaim,則該 PersistentVolume 會和該 PersistentVolumeClaim 綁定到一起。

綁定操作不會考慮某些卷匹配條件是否滿足,包括節點親和性等等。 控制面仍然會檢查 存儲類、訪問模式和所請求的 存儲尺寸都是合法的。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: foo-pvc
  namespace: foo
spec:
  storageClassName: "" # 此處須顯式設置空字符串,否則會被設置為默認的 StorageClass
  volumeName: foo-pv
  ...

此方法無法對 PersistentVolume 的綁定特權做出任何形式的保證。 如果有其他 PersistentVolumeClaim 可以使用你所指定的 PV,則你應該首先預留 該存儲卷。你可以將 PV 的 claimRef 字段設置為相關的 PersistentVolumeClaim 以確保其他 PVC 不會綁定到該 PV 卷。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: foo-pv
spec:
  storageClassName: ""
  claimRef:
    name: foo-pvc
    namespace: foo
  ...

如果你想要使用 claimPolicy 屬性設置為 Retain 的 PersistentVolume 卷 時,包括你希望復用現有的 PV 卷時,這點是很有用的

擴充 PVC 申領 

FEATURE STATE:  Kubernetes v1.11 [beta]

現在,對擴充 PVC 申領的支持默認處於被啟用狀態。你可以擴充以下類型的卷:

  • gcePersistentDisk
  • awsElasticBlockStore
  • Cinder
  • glusterfs
  • rbd
  • Azure File
  • Azure Disk
  • Portworx
  • FlexVolumes CSI

只有當 PVC 的存儲類中將 allowVolumeExpansion 設置為 true 時,你才可以擴充該 PVC 申領。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
  resturl: "http://192.168.10.100:8080"
  restuser: ""
  secretNamespace: ""
  secretName: ""
allowVolumeExpansion: true

如果要為某 PVC 請求較大的存儲卷,可以編輯 PVC 對象,設置一個更大的尺寸值。 這一編輯操作會觸發為下層 PersistentVolume 提供存儲的卷的擴充。 Kubernetes 不會創建新的 PV 卷來滿足此申領的請求。 與之相反,現有的卷會被調整大小。

重設包含文件系統的卷的大小

只有卷中包含的文件系統是 XFS、Ext3 或者 Ext4 時,你才可以重設卷的大小。

當卷中包含文件系統時,只有在 Pod 使用 ReadWrite 模式來使用 PVC 申領的 情況下才能重設其文件系統的大小。 文件系統擴充的操作或者是在 Pod 啟動期間完成,或者在下層文件系統支持在線 擴充的前提下在 Pod 運行期間完成。

如果 FlexVolumes 的驅動將 RequiresFSResize 能力設置為 true,則該 FlexVolume 卷可以在 Pod 重啟期間調整大小。

重設使用中 PVC 申領的大小 

FEATURE STATE:  Kubernetes v1.15 [beta]
說明: Kubernetes 從 1.15 版本開始將調整使用中 PVC 申領大小這一能力作為 Beta 特性支持;該特性在 1.11 版本以來處於 Alpha 階段。  ExpandInUsePersistentVolumes 特性必須被啟用;在很多集群上,與此類似的 Beta 階段的特性是自動啟用的。 可參考 特性門控 文檔了解更多信息。

在這種情況下,你不需要刪除和重建正在使用某現有 PVC 的 Pod 或 Deployment。 所有使用中的 PVC 在其文件系統被擴充之后,立即可供其 Pod 使用。 此功能特性對於沒有被 Pod 或 Deployment 使用的 PVC 而言沒有效果。 你必須在執行擴展操作之前創建一個使用該 PVC 的 Pod。

與其他卷類型類似,FlexVolume 卷也可以在被 Pod 使用期間執行擴充操作。

說明: FlexVolume 卷的重設大小只能在下層驅動支持重設大小的時候才可進行。
說明: 擴充 EBS 卷的操作非常耗時。同時還存在另一個配額限制: 每 6 小時只能執行一次(尺寸)修改操作。

處理擴充卷過程中的失敗 

如果擴充下層存儲的操作失敗,集群管理員可以手動地恢復 PVC 申領的狀態並 取消重設大小的請求。否則,在沒有管理員干預的情況下,控制器會反復重試 重設大小的操作。

  1. 將綁定到 PVC 申領的 PV 卷標記為 Retain 回收策略;
  2. 刪除 PVC 對象。由於 PV 的回收策略為 Retain,我們不會在重建 PVC 時丟失數據。
  3. 刪除 PV 規約中的 claimRef 項,這樣新的 PVC 可以綁定到該卷。 這一操作會使得 PV 卷變為 "可用(Available)"。
  4. 使用小於 PV 卷大小的尺寸重建 PVC,設置 PVC 的 volumeName 字段為 PV 卷的名稱。 這一操作將把新的 PVC 對象綁定到現有的 PV 卷。
  5. 不要忘記恢復 PV 卷上設置的回收策略。

持久卷的類型 

PV 持久卷是用插件的形式來實現的。Kubernetes 目前支持以下插件:

持久卷 

每個 PV 對象都包含 spec 部分和 status 部分,分別對應卷的規約和狀態。 PersistentVolume 對象的名稱必須是合法的 DNS 子域名.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2

 說明: 在集群中使用持久卷存儲通常需要一些特定於具體卷類型的輔助程序。 在這個例子中,PersistentVolume 是 NFS 類型的,因此需要輔助程序 /sbin/mount.nfs 來支持掛載 NFS 文件系統。

卷模式 

FEATURE STATE:  Kubernetes v1.18 [stable]

針對 PV 持久卷,Kubernetes 支持兩種卷模式(volumeModes):Filesystem(文件系統) 和 Block(塊)。 volumeMode 是一個可選的 API 參數。 如果該參數被省略,默認的卷模式是 Filesystem

volumeMode 屬性設置為 Filesystem 的卷會被 Pod 掛載(Mount) 到某個目錄。 如果卷的存儲來自某塊設備而該設備目前為空,Kuberneretes 會在第一次掛載卷之前 在設備上創建文件系統。

你可以將 volumeMode 設置為 Block,以便將卷作為原始塊設備來使用。 這類卷以塊設備的方式交給 Pod 使用,其上沒有任何文件系統。 這種模式對於為 Pod 提供一種使用最快可能方式來訪問卷而言很有幫助,Pod 和 卷之間不存在文件系統層。另外,Pod 中運行的應用必須知道如何處理原始塊設備。 關於如何在 Pod 中使用 volumeMode: Block 的卷,可參閱 原始塊卷支持

訪問模式 

PersistentVolume 卷可以用資源提供者所支持的任何方式掛載到宿主系統上。 如下表所示,提供者(驅動)的能力不同,每個 PV 卷的訪問模式都會設置為 對應卷所支持的模式值。 例如,NFS 可以支持多個讀寫客戶,但是某個特定的 NFS PV 卷可能在服務器 上以只讀的方式導出。每個 PV 卷都會獲得自身的訪問模式集合,描述的是 特定 PV 卷的能力。

訪問模式有:

ReadWriteOnce
卷可以被一個節點以讀寫方式掛載。 ReadWriteOnce 訪問模式也允許運行在同一節點上的多個 Pod 訪問卷。
ReadOnlyMany
卷可以被多個節點以只讀方式掛載。
ReadWriteMany
卷可以被多個節點以讀寫方式掛載。
ReadWriteOncePod
卷可以被單個 Pod 以讀寫方式掛載。 如果你想確保整個集群中只有一個 Pod 可以讀取或寫入該 PVC, 請使用ReadWriteOncePod 訪問模式。這只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。

這篇博客文章 Introducing Single Pod Access Mode for PersistentVolumes 描述了更詳細的內容。

在命令行接口(CLI)中,訪問模式也使用以下縮寫形式:

  • RWO - ReadWriteOnce
  • ROX - ReadOnlyMany
  • RWX - ReadWriteMany
  • RWOP - ReadWriteOncePod

重要提醒! 每個卷同一時刻只能以一種訪問模式掛載,即使該卷能夠支持 多種訪問模式。例如,一個 GCEPersistentDisk 卷可以被某節點以 ReadWriteOnce 模式掛載,或者被多個節點以 ReadOnlyMany 模式掛載,但不可以同時以兩種模式 掛載。

 

卷插件 ReadWriteOnce ReadOnlyMany ReadWriteMany ReadWriteOncePod
AWSElasticBlockStore - - -
AzureFile -
AzureDisk - - -
CephFS -
Cinder - - -
CSI 取決於驅動 取決於驅動 取決於驅動 取決於驅動
FC - -
FlexVolume 取決於驅動 -
Flocker - - -
GCEPersistentDisk - -
Glusterfs -
HostPath - - -
iSCSI - -
Quobyte -
NFS -
RBD - -
VsphereVolume - - (Pod 運行於同一節點上時可行) -
PortworxVolume - -
StorageOS - - -
 

類 

每個 PV 可以屬於某個類(Class),通過將其 storageClassName 屬性設置為某個 StorageClass 的名稱來指定。 特定類的 PV 卷只能綁定到請求該類存儲卷的 PVC 申領。 未設置 storageClassName 的 PV 卷沒有類設定,只能綁定到那些沒有指定特定 存儲類的 PVC 申領。

早前,Kubernetes 使用注解 volume.beta.kubernetes.io/storage-class 而不是 storageClassName 屬性。這一注解目前仍然起作用,不過在將來的 Kubernetes 發布版本中該注解會被徹底廢棄。

回收策略 

目前的回收策略有:

  • Retain -- 手動回收
  • Recycle -- 基本擦除 (rm -rf /thevolume/*)
  • Delete -- 諸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷這類關聯存儲資產也被刪除

目前,僅 NFS 和 HostPath 支持回收(Recycle)。 AWS EBS、GCE PD、Azure Disk 和 Cinder 卷都支持刪除(Delete)。

節點親和性 

每個 PV 卷可以通過設置節點親和性來定義一些約束,進而限制從哪些節點上可以訪問此卷。 使用這些卷的 Pod 只會被調度到節點親和性規則所選擇的節點上執行。 要設置節點親和性,配置 PV 卷 .spec 中的 nodeAffinity。 持久卷 API 參考關於該字段的更多細節。

說明: 對大多數類型的卷而言,你不需要設置節點親和性字段。  AWS EBS、  GCE PD 和  Azure Disk 卷類型都能 自動設置相關字段。 你需要為  local 卷顯式地設置 此屬性。

階段 

每個卷會處於以下階段(Phase)之一:

  • Available(可用)-- 卷是一個空閑資源,尚未綁定到任何申領;
  • Bound(已綁定)-- 該卷已經綁定到某申領;
  • Released(已釋放)-- 所綁定的申領已被刪除,但是資源尚未被集群回收;
  • Failed(失敗)-- 卷的自動回收操作失敗。

命令行接口能夠顯示綁定到某 PV 卷的 PVC 對象。

PersistentVolumeClaims 

每個 PVC 對象都有 spec 和 status 部分,分別對應申領的規約和狀態。 PersistentVolumeClaim 對象的名稱必須是合法的 DNS 子域名.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

訪問模式

申領在請求具有特定訪問模式的存儲時,使用與卷相同的訪問模式約定

卷模式

申領使用與卷相同的約定來表明是將卷作為文件系統還是塊設備來使用。

資源 

申領和 Pod 一樣,也可以請求特定數量的資源。在這個上下文中,請求的資源是存儲。 卷和申領都使用相同的 資源模型

選擇算符 

申領可以設置標簽選擇算符 來進一步過濾卷集合。只有標簽與選擇算符相匹配的卷能夠綁定到申領上。 選擇算符包含兩個字段:

  • matchLabels - 卷必須包含帶有此值的標簽
  • matchExpressions - 通過設定鍵(key)、值列表和操作符(operator) 來構造的需求。合法的操作符有 In、NotIn、Exists 和 DoesNotExist。

來自 matchLabels 和 matchExpressions 的所有需求都按邏輯與的方式組合在一起。 這些需求都必須被滿足才被視為匹配。

類 

申領可以通過為 storageClassName 屬性設置 StorageClass 的名稱來請求特定的存儲類。 只有所請求的類的 PV 卷,即 storageClassName 值與 PVC 設置相同的 PV 卷, 才能綁定到 PVC 申領。

PVC 申領不必一定要請求某個類。如果 PVC 的 storageClassName 屬性值設置為 "", 則被視為要請求的是沒有設置存儲類的 PV 卷,因此這一 PVC 申領只能綁定到未設置 存儲類的 PV 卷(未設置注解或者注解值為 "" 的 PersistentVolume(PV)對象在系統中不會被刪除,因為這樣做可能會引起數據丟失。 未設置 storageClassName 的 PVC 與此大不相同,也會被集群作不同處理。 具體篩查方式取決於 DefaultStorageClass 准入控制器插件 是否被啟用。

  • 如果准入控制器插件被啟用,則管理員可以設置一個默認的 StorageClass。 所有未設置 storageClassName 的 PVC 都只能綁定到隸屬於默認存儲類的 PV 卷。 設置默認 StorageClass 的工作是通過將對應 StorageClass 對象的注解 storageclass.kubernetes.io/is-default-class 賦值為 true 來完成的。 如果管理員未設置默認存儲類,集群對 PVC 創建的處理方式與未啟用准入控制器插件 時相同。如果設定的默認存儲類不止一個,准入控制插件會禁止所有創建 PVC 操作。
  • 如果准入控制器插件被關閉,則不存在默認 StorageClass 的說法。 所有未設置 storageClassName 的 PVC 都只能綁定到未設置存儲類的 PV 卷。 在這種情況下,未設置 storageClassName 的 PVC 與 storageClassName 設置未 "" 的 PVC 的處理方式相同。

取決於安裝方法,默認的 StorageClass 可能在集群安裝期間由插件管理器(Addon Manager)部署到集群中。

當某 PVC 除了請求 StorageClass 之外還設置了 selector,則這兩種需求會按 邏輯與關系處理:只有隸屬於所請求類且帶有所請求標簽的 PV 才能綁定到 PVC。

說明: 目前,設置了非空  selector 的 PVC 對象無法讓集群為其動態供應 PV 卷。

早前,Kubernetes 使用注解 volume.beta.kubernetes.io/storage-class 而不是 storageClassName 屬性。這一注解目前仍然起作用,不過在將來的 Kubernetes 發布版本中該注解會被徹底廢棄。

使用申領作為卷 

Pod 將申領作為卷來使用,並藉此訪問存儲資源。 申領必須位於使用它的 Pod 所在的同一名字空間內。 集群在 Pod 的名字空間中查找申領,並使用它來獲得申領所使用的 PV 卷。 之后,卷會被掛載到宿主上並掛載到 Pod 中。

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim

關於名字空間的說明 

PersistentVolume 卷的綁定是排他性的。 由於 PersistentVolumeClaim 是名字空間作用域的對象,使用 "Many" 模式(ROXRWX)來掛載申領的操作只能在同一名字空間內進行。

類型為 hostpath 的 PersistentVolume 

hostPath PersistentVolume 使用節點上的文件或目錄來模擬網絡附加(network-attached)存儲。 相關細節可參閱hostPath 卷示例

原始塊卷支持 

FEATURE STATE:  Kubernetes v1.18 [stable]

以下卷插件支持原始塊卷,包括其動態供應(如果支持的話)的卷:

  • AWSElasticBlockStore
  • AzureDisk
  • CSI
  • FC (光纖通道)
  • GCEPersistentDisk
  • iSCSI
  • Local 卷
  • OpenStack Cinder
  • RBD (Ceph 塊設備)
  • VsphereVolume

使用原始塊卷的持久卷 

apiVersion: v1
kind: PersistentVolume
metadata:
  name: block-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  volumeMode: Block
  persistentVolumeReclaimPolicy: Retain
  fc:
    targetWWNs: ["50060e801049cfd1"]
    lun: 0
    readOnly: false

申請原始塊卷的 PVC 申領 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: block-pvc
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Block
  resources:
    requests:
      storage: 10Gi

卷填充器(Populator)與數據源 

FEATURE STATE:  Kubernetes v1.22 [alpha]
說明:

Kubernetes 支持自定義的卷填充器;Kubernetes 1.18 版本引入了這個 alpha 特性。 Kubernetes 1.22 使用重新設計的 API 重新實現了該機制。 確認你正在閱讀與你的集群版本一致的 Kubernetes 文檔。 要獲知版本信息,請輸入 kubectl version.

要使用自定義的卷填充器,你必須為 kube-apiserver 和 kube-controller-manager 啟用 AnyVolumeDataSource 特性門控

卷填充器利用了 PVC 規約字段 dataSourceRef。 不像 dataSource 字段只能包含對另一個持久卷申領或卷快照的引用, dataSourceRef 字段可以包含對同一命名空間中任何對象的引用(不包含除 PVC 以外的核心資源)。 對於啟用了特性門控的集群,使用 dataSourceRef 比 dataSource 更好。

數據源引用 

dataSourceRef 字段的行為與 dataSource 字段幾乎相同。 如果其中一個字段被指定而另一個字段沒有被指定,API 服務器將給兩個字段相同的值。 這兩個字段都不能在創建后改變,如果試圖為這兩個字段指定不同的值,將導致驗證錯誤。 因此,這兩個字段將總是有相同的內容。

在 dataSourceRef 字段和 dataSource 字段之間有兩個用戶應該注意的區別:

  • dataSource 字段會忽略無效的值(如同是空值), 而 dataSourceRef 字段永遠不會忽略值,並且若填入一個無效的值,會導致錯誤。 無效值指的是 PVC 之外的核心對象(沒有 apiGroup 的對象)。
  • dataSourceRef 字段可以包含不同類型的對象,而 dataSource 字段只允許 PVC 和卷快照。

用戶應該始終在啟用了特性門控的集群上使用 dataSourceRef,而在沒有啟用特性門控的集群上使用 dataSource。 在任何情況下都沒有必要查看這兩個字段。 這兩個字段的值看似相同但是語義稍微不一樣,是為了向后兼容。 特別是混用舊版本和新版本的控制器時,它們能夠互通。

使用卷填充器 

卷填充器是能創建非空卷的控制器, 其卷的內容通過一個自定義資源決定。 用戶通過使用 dataSourceRef 字段引用自定義資源來創建一個被填充的卷:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: populated-pvc
spec:
  dataSourceRef:
    name: example-name
    kind: ExampleDataSource
    apiGroup: example.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

因為卷填充器是外部組件,如果沒有安裝所有正確的組件,試圖創建一個使用卷填充器的 PVC 就會失敗。 外部控制器應該在 PVC 上產生事件,以提供創建狀態的反饋,包括在由於缺少某些組件而無法創建 PVC 的情況下發出警告。

你可以把 alpha 版本的卷數據源驗證器 控制器安裝到你的集群中。 如果沒有填充器處理該數據源的情況下,該控制器會在 PVC 上產生警告事件。 當一個合適的填充器被安裝到 PVC 上時,該控制器的職責是上報與卷創建有關的事件,以及在該過程中發生的問題。

在容器中添加原始塊設備路徑的 Pod 規約

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-block-volume
spec:
  containers:
    - name: fc-container
      image: fedora:26
      command: ["/bin/sh", "-c"]
      args: [ "tail -f /dev/null" ]
      volumeDevices:
        - name: data
          devicePath: /dev/xvda
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: block-pvc
說明: 向 Pod 中添加原始塊設備時,你要在容器內設置設備路徑而不是掛載路徑。

綁定塊卷 

如果用戶通過 PersistentVolumeClaim 規約的 volumeMode 字段來表明對原始 塊設備的請求,綁定規則與之前版本中未在規約中考慮此模式的實現略有不同。 下面列舉的表格是用戶和管理員可以為請求原始塊設備所作設置的組合。 此表格表明在不同的組合下卷是否會被綁定。

靜態供應卷的卷綁定矩陣:

 

PV volumeMode PVC volumeMode Result
未指定 未指定 綁定
未指定 Block 不綁定
未指定 Filesystem 綁定
Block 未指定 不綁定
Block Block 綁定
Block Filesystem 不綁定
Filesystem Filesystem 綁定
Filesystem Block 不綁定
Filesystem 未指定 綁定

 

說明: Alpha 發行版本中僅支持靜態供應的卷。 管理員需要在處理原始塊設備時小心處理這些值。

對卷快照及從卷快照中恢復卷的支持

FEATURE STATE:  Kubernetes v1.17 [beta]

卷快照(Volume Snapshot)功能的添加僅是為了支持 CSI 卷插件。 有關細節可參閱卷快照文檔。

要啟用從卷快照數據源恢復數據卷的支持,可在 API 服務器和控制器管理器上啟用 VolumeSnapshotDataSource 特性門控。

基於卷快照創建 PVC 申領 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: restore-pvc
spec:
  storageClassName: csi-hostpath-sc
  dataSource:
    name: new-snapshot-test
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

卷克隆 

卷克隆功能特性僅適用於 CSI 卷插件。

基於現有 PVC 創建新的 PVC 申領 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: cloned-pvc
spec:
  storageClassName: my-csi-plugin
  dataSource:
    name: existing-src-pvc-name
    kind: PersistentVolumeClaim
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

編寫可移植的配置 

如果你要編寫配置模板和示例用來在很多集群上運行並且需要持久性存儲,建議你使用以下模式:

  • 將 PersistentVolumeClaim 對象包含到你的配置包(Bundle)中,和 Deployment 以及 ConfigMap 等放在一起。
  • 不要在配置中包含 PersistentVolume 對象,因為對配置進行實例化的用戶很可能 沒有創建 PersistentVolume 的權限。
  • 為用戶提供在實例化模板時指定存儲類名稱的能力。
    • 仍按用戶提供存儲類名稱,將該名稱放到 persistentVolumeClaim.storageClassName 字段中。 這樣會使得 PVC 在集群被管理員啟用了存儲類支持時能夠匹配到正確的存儲類,
    • 如果用戶未指定存儲類名稱,將 persistentVolumeClaim.storageClassName 留空(nil)。 這樣,集群會使用默認 StorageClass 為用戶自動供應一個存儲卷。 很多集群環境都配置了默認的 StorageClass,或者管理員也可以自行創建默認的 StorageClass
  • 在你的工具鏈中,監測經過一段時間后仍未被綁定的 PVC 對象,要讓用戶知道這些對象, 因為這可能意味着集群不支持動態存儲(因而用戶必須先創建一個匹配的 PV),或者 集群沒有配置存儲系統(因而用戶無法配置需要 PVC 的工作負載配置)。

PersistentVolume參數

# kubectl explain PersistentVolume
Capacity: #當前PV空間大小,kubectl explain PersistentVolume.spec.capacity
accessModes :訪問模式,#kubectl explain PersistentVolume.spec.accessModes ReadWriteOnce – PV只能被單個節點以讀寫權限掛載,RWO ReadOnlyMany – PV以可以被多個節點掛載但是權限是只讀的,ROX ReadWriteMany – PV可以被多個節點是讀寫方式掛載使用,RWX
persistentVolumeReclaimPolicy #刪除機制即刪除存儲卷卷時候,已經創建好的存儲卷由以下刪除操作:
#kubectl explain PersistentVolume.spec.persistentVolumeReclaimPolicy Retain – 刪除PV后保持原裝,最后需要管理員手動刪除 Recycle – 空間回收,及刪除存儲卷上的所有數據(包括目錄和隱藏文件),目前僅支持NFS和hostPath Delete – 自動刪除存儲卷 volumeMode #卷類型,kubectl explain PersistentVolume.spec.volumeMode 定義存儲卷使用的文件系統是塊設備還是文件系統,默認為文件系統 mountOptions #附加的掛載選項列表,實現更精細的權限控制 ro #等

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM