使用儲存版本遷移來遷移 Kubernetes 物件

功能狀態: Kubernetes v1.30 [alpha] (預設停用:false)

Kubernetes 依賴主動重寫的 API 資料,以支援與靜態儲存相關的一些維護活動。兩個突出的例子是儲存資源的版本化架構(即給定資源的首選儲存架構從 v1 變更為 v2)和靜態加密(即基於資料應如何加密的變更來重寫過時的資料)。

開始之前

安裝 kubectl

您需要有一個 Kubernetes 叢集,並且必須將 kubectl 命令列工具配置為與您的叢集通信。建議在至少有兩個節點且未充當控制平面主機的叢集上執行本教學課程。如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用這些 Kubernetes 實驗環境之一

您的 Kubernetes 伺服器必須是 v1.30 或更高版本。若要檢查版本,請輸入 kubectl version

確保您的叢集已啟用 StorageVersionMigratorInformerResourceVersion 功能閘道。您將需要控制平面管理員存取權才能進行該變更。

透過將 API 伺服器的執行階段組態 storagemigration.k8s.io/v1alpha1 設定為 true 來啟用儲存版本遷移 REST API。有關如何執行此操作的更多資訊,請閱讀啟用或停用 Kubernetes API

使用儲存版本遷移重新加密 Kubernetes Secret

  • 首先,配置 KMS 提供者,以使用以下加密組態在 etcd 中加密靜態資料。

    kind: EncryptionConfiguration
    apiVersion: apiserver.config.k8s.io/v1
    resources:
    - resources:
      - secrets
      providers:
      - aescbc:
          keys:
          - name: key1
            secret: c2VjcmV0IGlzIHNlY3VyZQ==
    

    請務必將 --encryption-provider-config-automatic-reload 設定為 true,以啟用加密組態檔案的自動重新載入。

  • 使用 kubectl 建立 Secret。

    kubectl create secret generic my-secret --from-literal=key1=supersecret
    
  • 驗證該 Secret 物件的序列化資料是否以 k8s:enc:aescbc:v1:key1 為前綴。

  • 如下所示更新加密組態檔案以輪換加密金鑰。

    kind: EncryptionConfiguration
    apiVersion: apiserver.config.k8s.io/v1
    resources:
    - resources:
      - secrets
      providers:
      - aescbc:
          keys:
          - name: key2
            secret: c2VjcmV0IGlzIHNlY3VyZSwgaXMgaXQ/
      - aescbc:
          keys:
          - name: key1
            secret: c2VjcmV0IGlzIHNlY3VyZQ==
    
  • 為了確保先前建立的 secret my-secret 使用新金鑰 key2 重新加密,您將使用儲存版本遷移

  • 建立名為 migrate-secret.yaml 的 StorageVersionMigration 資訊清單,如下所示

    kind: StorageVersionMigration
    apiVersion: storagemigration.k8s.io/v1alpha1
    metadata:
      name: secrets-migration
    spec:
      resource:
        group: ""
        version: v1
        resource: secrets
    

    使用 kubectl 建立物件,如下所示

    kubectl apply -f migrate-secret.yaml
    
  • 透過檢查 StorageVersionMigration 的 .status 來監控 Secret 的遷移。成功的遷移應將其 Succeeded 條件設定為 true。如下所示取得 StorageVersionMigration 物件

    kubectl get storageversionmigration.storagemigration.k8s.io/secrets-migration -o yaml
    

    輸出類似於

    kind: StorageVersionMigration
    apiVersion: storagemigration.k8s.io/v1alpha1
    metadata:
      name: secrets-migration
      uid: 628f6922-a9cb-4514-b076-12d3c178967c
      resourceVersion: "90"
      creationTimestamp: "2024-03-12T20:29:45Z"
    spec:
      resource:
        group: ""
        version: v1
        resource: secrets
    status:
      conditions:
      - type: Running
        status: "False"
        lastUpdateTime: "2024-03-12T20:29:46Z"
        reason: StorageVersionMigrationInProgress
      - type: Succeeded
        status: "True"
        lastUpdateTime: "2024-03-12T20:29:46Z"
        reason: StorageVersionMigrationSucceeded
      resourceVersion: "84"
    
  • 驗證儲存的 secret 現在以 k8s:enc:aescbc:v1:key2 為前綴。

更新 CRD 的首選儲存架構

考慮一個情境,其中建立了一個 CustomResourceDefinition (CRD) 以服務自訂資源 (CR),並將其設定為偏好的儲存綱要。當需要引入 CRD 的 v2 版本時,可以新增 v2 版本僅用於服務,並搭配轉換 Webhook。這能實現更平順的轉換,讓使用者可以使用 v1 或 v2 綱要建立 CR,並透過 Webhook 執行它們之間必要的綱要轉換。在將 v2 設定為偏好的儲存綱要版本之前,務必確保所有現有的 v1 格式儲存的 CR 都已遷移至 v2。此遷移可以透過儲存版本遷移(Storage Version Migration)來完成,以將所有 CR 從 v1 遷移至 v2。

  • 建立 CRD 的 Manifest 檔案,命名為 test-crd.yaml,內容如下

    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: selfierequests.stable.example.com
    spec:
      group: stable.example.com
      names:
        plural: SelfieRequests
        singular: SelfieRequest
        kind: SelfieRequest
        listKind: SelfieRequestList
      scope: Namespaced
      versions:
      - name: v1
        served: true
        storage: true
        schema:
          openAPIV3Schema:
            type: object
            properties:
              hostPort:
                type: string
      conversion:
        strategy: Webhook
        webhook:
          clientConfig:
            url: "https://127.0.0.1:9443/crdconvert"
            caBundle: <CABundle info>
        conversionReviewVersions:
        - v1
        - v2
    

    使用 kubectl 建立 CRD

    kubectl apply -f test-crd.yaml
    
  • 建立範例 testcrd 的 Manifest 檔案。將 Manifest 檔案命名為 cr1.yaml 並使用以下內容

    apiVersion: stable.example.com/v1
    kind: SelfieRequest
    metadata:
      name: cr1
      namespace: default
    

    使用 kubectl 建立 CR

    kubectl apply -f cr1.yaml
    
  • 驗證 CR 已寫入並以 v1 格式儲存,方法是從 etcd 取得物件。

    ETCDCTL_API=3 etcdctl get /kubernetes.io/stable.example.com/testcrds/default/cr1 [...] | hexdump -C
    

    其中 [...] 包含連接到 etcd 伺服器的額外參數。

  • 更新 CRD test-crd.yaml 以包含 v2 版本用於服務和儲存,以及 v1 僅用於服務,如下所示

    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
    name: selfierequests.stable.example.com
    spec:
      group: stable.example.com
      names:
        plural: SelfieRequests
        singular: SelfieRequest
        kind: SelfieRequest
        listKind: SelfieRequestList
      scope: Namespaced
      versions:
        - name: v2
          served: true
          storage: true
          schema:
            openAPIV3Schema:
              type: object
              properties:
                host:
                  type: string
                port:
                  type: string
        - name: v1
          served: true
          storage: false
          schema:
            openAPIV3Schema:
              type: object
              properties:
                hostPort:
                  type: string
      conversion:
        strategy: Webhook
        webhook:
          clientConfig:
            url: "https://127.0.0.1:9443/crdconvert"
            caBundle: <CABundle info>
          conversionReviewVersions:
            - v1
            - v2
    

    使用 kubectl 更新 CRD

    kubectl apply -f test-crd.yaml
    
  • 建立 CR 資源檔案,命名為 cr2.yaml,內容如下

    apiVersion: stable.example.com/v2
    kind: SelfieRequest
    metadata:
      name: cr2
      namespace: default
    
  • 使用 kubectl 建立 CR

    kubectl apply -f cr2.yaml
    
  • 驗證 CR 已寫入並以 v2 格式儲存,方法是從 etcd 取得物件。

    ETCDCTL_API=3 etcdctl get /kubernetes.io/stable.example.com/testcrds/default/cr2 [...] | hexdump -C
    

    其中 [...] 包含連接到 etcd 伺服器的額外參數。

  • 建立名為 migrate-crd.yaml 的 StorageVersionMigration Manifest 檔案,內容如下

    kind: StorageVersionMigration
    apiVersion: storagemigration.k8s.io/v1alpha1
    metadata:
      name: crdsvm
    spec:
      resource:
        group: stable.example.com
        version: v1
        resource: SelfieRequest
    

    使用 kubectl 建立物件,如下所示

    kubectl apply -f migrate-crd.yaml
    
  • 使用狀態監控 Secret 的遷移。成功的遷移應在狀態欄位中將 Succeeded 條件設定為 "True"。取得遷移資源的方式如下

    kubectl get storageversionmigration.storagemigration.k8s.io/crdsvm -o yaml
    

    輸出類似於

    kind: StorageVersionMigration
    apiVersion: storagemigration.k8s.io/v1alpha1
    metadata:
      name: crdsvm
      uid: 13062fe4-32d7-47cc-9528-5067fa0c6ac8
      resourceVersion: "111"
      creationTimestamp: "2024-03-12T22:40:01Z"
    spec:
      resource:
        group: stable.example.com
        version: v1
        resource: testcrds
    status:
      conditions:
        - type: Running
          status: "False"
          lastUpdateTime: "2024-03-12T22:40:03Z"
          reason: StorageVersionMigrationInProgress
        - type: Succeeded
          status: "True"
          lastUpdateTime: "2024-03-12T22:40:03Z"
          reason: StorageVersionMigrationSucceeded
      resourceVersion: "106"
    
  • 驗證先前建立的 cr1 現在已寫入並以 v2 格式儲存,方法是從 etcd 取得物件。

    ETCDCTL_API=3 etcdctl get /kubernetes.io/stable.example.com/testcrds/default/cr1 [...] | hexdump -C
    

    其中 [...] 包含連接到 etcd 伺服器的額外參數。

上次修改時間:2024 年 11 月 13 日 太平洋標準時間上午 11:50:修正 EncryptionConfiguration 縮排 (d9298ddb3f)