Миграция Ceph CSI на shturval-ceph-csi

При обновлении до 2.15.0 по умолчанию выполняется миграция в кластере shturval-ceph-cephfs и shturval-ceph-rbd на shturval-ceph-csi. При необходимости миграции вручную выполните шаги инструкции до запуска обновления.

На странице описано, как перевести уже работающие в кластере сервисы shturval-ceph-cephfs и shturval-ceph-rbd на сервис shturval-ceph-csi без прерывания работы существующих томов. Данные в Ceph не будут утеряны, драйверы сохраняют прежние имена (cephfs.csi.ceph.com и rbd.csi.ceph.com).

Утилита миграции только читает данные кластера и записывает YAML на диск, объекты в кластере не изменяются.

До запуска скрипта миграции

Что нужноКак проверить
Оба модуля установлены и работают. У каждого SSC status.appliedMode — auto, status.ready — true.kubectl get shturvalserviceconfig shturval-ceph-cephfs shturval-ceph-rbd -o custom-columns=NAME:.metadata.name,MODE:.status.appliedMode,READY:.status.ready. В выводе MODE — auto, READY — true.
Файл kubeconfig с правом читать SSC и Secret в неймспейсах CSI. У модулей платформы это ceph-fs и ceph-rbd.kubectl --kubeconfig <файл> get shturvalserviceconfig shturval-ceph-cephfs и kubectl --kubeconfig <файл> get secret -n ceph-fs. То же для shturval-ceph-rbd и неймспейса ceph-rbd. Команды завершаются без ошибки доступа.
Go 1.26, Helm и kubectl.go version, helm version, kubectl version --client. В выводе Go — go1.26.
Каталог утилиты ceph-operator-migration. Команды ниже выполняются из него, манифесты появятся в ./manifests.В каталоге есть main.go, constants.go и README.md. Дальнейшие команды запускайте отсюда.
У CephFS и RBD разные spec.customvalues.csiConfig[0].clusterID. Одинаковый идентификатор даст двум ClientProfile одно metadata.name, в одном неймспейсе это конфликт. Проверьте до генерации манифестов.kubectl get shturvalserviceconfig shturval-ceph-cephfs shturval-ceph-rbd -o custom-columns=NAME:.metadata.name,CLUSTERID:.spec.customvalues.csiConfig[0].clusterID. Значения в колонке CLUSTERID различаются.

Сохраните вывод команд в текстовый файл в каталоге утилиты, например, pre-migration.txt. Сделайте это до выключения сервисов. После отключения сервисов Secret и StorageClass чарта удаляются, потом потребуется проверить, что Secret из backup вернулся в свой неймспейс, что старый StorageClass исчез, и какие поды нельзя перезапускать, пока CSI-поды оператора не станут Running.

  • Имя Secret (spec.customvalues.secret.name) и неймспейс (spec.namespace) каждого SSC.

    kubectl get shturvalserviceconfig shturval-ceph-cephfs shturval-ceph-rbd -o custom-columns=NAME:.metadata.name,NAMESPACE:.spec.namespace,SECRET:.spec.customvalues.secret.name
    
  • Имя StorageClass (spec.customvalues.storageClass.name), если оно задано.

    kubectl get shturvalserviceconfig shturval-ceph-cephfs shturval-ceph-rbd -o custom-columns=NAME:.metadata.name,STORAGECLASS:.spec.customvalues.storageClass.name
    
  • Список PVC, которые уже смонтированы. Их поды нельзя перезапускать, пока новые CSI-поды оператора не станут Running.

    kubectl get pvc -A --field-selector=status.phase=Bound
    

Не отключайте сервисы, пока миграция не завершиться и в каталоге manifests не появятся файлы. Утилита читает только включённые SSC и их Secret. Если перевести сервисы в режим Выкл раньше, Secret удалятся, и повторный запуск уже не сможет забрать учётные данные.

Если в кластере включён только один из двух модулей, миграция завершиться с ошибкой по отсутствующему SSC. Манифесты готового модуля при этом сохраняются. Для полного прогона оба сервиса должны быть готовы до запуска.

Шаг 1. Собрать утилиту и запустить миграцию

На этом шаге создаются YAML-манифесты и помещаются в каталог manifests/. В кластере ничего не применяется.

go build -o ceph-operator-migration .
./ceph-operator-migration --kubeconfig /path/to/kubeconfig.conf
ФлагОбязательныйПо умолчаниюКогда менять
--kubeconfigДанетПуть к kubeconfig. Без этого флага утилита не запустится.
--operator-namespaceНетceph-csi-operatorНужен другой неймспейс оператора. То же имя потом используйте в helm install -n.
--monitors-cephfsНетautoСписок мониторов CephFS через запятую, если его нельзя взять из SSC shturval-ceph-cephfs (spec.customvalues.csiConfig[0].monitors).
--monitors-rbdНетautoТо же для RBD и SSC shturval-ceph-rbd.
--sub-volume-groupНетcsiИмя группы подтомов CephFS в ClientProfile. Для модулей платформы группа называется csi.

Запуск без сборки: go run . --kubeconfig /path/to/kubeconfig.conf.

Сообщения saved ... пишутся в stderr. Код выхода 0 означает, что оба SSC прочитаны. Если в stderr есть error:, не переходите к следующему шагу - выключению сервисов: исправьте причину и запустите утилиту снова.

После успешного запуска в каталоге запуска должны быть созданы:

manifests/
├── step0/
│   └── namespace.yaml
├── backup/
│   ├── ceph-fs-csi-secret.yaml
│   └── ceph-rbd-csi-secret.yaml
├── step1/
│   ├── operator-images-configmap.yaml
│   ├── cephfs-driver.yaml
│   ├── rbd-driver.yaml
│   ├── ceph-fs-connection.yaml
│   ├── ceph-rbd-connection.yaml
│   ├── ceph-fs-client-profile.yaml
│   ├── ceph-rbd-client-profile.yaml
│   ├── ceph-fs-operator-secret.yaml
│   └── ceph-rbd-operator-secret.yaml
└── step2/
    ├── ceph-fs-storageclass.yaml
    └── ceph-rbd-storageclass.yaml

Образы CSI

В файл с образами CSI manifests/step1/operator-images-configmap.yaml - записываются адреса по умолчанию. Если поды должны браться из вашего реестра, замените их в этом файле и примените его на шаге 7. Пересобирать утилиту не нужно.

Ключ в файлеАдрес по умолчанию
pluginquay.io/cephcsi/cephcsi:v3.16.2
provisionerregistry.k8s.io/sig-storage/csi-provisioner:v6.0.0
attacherregistry.k8s.io/sig-storage/csi-attacher:v4.10.0
resizerregistry.k8s.io/sig-storage/csi-resizer:v2.0.0
snapshotterregistry.k8s.io/sig-storage/csi-snapshotter:v8.4.0
registrarregistry.k8s.io/sig-storage/csi-node-driver-registrar:v2.15.0

Проверьте перед выключением SSC:

  • В backup/ у Secret тот же metadata.name, что в SSC, и metadata.namespace равен исходному неймспейсу CSI (ceph-fs или ceph-rbd).
  • В step1/ те же Secret лежат уже в неймспейсе оператора.
  • В step1/*-connection.yaml список spec.monitors совпадает с мониторами соответствующего SSC.
  • В step2/ классы называются shturval-cephfs и shturval-rbd. Эти имена утилита задаёт сама, даже если в customvalues чарта класс назывался иначе.
  • parameters.clusterID, fsName (CephFS) и pool (RBD) совпадают с customvalues своего SSC.

Шаг 2. Выключить SSC

Два драйвера с одним именем одновременно работать не могут. Сначала снимается чартовый CSI, затем поднимается оператор.

Для Модуль Ceph CSI - CephFS и Модуль Ceph CSI - CephRBD:

  1. Сервисы и репозитории → Установленные сервисы.
  2. Найдите Модуль Ceph CSI - CephFS и смените режим управления на Выкл.
  3. Найдите Модуль Ceph CSI - CephRBD и смените режим управления на Выкл.

То же через kubectl. Сервисы не критические, снимать iscritical не нужно:

kubectl patch shturvalserviceconfig shturval-ceph-cephfs --type merge -p '{"spec":{"mode":"absent"}}'
kubectl patch shturvalserviceconfig shturval-ceph-rbd --type merge -p '{"spec":{"mode":"absent"}}'

Дождитесь, пока поды чартов удалятся:

kubectl get pods -n ceph-fs
kubectl get pods -n ceph-rbd

Выключение удаляет поды controller/node plugin и StorageClass, которые создал чарт. Объекты PersistentVolume и PersistentVolumeClaim не удаляются. Данные в Ceph остаются. Уже смонтированный том на узле продолжает работать: монтирование в ядре или через ceph-fuse уже выполнено.

После включения сервисов не перезапускайте поды с PVC, не делайте drain узлов и не перезагружайте узлы. Повторное монтирование зависнет.

Шаг 3. Убедиться, что старые StorageClass удалены

kubectl get storageclass shturval-cephfs shturval-rbd

Если в customvalues было другое имя класса, проверьте и его. Пустой вывод — ожидаемый результат.

Если StorageClass остался, удалите его:

kubectl delete storageclass shturval-cephfs shturval-rbd

Secret, PersistentVolume и PersistentVolumeClaim в неймспейсах старых драйверов не удаляйте.

Шаг 4. Вернуть Secrets в исходные неймспейсы

На шаге 1 были сохранены Secret в файлы manifests/backup/, который необходимо применить в кластере:

kubectl apply -f manifests/backup/

Secret возвращаются в неймспейсы, из которых утилита их прочитала (ceph-fs, ceph-rbd или фактический spec.namespace). Существующие PVC ссылаются на Secret именно там. Неймспейс Secret у уже созданного PVC сменить нельзя, поэтому этот шаг обязателен: без него том не смонтируется заново после рестарта пода.

Проверка:

kubectl get secret -n ceph-fs
kubectl get secret -n ceph-rbd

Имена должны совпасть с metadata.name в файлах backup/.

Шаг 5. Создать неймспейс оператора

kubectl apply -f manifests/step0/

Появится неймспейс ceph-csi-operator (или значение установленное флагом --operator-namespace на шаге 1).

Шаг 6. Установить чарт оператора

Чарт ceph-csi-operator/ceph-csi-operator из репозитория https://ceph.github.io/ceph-csi-operator/.

helm install ceph-csi-operator ceph-csi-operator/ceph-csi-operator \
  -n ceph-csi-operator --create-namespace=false \
  --values values.yaml

В неймспейсе оператора запускается один под: ceph-csi-operator-controller-manager. Поды CSI ещё не запущены. Они будут созданы после применения манифестов из step1.

Шаг 7. Применить манифесты и дождаться подов CSI

kubectl apply -f manifests/step1/
kubectl get pods -n ceph-csi-operator -w

К шагу 8 переходите, когда все поды неймспейса в статусе Running, включая поды на каждом узле, где должны монтироваться тома. ContainerCreating и CrashLoopBackOff означают, что новый плагин ещё не готов принимать remount. Смотрите события пода: чаще всего это недоступный образ из ConfigMap operator-images или ошибка в ClientProfile (мониторы, clusterID).

На этом этапе уже можно перезапустить под с существующим PVC и убедиться, что том монтируется снова. Секрет для этого монтирования берётся из каталога backup.

Шаг 8. Применить StorageClass

kubectl apply -f manifests/step2/
kubectl get storageclass shturval-cephfs shturval-rbd

Классы shturval-cephfs и shturval-rbd ссылаются на Secret в неймспейсе оператора. Они нужны новым PVC. Уже созданные PVC продолжают использовать Secret из шага 4 и прежнее имя драйвера в PV. Менять у них storageClassName не требуется.

Проверка нового тома: создайте PVC с storageClassName: shturval-cephfs или shturval-rbd, дождитесь Bound и запуска пода. Если PVC остаётся в Pending, смотрите kubectl describe pvc и логи provisioner в неймспейсе ceph-csi-operator.

Что попадает в манифесты

МанифестОткуда берутся поля
step0/namespace.yaml--operator-namespace
step1/operator-images-configmap.yamlконстанты Image* в constants.go
step1/cephfs-driver.yaml, step1/rbd-driver.yamlфиксированные имена драйверов и ссылка на ConfigMap operator-images
backup/*.yamlSecret из spec.namespace SSC, имя из spec.customvalues.secret.name. Аннотации meta.helm.sh/* и helm.sh/* убираются
step1/*-operator-secret.yamlте же данные Secret, неймспейс оператора
step1/ceph-fs-connection.yamlмониторы CephFS (--monitors-cephfs или SSC)
step1/ceph-rbd-connection.yamlмониторы RBD
step1/ceph-fs-client-profile.yamlmetadata.name = clusterID CephFS, группа подтомов --sub-volume-group, связь с cephfs-connection
step1/ceph-rbd-client-profile.yamlmetadata.name = clusterID RBD, связь с rbd-connection
step2/ceph-fs-storageclass.yamlимя shturval-cephfs, fsName и clusterID из SSC CephFS, Secret в неймспейсе оператора
step2/ceph-rbd-storageclass.yamlимя shturval-rbd, pool, imageFeatures и clusterID из SSC RBD. Пустой imageFeatures утилита заменяет на layering