Міграція обʼєктів Kubernetes за допомогою міграції версій сховища

СТАН ФУНКЦІОНАЛУ: Kubernetes v1.30 [alpha] (стандартно увімкнено: false)

Kubernetes покладається на активне переписування даних API, щоб підтримувати деякі дії обслуговування, повʼязані зі збереженням у спокої. Два видатні приклади цього — це версійна схема збережених ресурсів (тобто зміна перевіреної схеми збереження від v1 до v2 для певного ресурсу) та шифрування у спокої (тобто перезапис старих даних на основі зміни у способі шифрування даних).

Перш ніж ви розпочнете

Встановіть kubectl.

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Версія вашого Kubernetes сервера має бути не старішою ніж v1.30. Для перевірки версії введіть kubectl version.

Переконайтеся, що у вашому кластері увімкнено функціональні можливості StorageVersionMigrator та InformerResourceVersion. Для внесення цих змін вам знадобиться доступ адміністратора панелі управління.

Увімкніть REST API для міграції версій сховища, встановивши параметр конфігурації storagemigration.k8s.io/v1alpha1 на true для API-сервера. Для отримання додаткової інформації про те, як це зробити, прочитайте увімкнення або вимкнення API Kubernetes.

Перешифрування Secret Kubernetes за допомогою міграції версій сховища

  • Для початку, налаштуйте постачальника KMS для шифрування даних у спокої в etcd, використовуючи наступну конфігурацію шифрування.

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

    Переконайтеся, що автоматичне перезавантаження конфігурації шифрування встановлено на значення true, встановивши --encryption-provider-config-automatic-reload.

  • Створіть Secret за допомогою kubectl.

    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==
    
  • Щоб переконатися, що раніше створений секрет my-secret зашифровано новим ключем key2, ви будете використовувати Storage Version Migration.

  • Створіть маніфест StorageVersionMigration з назвою migrate-secret.yaml, наступного змісту:

    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
    
  • Спостерігайте за міграцією Secret, перевіряючи .status обʼєкта StorageVersionMigration. Успішна міграція повинна мати умову 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), і встановлено як бажана схема сховища. Коли настане час ввести v2 CRD, його можна додати для обслуговування лише з вебхуком. Це дозволяє плавний перехід, де користувачі можуть створювати CR за допомогою схеми v1 або v2, з вкбхуком, що виконує необхідну конвертацію схеми між ними. Перш ніж встановити v2 як бажану версію схеми сховища, важливо переконатися, що всі наявні CR, збережені як v1, мігрували на v2. Ця міграція може бути досягнута через Storage Version Migration для міграції всіх 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: <Інформація про CA Bundle>
        conversionReviewVersions:
        - v1
        - v2
    

    Створіть CRD за допомогою kubectl:

    kubectl apply -f test-crd.yaml
    
  • Створіть маніфест для прикладу testcrd. Назва маніфесту — cr1.yaml, з наступним змістом:

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

    Створіть CR за допомогою kubectl:

    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: <Інформація про CA Bundle>
          conversionReviewVersions:
            - v1
            - v2
    

    Оновіть CRD за допомогою kubectl:

    kubectl apply -f test-crd.yaml
    
  • Створіть файл ресурсу CR з назвою cr2.yaml наступного змісту:

    apiVersion: stable.example.com/v2
    kind: SelfieRequest
    metadata:
      name: cr2
      namespace: default
    
  • Створіть CR за допомогою kubectl:

    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, з наступним

змістом:

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.

Змінено September 19, 2024 at 6:45 PM PST: upstream sync (5177b0dd6f)