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

CSI 臨時內聯卷

通常,Kubernetes 中外部儲存驅動程式提供的卷是**持久的**,其生命週期完全獨立於 Pod,或者(作為特例)與使用卷的第一個 Pod 鬆散耦合(延遲繫結模式)。在 Kubernetes 中請求和定義此類卷的機制是持久卷宣告 (PVC) 和持久卷 (PV) 物件。最初,由容器儲存介面 (CSI) 驅動程式支援的卷只能透過這種 PVC/PV 機制使用。

但也有一些用例需要資料卷,其內容和生命週期與 Pod 繫結。例如,驅動程式可能使用特定於在 Pod 中執行的應用程式的動態建立的 Secrets 來填充卷。此類卷需要與 Pod 一起建立,並且可以作為 Pod 終止的一部分被刪除(**臨時**)。它們被定義為 Pod 規範的一部分(**內聯**)。

自 Kubernetes 1.15 起,CSI 驅動程式也可以用於此類**臨時內聯**卷。在 1.15 版中,必須設定 CSIInlineVolume 功能門才能啟用它,因為支援仍處於 alpha 階段。在 1.16 版中,該功能達到了 Beta 階段,這通常意味著它在叢集中預設啟用。

CSI 驅動程式必須進行調整才能支援此功能,因為儘管使用了兩個現有的 CSI gRPC 呼叫(`NodePublishVolume` 和 `NodeUnpublishVolume`),但它們的使用方式不同且未包含在 CSI 規範中:對於臨時卷,`kubelet` 在請求 CSI 驅動程式獲取卷時僅呼叫 `NodePublishVolume`。所有其他呼叫(如 `CreateVolume`、`NodeStageVolume` 等)都將被跳過。卷引數在 Pod 規範中提供,並從中複製到 `NodePublishVolumeRequest.volume_context` 欄位。目前沒有標準化引數;即使是大小等常見引數也必須以 CSI 驅動程式定義的格式提供。同樣,只有在 Pod 終止並且需要移除卷後,才會呼叫 `NodeUnpublishVolume`。

最初的假設是 CSI 驅動程式將專門編寫用於提供持久卷或臨時卷。但也有一些驅動程式提供在兩種模式下都很有用的儲存:例如,PMEM-CSI 管理持久記憶體 (PMEM),這是一種由 Intel® Optane™ DC 持久記憶體提供的新型本地儲存。這種記憶體既可以用作持久資料儲存(比普通 SSD 快),也可以用作臨時暫存空間(容量高於 DRAM)。

因此,Kubernetes 1.16 中的支援得到了擴充套件。

  • Kubernetes 和使用者可以透過 `CSIDriver` 物件中的 `volumeLifecycleModes` 欄位來確定驅動程式支援哪種卷。
  • 驅動程式可以透過啟用“掛載時的 Pod 資訊”功能來獲取卷模式資訊,該功能將在 `NodePublishRequest.volume_context` 中新增新的 `csi.storage.k8s.io/ephemeral` 條目。

有關在 CSI 驅動程式中實現臨時內聯卷支援的更多資訊,請參閱Kubernetes-CSI 文件原始設計文件

這篇部落格文章接下來將介紹基於真實驅動程式的使用示例,並在最後進行總結。

示例

PMEM-CSI

v0.6.0 版本中添加了對臨時內聯卷的支援。該驅動程式可以在具有真實 Intel® Optane™ DC 持久記憶體的主機上使用,在 GCE 中的特殊機器上或透過 QEMU 模擬的硬體上使用。後者已完全整合到 Makefile 中,只需要 Go、Docker 和 KVM,因此本示例使用了這種方法。

git clone --branch release-0.6 https://github.com/intel/pmem-csi
cd pmem-csi
TEST_DISTRO=clear TEST_DISTRO_VERSION=32080 TEST_PMEM_REGISTRY=intel make start

啟動四節點叢集可能需要一段時間,但最終應該會顯示:

The test cluster is ready. Log in with /work/pmem-csi/_work/pmem-govm/ssh-pmem-govm, run kubectl once logged in.
Alternatively, KUBECONFIG=/work/pmem-csi/_work/pmem-govm/kube.config can also be used directly.

To try out the pmem-csi driver persistent volumes:
...

To try out the pmem-csi driver ephemeral volumes:
   cat deploy/kubernetes-1.17/pmem-app-ephemeral.yaml | /work/pmem-csi/_work/pmem-govm/ssh-pmem-govm kubectl create -f -

deploy/kubernetes-1.17/pmem-app-ephemeral.yaml 指定了一個卷。

kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app-inline-volume
spec:
  containers:
    - name: my-frontend
      image: busybox
      command: [ "sleep", "100000" ]
      volumeMounts:
      - mountPath: "/data"
        name: my-csi-volume
  volumes:
  - name: my-csi-volume
    csi:
      driver: pmem-csi.intel.com
      fsType: "xfs"
      volumeAttributes:
        size: "2Gi"
        nsmode: "fsdax"

一旦我們建立了該 Pod,我們就可以檢查結果。

kubectl describe pods/my-csi-app-inline-volume
Name:         my-csi-app-inline-volume
...
Volumes:
  my-csi-volume:
    Type:              CSI (a Container Storage Interface (CSI) volume source)
    Driver:            pmem-csi.intel.com
    FSType:            xfs
    ReadOnly:          false
    VolumeAttributes:      nsmode=fsdax
                           size=2Gi
kubectl exec my-csi-app-inline-volume -- df -h /data
Filesystem                Size      Used Available Use% Mounted on
/dev/ndbus0region0fsdax/d7eb073f2ab1937b88531fce28e19aa385e93696
                          1.9G     34.2M      1.8G   2% /data

映象填充器

映象填充器會自動解壓容器映象並將其內容作為臨時卷提供。它仍在開發中,但已提供 canary 映象,可以透過以下方式安裝:

kubectl create -f https://github.com/kubernetes-csi/csi-driver-image-populator/raw/master/deploy/kubernetes-1.16/csi-image-csidriverinfo.yaml
kubectl create -f https://github.com/kubernetes-csi/csi-driver-image-populator/raw/master/deploy/kubernetes-1.16/csi-image-daemonset.yaml

此示例 Pod 將執行 nginx 並讓它提供來自 `kfox1111/misc:test` 映象的資料。

kubectl create -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.16-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: data
      mountPath: /usr/share/nginx/html
  volumes:
  - name: data
    csi:
      driver: image.csi.k8s.io
      volumeAttributes:
          image: kfox1111/misc:test
EOF
kubectl exec nginx -- cat /usr/share/nginx/html/test

那個 `test` 檔案只包含一個單詞

testing

此類資料容器可以使用 Dockerfile 構建,例如:

FROM scratch
COPY index.html /index.html

cert-manager-csi

cert-manager-csi 與 cert-manager 協同工作。此驅動程式的目標是促進無縫地向 Pod 請求和掛載證書金鑰對。這對於促進 mTLS 或透過保證存在證書來保護 Pod 連線非常有用,同時擁有 cert-manager 提供的所有功能。此專案是實驗性的。

後續步驟

臨時內聯卷存在的問題之一是 Kubernetes 在將 Pod 排程到節點時,對該節點上當前可用的儲存一無所知。一旦 Pod 被排程,CSI 驅動程式必須在該節點上使卷可用。如果當前不可能,Pod 將無法啟動。這將重試直到卷最終準備就緒。儲存容量跟蹤 KEP 正在嘗試解決此問題。

一個相關的 KEP 引入了標準化大小引數

目前,CSI 臨時內聯卷仍處於 Beta 階段,同時正在討論此類問題。我們需要您的反饋來決定如何處理此功能。對於 KEP,上面連結的兩個 PR 是一個很好的評論之處。SIG Storage 也定期開會,可以透過 Slack 和郵件列表聯絡。