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

Kubernetes 1.22:卷填充器的新設計

Kubernetes v1.22(本月早些時候釋出)引入了卷填充器的重新設計方法。最初在v1.18中實現,該API存在向後相容性問題。Kubernetes v1.22包含一個名為dataSourceRef的新API欄位,解決了這些問題。

資料來源

早期的Kubernetes版本已在PersistentVolumeClaim API中添加了dataSource欄位,用於克隆卷和從快照建立卷。您可以在建立新的PVC時使用dataSource欄位,引用同一名稱空間中現有的PVC或VolumeSnapshot。這也修改了正常的供應過程,使得新的PVC不再生成空卷,而是包含與克隆的PVC或克隆的VolumeSnapshot相同的資料。

卷填充器採用相同的設計理念,但將其擴充套件到任何型別的物件,只要存在用於定義資料來源的自定義資源和用於實現邏輯的填充器控制器。最初,dataSource欄位直接擴充套件以允許任意物件,前提是叢集上啟用了AnyVolumeDataSource特性門。不幸的是,這一更改導致了向後相容性問題,因此誕生了新的dataSourceRef欄位。

在v1.22中,如果啟用了AnyVolumeDataSource特性門,則會新增dataSourceRef欄位,其行為類似於dataSource欄位,但它允許指定任意物件。API伺服器確保這兩個欄位始終具有相同的內容,並且兩者都不可變。區別在於,在建立時,dataSource只允許PVC或VolumeSnapshot,並忽略所有其他值,而dataSourceRef允許大多數型別的物件,並且在少數情況下它不允許物件(除PVC之外的核心物件)時,會發生驗證錯誤。

當此API更改升級到穩定版時,我們將棄用使用dataSource並建議所有用例都使用dataSourceRef欄位。在v1.22版本中,dataSourceRef(作為Alpha功能)專門用於您想要自定義卷填充器的情況。

使用填充器

每個卷填充器都必須支援一個或多個CRD。管理員可以安裝CRD和填充器控制器,然後帶有dataSourceRef指定填充器支援的CR型別的PVC將由填充器控制器而不是CSI驅動直接處理。

在底層,CSI驅動仍然被呼叫來建立一個空卷,填充器控制器會用適當的資料填充它。PVC直到完全填充後才會繫結到PV,因此可以安全地定義一個完整的應用程式清單,包括Pod和PVC規範,並且Pod直到一切準備就緒後才會開始執行,就像PVC是另一個PVC或VolumeSnapshot的克隆一樣。

工作原理

具有資料來源的PVC仍然會被相關儲存類的外部供應器sidecar注意到(假設使用了CSI供應器),但由於sidecar不理解資料來源型別,它不會執行任何操作。填充器控制器也在監視具有它理解的資料來源型別的PVC,當它看到一個時,它會建立一個與原始PVC大小、卷模式、儲存類甚至拓撲(如果使用了拓撲)相同的臨時PVC。填充器控制器建立一個工作Pod,該Pod連線到卷並向其中寫入必要的資料,然後從卷中分離,填充器控制器將PV從臨時PVC重新繫結到原始PVC。

試一試

使用卷填充器需要以下事項:

  • 啟用AnyVolumeDataSource特性門
  • 安裝特定資料來源/填充器的CRD
  • 安裝填充器控制器本身

填充器控制器可以使用lib-volume-populator庫來完成大部分Kubernetes API級別的工作。單個填充器只需根據特定的CR例項提供實際將資料寫入卷的邏輯。此庫提供了一個示例填充器實現。

這些可選元件改進了使用者體驗:

  • 安裝VolumePopulator CRD
  • 為每個特定資料來源建立VolumePopulator自定義資源
  • 安裝卷資料來源驗證器控制器(Alpha)

這些元件的目的是針對沒有填充器的PVC上的資料來源生成警告事件。

整合起來

要了解其工作原理,您可以安裝示例“hello”填充器並試用。

首先安裝volume-data-source-validator控制器。

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/volume-data-source-validator/master/client/config/crd/populator.storage.k8s.io_volumepopulators.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/volume-data-source-validator/master/deploy/kubernetes/rbac-data-source-validator.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/volume-data-source-validator/master/deploy/kubernetes/setup-data-source-validator.yaml

接下來安裝示例填充器。

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/lib-volume-populator/master/example/hello-populator/crd.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/lib-volume-populator/master/example/hello-populator/deploy.yaml

建立一個帶有文字的Hello CR例項。

apiVersion: hello.k8s.io/v1alpha1
kind: Hello
metadata:
  name: example-hello
spec:
  fileName: example.txt
  fileContents: Hello, world!

建立一個將該CR作為其資料來源的PVC。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Mi
  dataSourceRef:
    apiGroup: hello.k8s.io
    kind: Hello
    name: example-hello
  volumeMode: Filesystem

接下來,執行一個讀取PVC中檔案的作業。

apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  template:
    spec:
      containers:
        - name: example-container
          image: busybox:latest
          command:
            - cat
            - /mnt/example.txt
          volumeMounts:
            - name: vol
              mountPath: /mnt
      restartPolicy: Never
      volumes:
        - name: vol
          persistentVolumeClaim:
            claimName: example-pvc

等待作業完成(包括所有依賴項)。

kubectl wait --for=condition=Complete job/example-job

最後檢查作業的日誌。

kubectl logs job/example-job
Hello, world!

請注意,卷中已經包含一個文字檔案,其中包含CR中的字串內容。這只是最簡單的示例。實際的填充器可以設定卷以包含任意內容。

如何編寫自己的卷填充器

有興趣編寫新填充器的開發人員,建議使用lib-volume-populator庫,並且只需提供圍繞該庫的小型控制器包裝器,以及一個能夠連線到卷並向卷寫入適當資料的Pod映象。

單個填充器可以非常通用,以便它們適用於所有型別的PVC,或者它們可以執行供應商特定的操作,以快速將資料填充到卷中,如果該卷是由同一供應商的特定CSI驅動程式提供的,例如,透過直接與該卷的儲存進行通訊。

未來

由於此功能仍處於Alpha階段,我們希望更新樹外控制器,提供更多測試和文件。社群計劃最終將填充器庫重新實現為sidecar,以簡化操作。

我們希望看到一些針對廣泛共享用例的官方社群支援的填充器。此外,我們預計卷填充器將被備份供應商用作將備份“恢復”到卷的一種方式,並且可能會演變出用於執行此操作的標準化API。

我如何瞭解更多資訊?

增強提案卷填充器包含了關於此功能的歷史和技術實現的詳細資訊。

在關於持久卷的文件主題中,卷填充器和資料來源解釋瞭如何在叢集中使用此功能。

請透過加入Kubernetes儲存SIG參與進來,幫助我們增強此功能。我們已經有很多好主意了,我們很高興能有更多!