使用儲存版本遷移來遷移 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 版本時,可以新增 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 伺服器的額外參數。