使用儲存版本遷移 Kubernetes 物件
Kubernetes v1.30 [alpha]
(預設啟用:false)Kubernetes 依賴於主動重寫 API 資料,以支援一些與靜態儲存相關的維護活動。兩個顯著的例子是儲存資源的版本化模式(即,給定資源的首選儲存模式從 v1 變為 v2)和靜態加密(即,根據資料應如何加密的更改重寫舊資料)。
準備工作
安裝 kubectl
。
你需要有一個 Kubernetes 叢集,並且 kubectl 命令列工具必須配置為與你的叢集通訊。建議在至少有兩個不作為控制平面主機的節點的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用以下 Kubernetes 演練場之一
你的 Kubernetes 伺服器版本必須是 v1.30 或更高版本。要檢查版本,請輸入 kubectl version
。
確保你的叢集已啟用 StorageVersionMigrator
和 InformerResourceVersion
特性門控。你需要控制平面管理員許可權才能進行此更改。
透過將 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 版本時,可以僅透過轉換 Webhook 新增它以供服務。這使得過渡更加順暢,使用者可以使用 v1 或 v2 模式建立 CR,並透過 Webhook 在它們之間執行必要的模式轉換。在將 v2 設定為首選儲存模式版本之前,重要的是要確保所有儲存為 v1 的現有 CR 都已遷移到 v2。這種遷移可以透過 **儲存版本遷移** 來實現,將所有 CR 從 v1 遷移到 v2。
為 CRD 建立一個名為
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 建立一個清單。將清單命名為
cr1.yaml
並使用以下內容apiVersion: stable.example.com/v1 kind: SelfieRequest metadata: name: cr1 namespace: default
使用 kubectl 建立 CR
kubectl apply -f cr1.yaml
透過從 etcd 獲取物件來驗證 CR 是否以 v1 寫入和儲存。
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
建立名為
cr2.yaml
的 CR 資原始檔,內容如下apiVersion: stable.example.com/v2 kind: SelfieRequest metadata: name: cr2 namespace: default
使用 kubectl 建立 CR
kubectl apply -f cr2.yaml
透過從 etcd 獲取物件來驗證 CR 是否以 v2 寫入和儲存。
ETCDCTL_API=3 etcdctl get /kubernetes.io/stable.example.com/testcrds/default/cr2 [...] | hexdump -C
其中
[...]
包含連線到 etcd 伺服器的附加引數。建立一個名為
migrate-crd.yaml
的 StorageVersionMigration 清單,內容如下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"
透過從 etcd 獲取物件來驗證之前建立的 cr1 現在是否以 v2 寫入和儲存。
ETCDCTL_API=3 etcdctl get /kubernetes.io/stable.example.com/testcrds/default/cr1 [...] | hexdump -C
其中
[...]
包含連線到 etcd 伺服器的附加引數。