Aller au contenu
6 minutes

Snapshots orphelins et points oubliés : nettoyer sans casser une sauvegarde

NCC liste les snapshots dont la VM a disparu, l’API v4 dit qui a créé chaque recovery point. Lire d’abord, écarter ce qui appartient à une sauvegarde, puis supprimer un par un.

Snapshots orphelins et points oubliés : nettoyer sans casser une sauvegarde

Un snapshot pris « juste avant l’intervention » survit souvent à l’intervention, parfois à la VM elle-même, et garde ses blocs tant que personne ne le supprime. Le supprimer tient en une commande ; s’assurer qu’il n’appartient à aucune sauvegarde demande une méthode.

Ce que NCC remonte

Le contrôle NCC orphan_vm_snapshot_check liste les snapshots de VM dont la VM n’existe plus. Un employé Nutanix le rappelait sur le forum en 2020, renvoyant au KB-3752 avec une consigne : toujours vérifier que la VM a bien disparu.

Observé en AOS 6.10.1, 7.3.1.2 et 7.3.1.6 : il sort en INFO, pas en WARN, donc facile à laisser filer.

/health_checks/hypervisor_checks/orphan_vm_snapshot_check   [ INFO ]
INFO: Found N orphan VM snapshot(s): ['<uuid>', '<uuid>', ...]

Les noms trouvés parlaient d’eux-mêmes : référence de change, BEFORE-NGT, « post install », « reboot ok ». Des snapshots manuels d’avant intervention, les plus anciens créés en 2022. Pour la lecture d’un rapport NCC en général, voir ce billet.

Lire avant de supprimer

La séquence publiée sur un blog communautaire en 2018 (commandes à lancer sur une CVM) :

ncc health_checks hypervisor_checks orphan_vm_snapshot_check
acli snapshot.get <uuid_snapshot>     # nom, date de création, vm_uuid
acli vm.get <vm_uuid>                 # doit répondre que la VM est introuvable

snapshot.get rend le nom, create_time_usecs, le vm_uuid et une copie de la configuration de la VM (vm_spec), nom et annotation compris : de quoi retrouver la machine, et son propriétaire si l’annotation le mentionne.

Trois règles avant toute suppression :

  • Relire l’état. Entre le rapport et le traitement, des UUID avaient déjà été supprimés : snapshot.get répondait kNotFound, « Unknown snapshots ». Retirez-les.
  • Rien de moins de 24 heures. Un snapshot récent peut appartenir à une sauvegarde en cours.
  • Rien qui appartienne à un Protection Domain ou à un outil tiers. Ceux-là se nettoient depuis leur outil (voir ce cas).

Deux pièges d’automatisation

Le parseur. L’en-tête du rapport NCC contient l’UUID du cluster, qu’une regex générique prend pour un snapshot. Ne lisez que la ligne Found N orphan VM snapshot(s).

La confirmation. Observé sur les trois versions : acli snapshot.delete demande Delete 1 snapshots? (yes/no) et attend. Lancée en SSH non interactif, la commande reste suspendue. Répondez explicitement, un UUID par appel, après la simulation, avec un délai maximal :

echo yes | timeout 120 acli snapshot.delete <uuid_snapshot>

La sortie passe de <nom>: pending à <nom>: complete ; puis, sur le cluster où il a été relancé, le contrôle NCC est revenu en PASS.

Côté Prism Central : les recovery points

Snapshot ou recovery point : la différence est expliquée ici. D’après la documentation, non testé ici : l’API v4 les liste sur /api/dataprotection/v4.0/config/recovery-points. Le SDK documente creationTime, expirationTime, date à laquelle le point « expires and will be garbage collected », et ownerExtId, posé à la création, qui identifie son créateur. En lecture seule :

import os
import requests

pc = os.environ["PC_HOST"]
s = requests.Session()
s.auth = (os.environ["PC_USER"], os.environ["PC_PASSWORD"])
s.verify = os.environ.get("PC_CA_BUNDLE") or True   # bundle dédié, sinon magasin par défaut ; jamais False
url = f"https://{pc}:9440/api/dataprotection/v4.0/config/recovery-points"

page = 0
while True:
    r = s.get(url, params={"$page": page, "$limit": 100, "$orderby": "creationTime"}, timeout=30)
    r.raise_for_status()
    points = r.json().get("data") or []
    for p in points:
        print(p.get("creationTime"), p.get("expirationTime"), p.get("ownerExtId"), p.get("name"), sep=" | ")
    if len(points) < 100:
        break
    page += 1

Si l’outil de sauvegarde crée ses points avec un compte dédié, ownerExtId porte l’identifiant de ce compte : vérifiez-le sur un point connu avant de vous en servir comme filtre. Ces points-là restent à leur rétention. Un point ancien, créé par une personne, sans expiration ou à expiration lointaine, est un candidat.

Pour supprimer : DELETE sur .../recovery-points/{extId}. Le guide de l’API rend l’ETag obligatoire sur toute entité existante, en If-Match, avec un Ntnx-Request-Id ; l’exemple officiel nutanixdev lit l’ETag par un GET juste avant. Moins brutal, set_recovery_point_expiration_time fixe une échéance au lieu de supprimer sur-le-champ.

L’espace, lui, revient au fil des scans Curator, et seulement pour les blocs exclusifs (détail).

Ce qu’il faut retenir

  • orphan_vm_snapshot_check liste les snapshots dont la VM a disparu, en INFO : ne l’ignorez pas.
  • acli snapshot.get et acli vm.get avant toute suppression, sur un état relu.
  • acli snapshot.delete attend un yes : sans lui, un script reste bloqué.
  • ownerExtId et expirationTime disent qui a créé un recovery point et quand il partira.
  • Ce qui appartient à une sauvegarde se nettoie depuis la sauvegarde.

In English

NCC lists snapshots whose VM has disappeared, and the v4 API tells who created each recovery point. Read first, set aside anything owned by a backup, then delete one at a time. acli snapshot.delete waits for a yes/no confirmation that blocks a non-interactive SSH script, and a recovery point is deleted by DELETE on its extId with the ETag passed in If-Match.

Sources & vérification

Testé sur : AOS 6.10.1, 7.3.1.2 et 7.3.1.6, NCC 5.3.1.1 (partie recovery points v4 : documentation, non testée)

Comment les billets sont vérifiés et corrigés