C
CYSKA
Consulting
EN
Navigation
OpenStack · Migration du stockage

Migrer des volumes Cinder entre deux OpenStack sans copier les données

Quand un OpenStack ancien (Rocky par exemple) et son remplaçant moderne partagent le même cluster Ceph, les volumes n'ont pas à se déplacer : l'ancien Cinder les oublie (unmanage) et le nouveau Cinder adopte les images RBD existantes (manage). Les données ne quittent jamais Ceph. Ce guide couvre la CLI openstack, l'ancienne CLI cinder et l'équivalent Ansible, ainsi que la voie snapshot/export pour les backends isolés.

Public : exploitants cloud Prérequis : backend Cinder RBD sur les deux clouds, identifiants admin Mise à jour : septembre 2026

1. Comment fonctionne manage / unmanage

Cinder conserve pour chaque volume un enregistrement en base et un objet sur le backend de stockage (pour Ceph, une image RBD nommée volume-UUID). Unmanage supprime uniquement l'enregistrement : l'image RBD reste intacte. Manage fait l'inverse : il crée un nouvel enregistrement pointant vers une image RBD existante. Enchaînés, les deux appels transfèrent la propriété d'un volume d'un Cinder à l'autre sans copier un seul octet.

Piège de nommage dans la CLI openstack

La CLI unifiée openstack ne possède pas de sous-commandes volume manage ou volume unmanage. Pour retirer un volume de la gestion de Cinder sans supprimer ses données sur le backend, utilisez openstack volume delete --remote. Pour gérer un volume déjà présent sur un backend, utilisez openstack volume create --remote-source avec --host ou --cluster. Ces opérations nécessitent des privilèges administrateur. La CLI dédiée cinder propose les commandes plus explicites cinder manage et cinder unmanage et reste documentée par OpenStack.

2. Préparer l'instance source

Un volume ne peut être unmanaged que si son statut est available. Arrêtez l'instance, notez tout ce qui servira à la reconstruire sur la cible (flavor, réseaux, IP fixes, groupes de sécurité, métadonnées, ordre des volumes), puis libérez les volumes. Le volume de boot ne doit pas être supprimé avec le serveur : vérifiez delete_on_termination avant de supprimer l'instance.

# Legacy cloud (source credentials loaded)
openstack server stop <VM_NAME>
openstack server show <VM_NAME> -f json > <VM_NAME>.source.json   # flavor, addresses, volumes_attached, metadata
openstack port list --server <VM_NAME> -f json > <VM_NAME>.ports.json

# Detach data volumes; make sure the boot volume survives the server deletion
openstack server remove volume <VM_NAME> <DATA_VOLUME_ID>
openstack server volume list <VM_NAME>          # delete_on_termination must be False on the boot volume
openstack server delete --wait <VM_NAME>

# Every volume to migrate must now be "available"
openstack volume list --status available

3. Unmanage sur l'ancien cloud

Notez d'abord l'UUID du volume et inventoriez ses snapshots. Si les snapshots doivent être conservés, unmanagez chacun d'eux avant le volume parent et conservez sa référence backend. Après les appels, les enregistrements disparaissent de l'ancien Cinder tandis que les objets RBD restent dans le pool.

# Legacy OpenStack: unmanage the volume — Cinder forgets it,
# the RBD image stays untouched in Ceph (this is not a data deletion)
openstack volume snapshot list --volume <VOLUME_ID>
openstack volume snapshot delete --remote <SNAPSHOT_ID>  # repeat for each snapshot first
openstack volume delete --remote <VOLUME_ID>
#   legacy cinder CLI equivalent: cinder unmanage <VOLUME_ID>

# Proof: the image is still there
rbd -p <CEPH_POOL> ls | grep volume-<VOLUME_ID>
rbd -p <CEPH_POOL> info volume-<VOLUME_ID>

4. Manage sur le nouveau cloud

L'argument --host désigne le backend Cinder propriétaire du pool, sous la forme host@backend#pool telle qu'affichée par openstack volume service list. Cinder attribue un nouvel UUID et le driver RBD renomme l'image en volume-NEW_ID. Le volume atterrit dans le projet des identifiants utilisés : lancez la commande avec le projet du tenant, ou transférez-le ensuite.

# New OpenStack (target credentials loaded, ideally scoped to the tenant project)
openstack volume service list                   # find the cinder-volume host, e.g. new-cinder-host@rbd
openstack block storage volume manageable list new-cinder-host@rbd#rbd   # lists RBD images not yet managed

# Adopt the existing RBD image as a Cinder volume
openstack volume create --remote-source source-name=volume-<VOLUME_ID> \
  --host new-cinder-host@rbd#rbd --type <VOLUME_TYPE> <VM_NAME>_disk
#   legacy cinder CLI equivalent: cinder manage --id-type source-name \
#     --name <VM_NAME>_disk --volume-type <VOLUME_TYPE> \
#     new-cinder-host@rbd#rbd volume-<VOLUME_ID>

# Restore what manage does not carry over: bootable flag and image metadata for the boot volume
openstack volume set --bootable <NEW_VOLUME_ID>
openstack volume set --image-property hw_disk_bus=virtio --image-property hw_vif_model=virtio \
  --image-property os_type=linux <NEW_VOLUME_ID>

# Rebuild the instance on the target cloud, reusing the recorded fixed IP if continuity requires it
openstack port create --network <NET_ID> --fixed-ip ip-address=<OLD_FIXED_IP> <VM_NAME>-port
openstack server create --volume <NEW_VOLUME_ID> --flavor <FLAVOR> \
  --port <VM_NAME>-port --security-group <SG> <VM_NAME>

5. Équivalent Ansible

La collection openstack.cloud expose les deux opérations dans un seul module. state: absent avec l'ID du volume réalise l'unmanage ; state: present avec source_name et host réalise le manage. L'unmanage est asynchrone côté Cinder, d'où la boucle de retry.

- name: Release Cinder volumes on the legacy cloud (unmanage, RBD images untouched)
  openstack.cloud.volume_manage:
    cloud: "{{ cloud_source }}"
    name: "{{ item.id }}"          # must be the Cinder volume ID when state is absent
    state: absent
  loop: "{{ migration_volumes }}"
  register: unmanage_result
  retries: 3
  delay: 3
  until: unmanage_result is succeeded

- name: Adopt the same RBD images on the target cloud (manage)
  openstack.cloud.volume_manage:
    cloud: "{{ cloud_target }}"
    name: "{{ item.name }}"
    source_name: "volume-{{ item.id }}"
    host: "{{ cinder_target_host }}"        # e.g. new-cinder-host@rbd#rbd
    volume_type: "{{ item.volume_type }}"
    bootable: "{{ item.bootable }}"
    state: present
  loop: "{{ migration_volumes }}"

6. Secours : snapshot, clone et export

Quand les deux clouds ne partagent pas de backend de stockage, les données doivent bouger. Snapshotez le volume, clonez le snapshot en volume, téléversez ce volume comme image Glance, transférez l'image (Glance vers Glance ou via S3), puis créez un volume à partir d'elle sur la cible. Notez que openstack image create --volume prend un volume, pas un snapshot.

# Legacy cloud: snapshot, clone to a volume, then upload the volume as a Glance image
openstack volume snapshot create --volume <OLD_VOL_ID> snap-mig
openstack volume create --snapshot snap-mig vol-mig
openstack image create --volume vol-mig img-mig-<VM_NAME>
openstack image save --file img-mig-<VM_NAME>.raw img-mig-<VM_NAME>

# New cloud: import the image and boot from a volume
openstack image create --file img-mig-<VM_NAME>.raw --disk-format raw --container-format bare img-mig-<VM_NAME>
openstack volume create --image img-mig-<VM_NAME> --size <SIZE_GB> <VM_NAME>_disk
openstack server create --volume <VM_NAME>_disk --flavor <FLAVOR> --network <NET_ID> <VM_NAME>

7. Points de vigilance

  • ■Les deux services Cinder doivent atteindre le même pool Ceph avec une clé client disposant de rwx dessus ; testez avec un volume jetable avant de toucher aux données de production.
  • ■Les snapshots de volume sont des ressources Cinder distinctes. Pour les conserver, unmanagez-les avant le volume parent, puis gérez le volume sur la cible avant ses snapshots avec openstack volume snapshot create --volume VOLUME_CIBLE --remote-source source-name=SNAPSHOT_BACKEND NOM_SNAPSHOT.
  • ■Les quotas s'appliquent sur la cible : un volume managed compte dans les quotas gigabytes et volumes du projet.
  • ■Conservez une table de correspondance ancien UUID → nouvel UUID → nom d'image RBD ; supervision, sauvegardes et CMDB référencent les IDs de volume.
  • ■Testez le retour arrière avec un volume jetable. Avant toute écriture côté cible, il consiste à unmanager les snapshots puis le volume sur la cible, et à remanager le volume puis ses snapshots sur la source. Après la reprise des écritures, utilisez un plan de réplication ou de restauration cohérent avec l'application au lieu de supposer qu'une inversion des métadonnées suffit.