Come funziona Tenax¶
Tenax è un operator Kubernetes. Tu dichiari dove vanno i backup, ogni quanto e per quanto tempo, e quali database; al resto pensa Tenax.
flowchart LR
subgraph Declared["Declared in git"]
S[BackupStore<br/>bucket + keys]
P[BackupPolicy<br/>schedule, retention, window]
T[BackupTarget<br/>one database]
end
subgraph Created["Created by Tenax or by you"]
B[Backup<br/>one full backup]
R[Restore<br/>to a sandbox, new DB, download, in place]
X[Sandbox<br/>a throwaway database]
end
T --> P --> S
T -. schedule .-> B
R -. sandbox .-> X
| Risorsa | Ambito | Chi la crea | Cos'è |
|---|---|---|---|
BackupStore |
cluster | tu | Un bucket S3, le sue credenziali e i destinatari age verso cui viene cifrato ogni oggetto. |
BackupPolicy |
namespace | tu (o i preset del chart) | Pianificazione, finestra point-in-time, livelli di conservazione, limiti, protezione dal carico, verifica, compressione. |
BackupTarget |
namespace, accanto al database | tu | Un server di database: engine, endpoint, credenziali, policy, controlli, maschere. |
Backup |
namespace del target | Tenax (pianificazione, backup immediato, riavvio della catena) | Un'esecuzione di backup completo. Solo gli ultimi vengono mantenuti come oggetti; S3 li conserva tutti. |
Restore |
namespace del target | tu, la console o la CLI | Un piano da un orario o un ID di backup verso una destinazione. |
Sandbox |
cluster | un Restore verso una sandbox |
Un database privato con un TTL, credenziali e una console di query. |
Il percorso dei dati¶
flowchart LR
db[(Postgres / MySQL)] -->|pg_basebackup, pg_dump, mysqldump| mover[mover Job]
db -->|WAL receiver, mysqlbinlog| streamer[streamer]
mover --> pipe[zstd → age → SHA-256 → parallel multipart]
streamer --> pipe
pipe --> s3[(S3 bucket<br/>manifest.json written last)]
s3 --> restorer[restorer Job<br/>verify → decrypt → replay → checks]
restorer --> dest[sandbox · new database · in place · download]
- Il controller si limita a pianificare. Mover e restorer sono Job; ogni target con point-in-time recovery ha un Deployment streamer. I byte non passano mai dal controller né dall'API.
- Niente si blocca. Nessun mount, iSCSI, FUSE o block device; i database si raggiungono solo via rete. Ogni chiamata di I/O ha una deadline, ogni flusso un watchdog sull'avanzamento, e i tool figli girano nel proprio process group, così vengono terminati insieme a esso.
- Crash-only. Qualsiasi pod può essere terminato in qualsiasi momento. Lo stato vive nei CRD e in S3, e un backup esiste solo quando il suo manifest è stato scritto per ultimo, quindi un backup scritto a metà non viene mai scambiato per uno completo.
Il catalogo e la console¶
All'avvio tenax-api elenca i manifest di ogni store e mantiene un indice in memoria: target, backup, segmenti di
modifiche e finestre point-in-time. Inventari e anteprime mascherate sono cifrati anche verso una chiave di catalogo
aggiuntiva, che può leggerli ma non può decifrare dump o WAL (ADR 0009). La cache
è usa e getta; S3 è la fonte di verità.