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

為 Kubernetes 引入容器儲存介面(CSI)Alpha

Kubernetes 的一個關鍵區別因素是其強大的卷外掛系統,該系統支援多種不同型別的儲存系統來

  1. 在需要時自動建立儲存。
  2. 在任何排程容器的地方提供儲存。
  3. 在不再需要時自動刪除儲存。然而,為 Kubernetes 新增對新儲存系統的支援一直是一個挑戰。

Kubernetes 1.9 引入了容器儲存介面(CSI)的 Alpha 版實現,使得安裝新卷外掛像部署一個 Pod 一樣簡單。它還允許第三方儲存提供商開發解決方案,而無需新增到 Kubernetes 核心程式碼庫。

由於該功能在 1.9 版本中處於 Alpha 階段,因此必須明確啟用。Alpha 功能不建議用於生產環境,但它們很好地表明瞭專案的發展方向(在本例中,是朝著更具可擴充套件性和基於標準的 Kubernetes 儲存生態系統發展)。

為什麼選擇 Kubernetes CSI?

Kubernetes 卷外掛目前是“in-tree”的,這意味著它們與 Kubernetes 核心二進位制檔案連結、編譯、構建和一起釋出。要為 Kubernetes 新增對新儲存系統的支援(即卷外掛),需要將程式碼提交到 Kubernetes 核心倉庫。但與 Kubernetes 釋出流程保持一致對許多外掛開發者來說很痛苦。

現有的 Flex Volume 外掛試圖透過為外部卷外掛公開基於 exec 的 API 來解決這一痛點。儘管它允許第三方儲存供應商在樹外編寫驅動,但要部署第三方驅動檔案,它需要訪問節點和主機的根檔案系統。

除了部署困難之外,Flex 還沒有解決外掛依賴性的痛點:卷外掛往往有許多外部要求(例如,對掛載和檔案系統工具的需求)。這些依賴項被假定在底層主機作業系統上可用,但情況往往並非如此(安裝它們需要訪問節點機器的根檔案系統)。

CSI 透過允許儲存外掛在樹外開發、容器化、透過標準 Kubernetes 原語部署,並透過使用者熟悉和喜愛的 Kubernetes 儲存原語(PersistentVolumeClaims、PersistentVolumes、StorageClasses)來使用,解決了所有這些問題。

什麼是 CSI?

CSI 的目標是建立一個標準化機制,讓容器編排系統(COs)能夠向其容器化工作負載公開任意儲存系統。CSI 規範是 Kubernetes、Mesos、Docker 和 Cloud Foundry 等各種容器編排系統(COs)社群成員合作的產物。該規範獨立於 Kubernetes 進行開發,並在 https://github.com/container-storage-interface/spec/blob/master/spec.md 維護。

Kubernetes v1.9 暴露了 CSI 規範的 Alpha 版實現,使得 CSI 相容的卷驅動程式可以在 Kubernetes 上部署並被 Kubernetes 工作負載使用。

如何在 Kubernetes 叢集上部署 CSI 驅動?

CSI 外掛作者將提供他們自己的說明,以指導如何在 Kubernetes 上部署他們的外掛。

如何使用 CSI 卷?

假設 CSI 儲存外掛已部署在您的叢集上,您可以透過熟悉的 Kubernetes 儲存原語使用它:PersistentVolumeClaims、PersistentVolumes 和 StorageClasses。

CSI 是 Kubernetes v1.9 中的一項 Alpha 功能。要啟用它,請設定以下標誌

CSI is an alpha feature in Kubernetes v1.9. To enable it, set the following flags:

API server binary:
--feature-gates=CSIPersistentVolume=true
--runtime-config=storage.k8s.io/v1alpha1=true
API server binary and kubelet binaries:
--feature-gates=MountPropagation=true
--allow-privileged=true

動態配置

透過建立指向 CSI 外掛的 StorageClass,您可以為支援動態配置的 CSI 儲存外掛啟用卷的自動建立/刪除。

例如,以下 StorageClass 允許名為“com.example.team/csi-driver”的 CSI 卷外掛動態建立“fast-storage”卷。

kind: StorageClass

apiVersion: storage.k8s.io/v1

metadata:

  name: fast-storage

provisioner: com.example.team/csi-driver

parameters:

  type: pd-ssd

要觸發動態配置,請建立一個 PersistentVolumeClaim 物件。例如,以下 PersistentVolumeClaim 使用上述 StorageClass 觸發動態配置。

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: my-request-for-storage

spec:

  accessModes:

  - ReadWriteOnce

  resources:

    requests:

      storage: 5Gi

  storageClassName: fast-storage

當呼叫卷配置時,引數“type: pd-ssd”透過“CreateVolume”呼叫傳遞給 CSI 外掛“com.example.team/csi-driver”。作為響應,外部卷外掛配置一個新卷,然後自動建立一個 PersistentVolume 物件來表示新卷。Kubernetes 隨後將新的 PersistentVolume 物件繫結到 PersistentVolumeClaim,使其可以立即使用。

如果“fast-storage”StorageClass 被標記為預設,則無需在 PersistentVolumeClaim 中包含 storageClassName,它將預設使用。

預先配置的卷

您始終可以透過手動建立 PersistentVolume 物件來表示現有卷,從而在 Kubernetes 中公開預先存在的卷。例如,以下 PersistentVolume 公開了一個名為“existingVolumeName”的卷,該卷屬於名為“com.example.team/csi-driver”的 CSI 儲存外掛。

apiVersion: v1

kind: PersistentVolume

metadata:

  name: my-manually-created-pv

spec:

  capacity:

    storage: 5Gi

  accessModes:

    - ReadWriteOnce

  persistentVolumeReclaimPolicy: Retain

  csi:

    driver: com.example.team/csi-driver

    volumeHandle: existingVolumeName

    readOnly: false

附加和掛載

您可以在任何 Pod 或 Pod 模板中引用繫結到 CSI 卷的 PersistentVolumeClaim。

kind: Pod

apiVersion: v1

metadata:

  name: my-pod

spec:

  containers:

    - name: my-frontend

      image: dockerfile/nginx

      volumeMounts:

      - mountPath: "/var/www/html"

        name: my-csi-volume

  volumes:

    - name: my-csi-volume

      persistentVolumeClaim:

        claimName: my-request-for-storage

當引用 CSI 卷的 Pod 被排程時,Kubernetes 將觸發針對外部 CSI 外掛的相應操作(ControllerPublishVolume、NodePublishVolume 等),以確保指定卷已連線、掛載並可供 Pod 中的容器使用。

更多詳情請參閱 CSI 實現的設計文件文件

如何建立 CSI 驅動程式?

Kubernetes 在 CSI 卷驅動程式的打包和部署方面儘可能保持最少的規定。在 Kubernetes 上部署 CSI 卷驅動程式的最低要求記錄在此處

最低要求文件還包含一個部分,概述了在 Kubernetes 上部署任意容器化 CSI 驅動程式的建議機制。儲存提供商可以使用此機制來簡化在 Kubernetes 上部署容器化 CSI 相容卷驅動程式。

作為此推薦部署流程的一部分,Kubernetes 團隊提供了以下邊車(helper)容器:

  • 外部附加器 (external-attacher)

    • 監控 Kubernetes VolumeAttachment 物件並觸發針對 CSI 端點的 ControllerPublish 和 ControllerUnpublish 操作的邊車容器。
  • 外部供應器 (external-provisioner)

    • 監控 Kubernetes PersistentVolumeClaim 物件並觸發針對 CSI 端點的 CreateVolume 和 DeleteVolume 操作的邊車容器。
  • 驅動註冊器

    • Sidecar 容器,用於向 kubelet 註冊 CSI 驅動程式(將來),並將驅動程式的自定義 NodeId(透過對 CSI 端點執行 GetNodeID 呼叫獲取)新增到 Kubernetes Node API 物件的註解中

儲存供應商可以使用這些元件為其外掛構建 Kubernetes 部署,同時使其 CSI 驅動程式完全不瞭解 Kubernetes。

在哪裡可以找到 CSI 驅動程式?

CSI 驅動程式由第三方開發和維護。您可以在此處找到示例 CSI 驅動程式,但這些僅用於說明目的,不適用於生產工作負載。

Flex 怎麼樣?

Flex Volume 外掛作為一種基於 exec 的機制,用於建立“out-of-tree”卷外掛。儘管它有一些缺點(如上所述),但 Flex 卷外掛與新的 CSI 卷外掛共存。SIG Storage 將繼續維護 Flex API,以便現有的第三方 Flex 驅動程式(已部署在生產叢集中)能夠繼續工作。將來,新的卷功能將只新增到 CSI,而不是 Flex。

內部卷外掛會發生什麼變化?

一旦 CSI 達到穩定狀態,我們計劃將大多數內部卷外掛遷移到 CSI。請繼續關注更多詳細資訊,因為 Kubernetes CSI 實現將趨於穩定。

Alpha 版本的侷限性是什麼?

CSI 的 Alpha 實現有以下限制:

  • CreateVolume、NodePublishVolume 和 ControllerPublishVolume 呼叫中的憑證欄位不受支援。
  • 不支援塊卷;只支援檔案。
  • 不支援指定檔案系統,預設為 ext4。
  • CSI 驅動程式必須與提供的“external-attacher”一起部署,即使它們沒有實現“ControllerPublishVolume”。
  • Kubernetes 排程器拓撲感知不支援 CSI 卷:簡而言之,就是共享卷配置位置(區域、區域等)資訊,以允許 k8s 排程器做出更智慧的排程決策。

下一步是什麼?

根據反饋和採用情況,Kubernetes 團隊計劃在 1.10 或 1.11 版本中將 CSI 實現推向 Beta 版。

我如何參與?

這個專案,和所有 Kubernetes 專案一樣,是許多來自不同背景的貢獻者共同努力的成果。衷心感謝 Vladimir Vivien (vladimirvivien)、Jan Šafránek (jsafrane)、Chakravarthy Nelluri (chakri-nelluri)、Bradley Childs (childsb)、Luis Pabón (lpabon) 和 Saad Ali (saad-ali) 為將 CSI 引入 Kubernetes 所做的不懈努力。

如果您有興趣參與 CSI 或 Kubernetes 儲存系統任何部分的設計和開發,請加入 Kubernetes 儲存特別興趣小組(SIG)。我們正在迅速發展,並始終歡迎新的貢獻者。