本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

原始塊卷支援進入 Beta 階段

Kubernetes v1.13 將原生塊儲存卷支援提升至 beta 階段。此功能允許持久卷在容器內部作為塊裝置而非掛載的檔案系統暴露。

什麼是塊裝置?

塊裝置能夠以固定大小的塊隨機訪問資料。硬碟、SSD 和 CD-ROM 驅動器都是塊裝置的示例。

通常,持久儲存是分層實現的,檔案系統(如 ext4)位於塊裝置(如旋轉磁碟或 SSD)之上。然後應用程式讀寫檔案,而不是直接操作塊。作業系統負責使用指定的檔案系統將檔案讀寫到底層裝置,以塊的形式進行。

值得注意的是,雖然整個磁碟是塊裝置,但磁碟分割槽和儲存區域網路 (SAN) 裝置的 LUN 也是塊裝置。

為什麼要在 Kubernetes 中新增原生塊儲存卷?

有些特殊應用程式需要直接訪問塊裝置,例如,因為檔案系統層引入了不必要的開銷。最常見的用例是資料庫,它們更喜歡直接在底層儲存上組織資料。原生塊裝置也常用於任何本身實現某種儲存服務(軟體定義儲存系統)的軟體。

從程式設計師的角度來看,塊裝置是一個非常大的位元組陣列,通常讀寫具有最小粒度,通常為 512 位元組,但經常是 4K 或更大。

隨著在 Kubernetes 內部執行資料庫軟體和儲存基礎設施軟體變得越來越普遍,Kubernetes 對原生塊裝置支援的需求也變得越來越重要。

哪些卷外掛支援原生塊儲存?

截至本部落格釋出時,以下樹內卷型別支援原生塊儲存:

  • AWS EBS
  • Azure Disk
  • Cinder
  • 光纖通道
  • GCE PD
  • iSCSI
  • 本地卷
  • RBD (Ceph)
  • Vsphere

樹外 CSI 卷驅動程式 也可能支援原生塊儲存卷。Kubernetes CSI 對原生塊儲存卷的支援目前處於 alpha 階段。請參閱此處的文件。

Kubernetes 原生塊儲存卷 API

原生塊儲存卷與普通卷有很多共同之處。兩者都透過建立繫結到 PersistentVolume 物件的 PersistentVolumeClaim 物件來請求,並透過將它們包含在 PodSpec 的 volumes 陣列中來附加到 Kubernetes 中的 Pod。

但是,有 2 個重要的區別。首先,要請求原生塊 PersistentVolumeClaim,您必須在 PersistentVolumeClaimSpec 中設定 volumeMode = "Block"。將 volumeMode 留空等同於指定 volumeMode = "Filesystem",這將導致傳統行為。PersistentVolumes 在其 PersistentVolumeSpec 中也有一個 volumeMode 欄位,並且 "Block" 型別的 PVC 只能繫結到 "Block" 型別的 PV,而 "Filesystem" 型別的 PVC 只能繫結到 "Filesystem" 型別的 PV。

其次,當在 Pod 中使用原生塊儲存卷時,您必須在 PodSpec 的容器部分中指定 VolumeDevice 而不是 VolumeMountVolumeDevices 具有 devicePaths 而不是 mountPaths,並且在容器內部,應用程式將在此路徑上看到一個裝置,而不是掛載的檔案系統。

應用程式在容器內部開啟、讀取和寫入裝置節點,就像它們在非容器化或虛擬化環境中與系統上的任何塊裝置互動一樣。

建立新的原生塊 PVC

首先,確保您選擇的儲存類關聯的 Provisioner 支援原生塊儲存。然後建立 PVC。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Block
  storageClassName: my-sc
  resources:
    requests:
    storage: 1Gi

使用原生塊 PVC

當您在 Pod 定義中使用 PVC 時,您可以為塊裝置選擇裝置路徑,而不是為檔案系統選擇掛載路徑。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: busybox
      command:
        - sleep
        - “3600”
      volumeDevices:
        - devicePath: /dev/block
          name: my-volume
      imagePullPolicy: IfNotPresent
  volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: my-pvc

作為儲存供應商,我如何為我的 CSI 外掛新增原生塊裝置支援?

CSI 外掛的原生塊支援仍處於 alpha 階段,但現在就可以新增支援。CSI 規範詳細說明了如何處理具有 BlockVolume 功能而不是 MountVolume 功能的卷請求。CSI 外掛可以支援兩種型別的卷,或其中一種。有關更多詳細資訊,請參閱此處的文件。

問題/陷阱

由於塊裝置實際上是裝置,因此可以在容器內部對其進行檔案系統卷無法實現的低階操作。例如,實際是 SCSI 磁碟的塊裝置支援使用 Linux ioctl 向裝置傳送 SCSI 命令。

但是,預設情況下,Linux 不允許容器在容器內部向磁碟傳送 SCSI 命令。為此,您必須授予容器安全上下文 SYS_RAWIO 功能以允許此操作。請參閱此處的文件。

此外,雖然 Kubernetes 保證向容器提供塊裝置,但不能保證它實際上是 SCSI 磁碟或任何其他型別的磁碟。使用者必須要麼確保其 Pod 使用所需的磁碟型別,要麼只部署可以處理各種塊裝置型別的應用程式。

我如何瞭解更多資訊?

請檢視此處有關快照功能的其他文件:原生塊儲存卷支援

我如何參與?

加入 Kubernetes 儲存 SIG 和 CSI 社群,幫助我們新增更多優秀功能並改進現有功能,例如原生塊儲存!

https://github.com/kubernetes/community/tree/master/sig-storage https://github.com/container-storage-interface/community/blob/master/README.md

特別感謝所有幫助 Kubernetes 新增塊儲存卷支援的貢獻者,包括: