Zaroz
Operar servicios

Copias de seguridad y restauración del volumen de un servicio

Un servicio que guarda datos tiene un volumen. Una copia de seguridad es una instantánea de ese volumen que haces bajo demanda, conservas y a la que puedes devolver el volumen. Son tus instantáneas. Aparte, Zaroz mantiene sus propias copias de recuperación ante desastres de la plataforma; no se listan aquí y no es de ellas de donde restauras.

Los ejemplos usan el ayudante de Usar la API de Zaroz. {resource_id} es el id del recurso volumen del servicio: lista los recursos con GET /service-instances/{id}/resources y elige el de tipo volumen. Solo pueden hacer copias los servicios cuyo producto tiene almacenamiento y cuyo clúster admite instantáneas; consulta la entrada backups de las capacidades del servicio. Un servicio sin almacenamiento responde 404, igual que uno que no es tuyo.

Hacer una copia

curl

TerminalCode
B=/service-instances/$SERVICE/resources/$VOLUME/backups curl -sS -X POST "$ZAROZ_API$B" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"name": "before-upgrade"}' # 202: se ejecuta en segundo plano curl -sS "$ZAROZ_API$B" -H "$AUTH"
JSONCode
{ "backups": [ { "id": "…", "name": "before-upgrade", "status": "ready", "size_bytes": 482344960, "created_at": "2026-10-15T09:00:00Z", "completed_at": "2026-10-15T09:01:12Z", "restore_phase": null, "restore_started_at": null } ], "max_backups": 5 }

TypeScript

TypeScriptCode
import { call } from "./zaroz"; const B = `/service-instances/${SERVICE}/resources/${VOLUME}/backups`; await call("POST", B, { name: "before-upgrade" }); // sin nombre se usa uno con marca de tiempo for (;;) { const { body } = await call("GET", B); const b = body.backups.find((x: any) => x.name === "before-upgrade"); console.log(b.status, `${body.backups.length}/${body.max_backups}`); if (b.status === "ready" || b.status === "failed") break; await new Promise((r) => setTimeout(r, 5000)); }

Python

Code
import time from zaroz import call B = f"/service-instances/{SERVICE}/resources/{VOLUME}/backups" call("POST", B, {"name": "before-upgrade"}) # sin nombre se usa uno con marca de tiempo while True: _, body = call("GET", B) b = next(x for x in body["backups"] if x["name"] == "before-upgrade") print(b["status"], f"{len(body['backups'])}/{body['max_backups']}") if b["status"] in ("ready", "failed"): break time.sleep(5)
  • Una copia empieza en creating y se puede restaurar en ready. Una failed sigue en la lista hasta que la borras.
  • max_backups es el techo por volumen, publicado en el listado para que nunca lo fijes a mano. Pasado ese techo, crear responde un error de cuota: borra antes una antigua.
  • No puedes iniciar una copia mientras otra copia o una restauración se ejecutan en el mismo volumen (409).
  • Una copia es una instantánea del volumen tal como está en ese momento. Si necesitas una copia consistente a nivel de aplicación (una base de datos a mitad de transacción), deja de escribir antes o haz también el volcado propio de la base.

Restaurar

Restaurar es irreversible. Los workloads que usan el volumen se detienen, los datos del volumen se revierten a la instantánea y después arrancan de nuevo: se pierde todo cambio hecho desde la copia. Si puedes querer recuperar el estado actual, haz antes una copia de él. La copia debe estar ready.

curl

TerminalCode
curl -sS -X POST "$ZAROZ_API$B/$BACKUP/restore" -H "$AUTH" # 202; consulta el listado

TypeScript

TypeScriptCode
await call("POST", `${B}/${BACKUP_ID}/restore`); for (;;) { const { body } = await call("GET", B); const b = body.backups.find((x: any) => x.id === BACKUP_ID); console.log(b.status, b.restore_phase); if (b.status === "ready" && !b.restore_phase) break; await new Promise((r) => setTimeout(r, 10_000)); }

Python

Code
call("POST", f"{B}/{BACKUP_ID}/restore") while True: _, body = call("GET", B) b = next(x for x in body["backups"] if x["id"] == BACKUP_ID) print(b["status"], b["restore_phase"]) if b["status"] == "ready" and not b["restore_phase"]: break time.sleep(10)

Mientras restaura, la copia muestra status: "restoring" y un restore_phase que pasa por stopping_workloads, detaching_pre, maint_attaching, reverting, detaching_post, csi_retaining_pv, csi_recreating_pvc y restarting_workloads. Tarda varios minutos; los volúmenes grandes más. No inicies otra copia ni restauración entretanto (409). Usa restore_started_at para mostrar "restaurando desde hace N minutos".

Borrar una copia

TerminalCode
curl -sS -X DELETE "$ZAROZ_API$B/$BACKUP" -H "$AUTH" # 204
TypeScriptCode
await call("DELETE", `${B}/${BACKUP_ID}`);
Code
call("DELETE", f"{B}/{BACKUP_ID}")

Una copia en creating o restoring no se puede borrar; espera a que esté ready o failed. Borrar elimina la instantánea subyacente.

Cuánto ocupa el volumen

curl

TerminalCode
curl -sS "$ZAROZ_API/service-instances/$SERVICE/resources/$VOLUME/volume" -H "$AUTH" # {"capacity_bytes": 10737418240, "used_bytes": 2147483648, "used_fraction": 0.2, # "used_label": "2.0 GiB of 10 GiB", "mount_path": "/data", "last_backup_at": "2026-10-15T09:01:12Z"}
TypeScriptCode
const v = await call("GET", `/service-instances/${SERVICE}/resources/${VOLUME}/volume`); console.log(v.body.used_label, v.body.last_backup_at);
Code
_, v = call("GET", f"/service-instances/{SERVICE}/resources/{VOLUME}/volume") print(v["used_label"], v["last_backup_at"])

capacity_bytes es el tamaño configurado (una cuota, siempre presente). used_bytes se mide dentro del clúster y es null cuando no se puede medir, así que muestra "desconocido" en lugar de cero. last_backup_at te dice si tu rutina funciona.

Antes de fiarte

  • Las copias pertenecen al volumen y a su suscripción. No las tomes como la única copia de nada que no puedas perder si puedes borrar o cancelar el servicio.
  • Para guardar una copia fuera de Zaroz, copia los archivos (con las rutas de archivos o SFTP) o vuelca la base de datos al almacenamiento de objetos.
  • Automatízalo: un trabajo nocturno que cree una copia, espere a ready y borre la más antigua al llegar a max_backups son unas pocas líneas del código anterior. Usa un token con services.manage limitado a ese servicio.
Last modified on