Μετάβαση στο περιεχόμενο

Αντίγραφα VM

Το BombVault αντιγράφει VMs KVM/libvirt χωρίς να προσαρτά καμία διαδρομή libvirt. Τρέχει το virsh στον host μέσω SSH (qemu+ssh://), διαβάζει και γράφει τους δίσκους των VM μέσω του mount Host Data (το /mnt του host είναι το /host/user στο κοντέινερ) και αντιγράφει το UEFI NVRAM μέσω SSH. Επειδή τίποτα που ανήκει στο libvirt δεν προσαρτάται με bind, το BombVault δεν μπορεί ποτέ να μπει εμπόδιο στον VM Manager του Unraid.

Αυτός ο οδηγός καλύπτει τη ρύθμιση, τις μεθόδους αντιγράφου, τις VMs με στιγμιότυπα Unraid και το TrueNAS SCALE. Τα αντίγραφα κοντέινερ δεν χρειάζονται τίποτα από αυτά.

Τα αντίγραφα συνόλων δεδομένων ZFS χρησιμοποιούν την ίδια σύνδεση SSH, με το ίδιο κλειδί, host και χρήστη. Μόλις συνδεθούν τα αντίγραφα VM, συνδέονται και τα στοιχεία συνόλων δεδομένων ZFS. Δείτε Σύνολα δεδομένων ZFS.

Τι ρυθμίζετε

Ρύθμιση Πού Προεπιλογή Τι σημαίνει
Host SSH: Address (LIBVIRT_HOST) μεταβλητή template host.docker.internal Ο host Unraid, που προσεγγίζεται μέσω SSH
Host SSH: Port (LIBVIRT_SSH_PORT) μεταβλητή template 22 Η θύρα SSH του Unraid
Host SSH: User (LIBVIRT_SSH_USER) μεταβλητή template root Ο χρήστης SSH στον host
Δημόσιο κλειδί Ρυθμίσεις, Ενσωματώσεις, SSH κεντρικού συστήματος δημιουργείται στην πρώτη εκκίνηση Εξουσιοδοτήστε το στον host

Το BombVault φτιάχνει το ζεύγος κλειδιών SSH στην πρώτη εκκίνηση στο /config/ssh/id_ed25519, αποθηκευμένο στο appdata. Το κλειδί του host καρφιτσώνεται στο /config/ssh/known_hosts στην πρώτη σύνδεση.

Το template γεμίζει το Host SSH: Address με το placeholder 192.168.x.x. Το BombVault το θεωρεί μη ορισμένο και δοκιμάζει το host.docker.internal, που λειτουργεί στο προεπιλεγμένο δίκτυο bridge. Σε προσαρμοσμένο δίκτυο, αντικαταστήστε το με τη LAN IP του host (βήμα 3 Β).

Βήμα 1: Ενεργοποιήστε το SSH στον host Unraid

  1. Στο Unraid, ανοίξτε Settings, Management Access και ορίστε το Use SSH σε Yes.
  2. Αν αλλάξατε τη θύρα SSH, σημειώστε την. Το Host SSH: Port πρέπει να ταιριάζει.

Βήμα 2: Εξουσιοδοτήστε το δημόσιο κλειδί του BombVault

Το /root του Unraid ζει στη μνήμη και σβήνεται σε κάθε εκκίνηση, οπότε το κλειδί πρέπει να βρίσκεται και στη μονάδα flash. Τρέξτε αυτό στο τερματικό του Unraid:

K=$(docker exec BombVault cat /config/ssh/id_ed25519.pub)
mkdir -p /root/.ssh /boot/config/ssh && chmod 700 /root/.ssh
grep -qxF "$K" /root/.ssh/authorized_keys 2>/dev/null  || echo "$K" >> /root/.ssh/authorized_keys
grep -qxF "$K" /boot/config/ssh/root.pubkeys 2>/dev/null || echo "$K" >> /boot/config/ssh/root.pubkeys
chmod 600 /root/.ssh/authorized_keys

Το Unraid 6.9 και νεότερο αντιγράφει το /boot/config/ssh/root.pubkeys στο authorized_keys του root σε κάθε εκκίνηση, οπότε αυτό επιβιώνει των επανεκκινήσεων. Ισχύει για κάθε σύνδεση root, όποιο όνομα host ή θύρα κι αν χρησιμοποιεί το BombVault.

Βήμα 3: Δικτύωση

Το BombVault πρέπει να ανοίξει μια σύνδεση TCP από το κοντέινερ προς τη θύρα SSH του host. Διαλέξτε την περίπτωση που ταιριάζει στη ρύθμισή σας.

Α. Το BombVault στο προεπιλεγμένο δίκτυο bridge

  • Αφήστε το Host SSH: Address στο host.docker.internal ή στο placeholder του template. Το template προσθέτει --add-host=host.docker.internal:host-gateway, που δείχνει στην πύλη docker0, δηλαδή στον host.
  • Ορίστε το Host SSH: Port στη θύρα SSH σας.

Β. Το BombVault σε προσαρμοσμένο δίκτυο

Ένα κοντέινερ σε br0.x, macvlan ή ipvlan δεν μπορεί να φτάσει τον host μέσω host.docker.internal, γιατί το 172.17.0.1 είναι το docker0 και δεν προσεγγίζεται από το br0.x. Αντί γι' αυτό:

  1. Στο Unraid, ορίστε το Settings, Docker, Host access to custom networks σε Enabled.
  2. Ορίστε το Host SSH: Address στη LAN IP του host Unraid, τη διεύθυνση στην οποία ανοίγετε το web UI.
  3. Αν το δίκτυο του κοντέινερ και ο host βρίσκονται σε διαφορετικά VLAN, επιτρέψτε τη διαδρομή στον router ή στο firewall σας: από το VLAN του κοντέινερ προς την IP του host στη θύρα SSH, μέσω TCP.
  4. Αν η LAN IP του host εξακολουθεί να μη φτάνει, χρησιμοποιήστε την IP shim του host στο υποδίκτυο του κοντέινερ. Βρείτε την στον host με ip -4 addr show | grep -B2 <container-subnet>.

Ελέγξτε ότι ο host απαντά

Τρέξτε αυτό στο τερματικό του Unraid, με την IP και τη θύρα σας:

docker exec BombVault timeout 6 bash -c 'echo > /dev/tcp/192.168.1.10/22' && echo OPEN || echo UNREACHABLE

Το OPEN σημαίνει ότι η διαδρομή δουλεύει. Το UNREACHABLE σημαίνει ότι η δικτύωση του βήματος 3 θέλει διόρθωση πριν από οτιδήποτε άλλο.

Βήμα 4: Ορίστε τις μεταβλητές και δοκιμάστε

  1. Στο Unraid, ανοίξτε το Docker, κάντε κλικ στο BombVault, επιλέξτε Edit, ορίστε το Host SSH: Address (και το Host SSH: Port αν δεν είναι 22) και πατήστε Apply. Αν οι μεταβλητές λείπουν, εισαγάγετε ξανά το template, γιατί το Unraid κρατά την αποθηκευμένη διαμόρφωση ενός υπάρχοντος κοντέινερ.
  2. Στο BombVault, ανοίξτε τις Ρυθμίσεις, Ενσωματώσεις, SSH κεντρικού συστήματος και πατήστε Δοκιμή σύνδεσης. Πρέπει να γίνει πράσινο.

Η ίδια κλήση από το τερματικό απαριθμεί τις VMs σας:

docker exec BombVault virsh -c "qemu+ssh://root@192.168.1.10:22/system?keyfile=/config/ssh/id_ed25519&known_hosts=/config/ssh/known_hosts&known_hosts_verify=auto" list --all

Βήμα 5: Η μέθοδος ανά VM

Κάθε VM έχει μια Μέθοδος στην κάρτα VM της καρτέλας Ρυθμίσεών της (ανοίξτε τη VM κάτω από τα Αντίγραφα ασφαλείας):

  • Η Ομαλή (τερματισμός) είναι η προεπιλογή. Τερματίζει τη VM, αντιγράφει τους δίσκους και την ξεκινά ξανά, οπότε το αντίγραφο είναι πάντα συνεπές. Περιμένει έως δέκα λεπτά να τερματιστεί ο guest και δεν τον σβήνει ποτέ διά της βίας. Ένας guest που τρέχει ακόμα μετά από αυτό αφήνεται ήσυχος, και το αντίγραφο αποτυγχάνει με τον λόγο. Αν ο guest σβήσει μέσα στην επόμενη ώρα, το BombVault τον ξεκινά ξανά. Αν αυτή η εκκίνηση αποτύχει, η αποτυχημένη εκτέλεση το λέει.
  • Το Ζωντανό στιγμιότυπο αντιγράφει μια VM που τρέχει μέσω ενός εξωτερικού στιγμιοτύπου και blockcommit. Χρειάζεται τον δίσκο στο /mnt/cache ή /mnt/diskX, όχι στο /mnt/user. Με τον qemu guest agent στη VM το στιγμιότυπο γίνεται με ησυχασμένο σύστημα αρχείων, και χωρίς αυτόν είναι συνεπές ως προς κατάρρευση (crash-consistent). Σε μια VM που είναι σβηστή, το Ζωντανό πέφτει μόνο του σε Ομαλή. Όταν δεν μπορεί να γίνει το στιγμιότυπο, εκείνο το αντίγραφο αποτυγχάνει και η VM συνεχίζει να τρέχει, αφού μια VM που επιλέξατε να αντιγράφεται ζωντανά δεν τερματίζεται ποτέ γι' αυτό.

Τι αφήνει έξω ένα αντίγραφο

Ένα αντίγραφο μπορεί να πετύχει και παρ' όλα αυτά να μην περιέχει ολόκληρη τη VM. Η εκτέλεση φέρει τότε μια σημείωση σε προειδοποιητικό τόνο που ονομάζει τι λείπει:

  • Δίσκοι που το BombVault δεν διαβάζει. Ένας δίσκος μόνο για ανάγνωση, ένα lun και ένας δίσκος network ή volume μένουν έξω, και η σημείωση ονομάζει τον καθένα με τη συσκευή προορισμού και το είδος του. Ο ορισμός στο αντίγραφο εξακολουθεί να τους απαριθμεί. Ένα cdrom και μια δισκέτα δεν ονομάζονται. Μια απλή συσκευή μπλοκ που δεν είναι ZFS zvol κάνει αντίθετα το αντίγραφο να αποτύχει.
  • Η κατάσταση ενός εξομοιωμένου TPM. Δεν έχει διαδρομή στο XML του domain. Ο VM Manager του Unraid στήνει ένα τέτοιο TPM για μια VM με το BIOS OVMF TPM, οπότε η σημείωση εμφανίζεται και στο Unraid. Ένας guest που κρατά ένα μυστικό στο TPM του, όπως μπορεί το BitLocker, μπορεί να ζητήσει το κλειδί ανάκτησής του μετά από μια επαναφορά που χάνει αυτή την κατάσταση, οπότε κρατήστε αυτό το κλειδί πρόχειρο.

Λεπτοί δίσκοι

Μια επαναφορά κρατά έναν λεπτό (thin) δίσκο λεπτό, είτε αντικαθιστά τον δίσκο είτε γράφει νέο: το restic γράφει τις σειρές μηδενικών ως κενά σε ένα νέο αρχείο, και το BombVault επιστρέφει τα μηδενικά μπλοκ ενός αρχείου που αντικαταστάθηκε με fallocate --dig-holes μόλις γραφτεί. Όσο το restic αντικαθιστά ένα αρχείο, αυτό το αρχείο πιάνει όλο το μέγεθός του, αν το pool έχει τον χώρο. Ένα σύστημα αρχείων χωρίς hole punching κρατά τον δίσκο σε όλο το μέγεθός του, και το αρχείο καταγραφής το λέει. Ο έλεγχος χώρου μετράει πάντως έναν νέο δίσκο σε όλο το μέγεθός του.

Μια επαναφορά που αποτυγχάνει

Μια επαναφορά στη θέση του πρωτοτύπου σβήνει τη VM, γράφει τους δίσκους, και αντικαθιστά τον ορισμό και το NVRAM μόνο αφού γραφτούν οι δίσκοι. Μια επαναφορά που αποτυγχάνει αφήνει τη VM ορισμένη με το NVRAM της. Αν οι δίσκοι της δεν άλλαξαν και έτρεχε, τρέχει ξανά. Αν μπορεί να άλλαξαν, μένει σβηστή, αφού η εκκίνηση από έναν μισογραμμένο δίσκο θα έγραφε πάνω του, και η εκτέλεση το λέει. Η επαναφορά του ίδιου αντιγράφου ξανά ολοκληρώνει τη δουλειά.

Στιγμιότυπα καταγεγραμμένα στο libvirt, που δεν είναι ο τρόπος με τον οποίο τα φτιάχνει ο VM Manager του Unraid, σταματούν μια επαναφορά στη θέση του πρωτοτύπου πριν αγγιχτεί η VM, γιατί το libvirt δεν μπορεί να αφαιρέσει μια VM που τα έχει. Διαγράψτε τα πρώτα.

Μόνο αλλαγμένα μπλοκ

Μια VM με δίσκους qcow2 μπορεί να αντιγραφεί διαβάζοντας μόνο ό,τι άλλαξε. Ενεργοποιήστε το Μόνο αλλαγμένα μπλοκ στην ίδια κάρτα, και το BombVault χρησιμοποιεί το API αντιγράφων του libvirt αντί για την παραπάνω μέθοδο:

  • Ξεκινά μια εργασία αντιγράφου σε λειτουργία pull (virsh backup-begin) που δημιουργεί ένα checkpoint με όνομα bombvault-<time> την ίδια στιγμή, και διαβάζει τους δίσκους μέσω της σύνδεσης SSH από ένα προωθημένο socket Unix. Όταν ο guest agent απαντά, τα συστήματα αρχείων του guest παγώνουν μόνο όσο ξεκινά η εργασία. Μια απόψυξη που αποτυγχάνει δοκιμάζεται ξανά για περίπου δεκαπέντε δευτερόλεπτα, και αν ο guest δεν ξεπαγώσει ακόμα, το BombVault στέλνει ειδοποίηση.
  • Η πρώτη εκτέλεση διαβάζει κάθε εκχωρημένο μπλοκ. Οι επόμενες διαβάζουν μόνο τα μπλοκ που το bitmap του checkpoint σημειώνει ως γραμμένα από το προηγούμενο αντίγραφο.
  • Κάθε δίσκος αποθηκεύεται ως φάκελος τμημάτων σταθερού μεγέθους που κρατούν ό,τι βλέπει ο guest. Τα τμήματα που δεν άλλαξαν παραλαμβάνονται από το προηγούμενο στιγμιότυπο χωρίς να διαβαστούν, οπότε κάθε στιγμιότυπο είναι πλήρες και επαναφέρεται μόνο του.
  • Μια επαναφορά ξαναχτίζει τον δίσκο από τα τμήματά του και τον μετατρέπει πάλι σε qcow2 με qemu-img. Ο δίσκος έχει το ίδιο περιεχόμενο όπως τη στιγμή του αντιγράφου, αλλά το αρχείο είναι ένα νέο αρχείο qcow2, και μια αλυσίδα backing επιστρέφει εξομαλυμένη.
  • Ο έλεγχος πριν από μια τέτοια επαναφορά απαριθμεί κάθε δίσκο που ξαναχτίζει και τον μετρά στο πλήρες μέγεθος του guest, δύο φορές για qcow2, αφού η ακατέργαστη εικόνα και το μετατρεμμένο αντίγραφό της στέκονται δίπλα δίπλα μέχρι να αντικατασταθεί το παλιό αρχείο. Αυτό είναι το περισσότερο που μπορεί να πιάσει ένας δίσκος, οπότε μια έλλειψη με αυτή τη μέτρηση αφήνει τη γραμμή χώρου γκρι αντί να μπλοκάρει. Ο έλεγχος επαναφοράς μετά το πρώτο αντίγραφο, και ο Έλεγχος επαναφοράς, βεβαιώνονται επίσης ότι το στιγμιότυπο κρατά κάθε τμήμα κάθε δίσκου στο μέγεθος που πρέπει.
  • Ανάμεσα στις εκτελέσεις η VM δεν έχει καταγεγραμμένο checkpoint στο libvirt. Το BombVault κρατά τον ορισμό του νεότερου checkpoint bombvault- κάτω από το /config/vm-checkpoints και αφαιρεί μόνο την καταγραφή του libvirt (virsh checkpoint-delete --metadata). Το bitmap του μένει στο αρχείο qcow2 και συνεχίζει να μετρά εγγραφές, και η επόμενη εκτέλεση βάζει το checkpoint πίσω (virsh checkpoint-create --redefine) πριν ξεκινήσει. Το libvirt αρνείται να καταργήσει τον ορισμό μιας VM που έχει checkpoints, οπότε αυτό αφήνει το Remove VM του Unraid και μια επαναφορά να λειτουργούν κανονικά.
  • Μια εργασία αντιγράφου που το BombVault άφησε να τρέχει, επειδή σταμάτησε στη μέση ενός αντιγράφου, τερματίζεται όταν το BombVault ξεκινά ξανά, μαζί με τα checkpoints που άφησε εκείνη η εκτέλεση στην καταγραφή.
  • Η απενεργοποίηση του διακόπτη, η αφαίρεση της VM από το χρονοδιάγραμμα ή η διαγραφή των αντιγράφων της τερματίζει επίσης μια τέτοια εργασία, και διαγράφει και το bitmap όσο τρέχει η VM. Σε μια VM που είναι σβηστή, το libvirt δεν μπορεί να το διαγράψει, και μένει στην εικόνα αχρησιμοποίητο.
  • Τα checkpoints άλλων εργαλείων αφήνονται ήσυχα. Μια VM που έχει κάποια δεν μπορεί να επαναφερθεί μέχρι να διαγραφούν, και η επαναφορά σταματά πριν αγγίξει τη VM.

Ο διακόπτης πέφτει πίσω μόνος του. Ένα checkpoint που λείπει ή είναι χαλασμένο, ένας δίσκος που άλλαξε μέγεθος, ή ένα νεότερο στιγμιότυπο που δεν είναι αλλαγμένων μπλοκ σημαίνει ότι ο δίσκος διαβάζεται ολόκληρος άλλη μία φορά. Μια VM που είναι σβηστή, ένας ακατέργαστος δίσκος ή δίσκος zvol, καμία σύνδεση SSH στον host, ένα libvirt χωρίς το API αντιγράφων ή πολύ λίγος ελεύθερος χώρος κάτω από το /config σημαίνει το συνηθισμένο αντίγραφο με τη μέθοδο παραπάνω. Η κάρτα λέει ποιο από αυτά χρησιμοποίησε η τελευταία εκτέλεση και γιατί.

Απαιτήσεις: libvirt με το API αντιγράφων (δοκιμασμένο με libvirt 12.2 και QEMU 10.2 στο Unraid 7.3), sshd με AllowStreamLocalForwarding yes (η προεπιλογή, και στο Unraid, που απενεργοποιεί την προώθηση TCP), και δίσκοι qcow2. Το libvirt αρνείται checkpoints σε ακατέργαστους δίσκους, και το Unraid δημιουργεί από προεπιλογή ακατέργαστα vdisks. Η VM συνεχίζει να τρέχει κατά τη διάρκεια του αντιγράφου, όπως με το Ζωντανό, και τα τμήματα που περιμένουν το restic πιάνουν έως 4 GiB κάτω από το /config.

VMs με στιγμιότυπα Unraid

Ένα στιγμιότυπο που παίρνει ο VM Manager του Unraid μετατρέπει έναν δίσκο qcow2 σε αλυσίδα: η αρχική εικόνα στο κάτω μέρος, και πάνω της ένα αρχείο ανά στιγμιότυπο, το καθένα με μόνο ό,τι άλλαξε από εκείνο από κάτω. Η VM γράφει στο νεότερο αρχείο. Ένας δίσκος με δύο στιγμιότυπα είναι τρία αρχεία.

Το BombVault αντιγράφει μια τέτοια VM πλήρως:

  • Κάθε αρχείο της αλυσίδας. Ακολουθεί την αλυσίδα backing κάθε δίσκου μέχρι το τέλος της και αντιγράφει κάθε αρχείο μέσα της, μαζί με τη λίστα στιγμιοτύπων του Unraid (/etc/libvirt/qemu/snapshotdb/<vm>/snapshots.db, που διαβάζεται μέσω SSH). Μια αλυσίδα που δεν μπορεί να ακολουθηθεί μέχρι το τέλος, για παράδειγμα επειδή λείπει ένα αρχείο στη μέση, αποτυγχάνει το αντίγραφο και ονομάζει το αρχείο.
  • Ένα ζωντανό αντίγραφο κρατά τα στιγμιότυπα. Το Ζωντανό στιγμιότυπο βάζει μια προσωρινή επικάλυψη από πάνω όσο διαβάζει τον δίσκο και τη συγχωνεύει πίσω μετά, μόνο στην εικόνα ακριβώς από κάτω. Η αλυσίδα είναι ίδια μετά το αντίγραφο όπως πριν. Μια VM χωρίς στιγμιότυπα συμπεριφέρεται όπως πάντα.
  • Μια επαναφορά φέρνει πίσω την αλυσίδα. Μια επαναφορά στη θέση του πρωτοτύπου γράφει κάθε αρχείο πίσω εκεί που ήταν και βάζει πίσω τη λίστα στιγμιοτύπων του Unraid, ώστε ο VM Manager να απαριθμεί ξανά τα στιγμιότυπα. Μια επαναφορά δίπλα στο πρωτότυπο γράφει τα αρχεία στον φάκελο του αντιγράφου και στρέφει τους επαναφερμένους δίσκους στα επαναφερμένα αρχεία, ώστε το αντίγραφο να μη διαβάζει ποτέ από τις εικόνες του πρωτοτύπου. Η λίστα στιγμιοτύπων του Unraid επιστρέφει μόνο με επαναφορά στη θέση του πρωτοτύπου, γιατί ονομάζει τα αρχεία εκεί που αντιγράφηκαν. Χωρίς αυτήν το αντίγραφο ξεκινά το ίδιο, και ο VM Manager απλώς δεν απαριθμεί στιγμιότυπα για αυτό.
  • Το Μόνο αλλαγμένα μπλοκ διαβάζει ό,τι βλέπει ο guest, οπότε η επαναφορά του επιστρέφει ως ένα εξομαλυμένο αρχείο qcow2 χωρίς τα στιγμιότυπα.
  • Μια επαναφορά φέρνει πίσω τον δίσκο του αντιγράφου που διαλέγετε. Στιγμιότυπα που πάρθηκαν ή συγχωνεύτηκαν μετά από εκείνο το αντίγραφο δεν το αλλάζουν αυτό. Ένα αντίγραφο από πριν από ένα στιγμιότυπο ορίζει τη VM στο αρχείο που κρατά, και ένα αντίγραφο από πριν από μια συγχώνευση φέρνει πίσω την επικάλυψή του και τρέχει πάνω της. Τα νεότερα αρχεία μένουν εκεί που είναι, αχρησιμοποίητα και αμετάβλητα. Ένα αντίγραφο που κρατά μια επικάλυψη αλλά όχι το αρχείο από κάτω της απορρίπτεται πριν αγγιχτεί η VM. Ο ορισμός της VM δεν απαριθμεί αλυσίδα μετά από μια επαναφορά, οπότε το libvirt διαβάζει την αλυσίδα από τα επαναφερμένα αρχεία.

Παράδειγμα: μια VM με δύο στιγμιότυπα

Η VM homeassistant έχει έναν δίσκο, το vdisk1.qcow2, και δύο στιγμιότυπα που πήρατε στον VM Manager πριν από δύο ενημερώσεις. Ο δίσκος της είναι τώρα αλυσίδα τριών αρχείων. Τρέχει συνεχώς, οπότε χρησιμοποιεί Ζωντανό στιγμιότυπο.

  1. Ανοίξτε τα Αντίγραφα ασφαλείας, μετά το homeassistant, μετά την καρτέλα Ρυθμίσεις του. Στην κάρτα VM, ελέγξτε ότι η Μέθοδος είναι Ζωντανό στιγμιότυπο και ότι το Μόνο αλλαγμένα μπλοκ είναι ανενεργό.
  2. Πατήστε Δημιουργία αντιγράφου τώρα στην κεφαλίδα της σελίδας.
  3. Όταν τελειώσει η εκτέλεση, η γραμμή της στις Πρόσφατες εκτελέσεις στην καρτέλα Επαλήθευση είναι πράσινη. Η VM συνέχισε να τρέχει όλη την ώρα, και το αντίγραφο κρατά και τα τρία αρχεία του δίσκου και τη λίστα στιγμιοτύπων του Unraid.
  4. Στον VM Manager, τα δύο στιγμιότυπα είναι ακόμα εκεί, και ο δίσκος διαβάζει ακόμα μέσω των ίδιων τριών αρχείων.

Ένα μήνα αργότερα μια ενημέρωση πάει στραβά και θέλετε την χθεσινή κατάσταση δίπλα στη χαλασμένη, για σύγκριση:

  1. Ανοίξτε την Επαναφορά, διαλέξτε VMs και κάντε κλικ στο homeassistant.
  2. Κρατήστε το προτεινόμενο αντίγραφο της περασμένης νύχτας και επιλέξτε Δίπλα στο πρωτότυπο στο Πού.
  3. Πατήστε Επαναφορά. Τα τρία αρχεία καταλήγουν σε έναν φάκελο με το όνομα της VM και -restored, και ο επαναφερμένος δίσκος δείχνει στα επαναφερμένα αρχεία. Τίποτα δεν αλλάζει στη VM που τρέχει.

Για να γυρίσετε ολόκληρη τη VM πίσω, επιλέξτε Αντικατάσταση πρωτοτύπου με ενεργό το Πρώτα αντίγραφο της τρέχουσας κατάστασης. Το BombVault κρατά αντίγραφο της χαλασμένης κατάστασης, τερματίζει τη VM, γράφει πίσω τα τρία αρχεία και τη λίστα στιγμιοτύπων του Unraid και την ξεκινά ξανά.

TrueNAS SCALE

Τα παραπάνω βήματα είναι γραμμένα για το Unraid, αλλά η ίδια σύνδεση qemu+ssh:// λειτουργεί απέναντι σε οποιοδήποτε libvirtd φτάνει το κοντέινερ, και στο TrueNAS SCALE, που έχει ξανά VMs σε libvirt από το 25.04.2. Στο TrueNAS η συμβολοσειρά σύνδεσης θέλει παράκαμψη και το κλειδί μπαίνει στον root στις δικές ρυθμίσεις χρηστών του TrueNAS. Τρία ακόμα πράγματα αλλάζουν ό,τι κρατά ένα αντίγραφο: δίσκοι σε zvols, κατάσταση vTPM και τα ονόματα που δίνει το TrueNAS στις VMs του.

1. Το socket του libvirt

Το libvirtd του TrueNAS δεν ακούει εκεί που περιμένει η συμβολοσειρά σύνδεσης που φτιάχνεται από τα πεδία Host SSH. Ορίστε αντί γι' αυτό το LIBVIRT_URI, με την επιπλέον παράμετρο ?socket=:

LIBVIRT_URI=qemu+ssh://<user>@<truenas-host>/system?socket=/run/truenas_libvirt/libvirt-sock

Το BombVault χρησιμοποιεί το LIBVIRT_URI ακριβώς όπως γράφτηκε, και τα LIBVIRT_HOST, LIBVIRT_SSH_USER και LIBVIRT_SSH_PORT δεν χρειάζονται. Για καθεμία από αυτές που δεν έχει οριστεί, το BombVault παίρνει τον host, τον χρήστη και τη θύρα από το URI και για τις δικές του εντολές SSH, ώστε η αντιγραφή NVRAM και τα αντίγραφα συνόλων δεδομένων ZFS να φτάνουν το ίδιο μηχάνημα με το virsh. Μια μεταβλητή που ορίζετε εσείς υπερισχύει πάντα, και το αρχείο καταγραφής εκκίνησης ονομάζει τον προορισμό που πήρε από το URI. Στο TrueNAS ένας χρήστης εκτός του root χρειάζεται επίσης zfs allow <user> snapshot,destroy,mount <dataset> για αντίγραφα συνόλων δεδομένων ZFS, δείτε Σύνολα δεδομένων ZFS.

Βάλτε τη διεύθυνση LAN του TrueNAS στο URI. Αν δεν έχει οριστεί ούτε το LIBVIRT_URI ούτε το LIBVIRT_HOST, το BombVault παίρνει ως host την προεπιλεγμένη πύλη της εφαρμογής, επειδή το host.docker.internal δεν επιλύεται σε μια εφαρμογή TrueNAS, και το αρχείο καταγραφής εκκίνησης ονομάζει τη διεύθυνση που διάλεξε. Αυτό αρκεί για αντίγραφα συνόλων δεδομένων ZFS. Τα αντίγραφα VM χρειάζονται ακόμα το URI για το socket.

Η εφαρμογή χρειάζεται τη δυνατότητα SETPCAP για αντίγραφα VM, δίπλα στα CHOWN, DAC_OVERRIDE, FOWNER, SETGID και SETUID. Χωρίς αυτήν το libvirt σταματά με «cannot apply process capabilities». Το YAML στο TrueNAS SCALE τις ορίζει όλες, μαζί με το SYS_CHROOT που χρειάζεται το στιγμιότυπο αντί για διακοπή.

Στο TrueNAS SCALE 25.10.0 η διαδρομή του socket ελέγχθηκε σε πραγματικό υλικό: το στάνταρ qemu:///system αποτυγχάνει με Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory, και η ίδια κλήση με ?socket=/run/truenas_libvirt/libvirt-sock απαριθμεί τα domains.

2. Το κλειδί του BombVault στο TrueNAS

Το βήμα 2 παραπάνω γράφει στη μονάδα flash του Unraid και δεν ισχύει εδώ. Στο TrueNAS:

  1. Ενεργοποιήστε την υπηρεσία SSH στα System, Services.
  2. Στα Credentials, Users, επεξεργαστείτε τον root και επικολλήστε το δημόσιο κλειδί του BombVault από τις Ρυθμίσεις, Ενσωματώσεις, SSH κεντρικού συστήματος ως δημόσιο κλειδί SSH του. Το TrueNAS το κρατά ανάμεσα σε επανεκκινήσεις και ενημερώσεις.

Οι φρέσκιες εγκαταστάσεις του TrueNAS 24.10 και νεότερου δεν δίνουν στον root κωδικό, και η σύνδεση με κλειδί δεν χρειάζεται κανέναν. Αν προτιμάτε να μη χρησιμοποιήσετε το root, εξουσιοδοτήστε το κλειδί για έναν λογαριασμό διαχειριστή με sudo και βάλτε το όνομά του στη θέση του root στο LIBVIRT_URI. Τα αντίγραφα συνόλων δεδομένων ZFS χρειάζονται τότε zfs allow όπως περιγράφεται παραπάνω.

Μια ρεπλίκα ZFS σε δεύτερο διακομιστή συνδέεται με δικό της κλειδί, που δείχνει το παράθυρο της ρεπλίκας. Το κλειδί Host SSH δεν εξουσιοδοτεί ρεπλίκα, και το κλειδί της ρεπλίκας δεν εξουσιοδοτεί αντίγραφα VM.

Το TrueNAS δεν βλέπει τις αλλαγές που γίνονται με virsh

Το middleware του TrueNAS, το επίπεδο πίσω από τις οθόνες VM του, προορίζεται να είναι ο μοναδικός τρόπος αλλαγής των VMs του. Μια εντολή virsh μέσω αυτής της σύνδεσης SSH, που είναι αυτό που τρέχουν το αντίγραφο και η επαναφορά VM του BombVault, το προσπερνά, και το TrueNAS μπορεί αργότερα να συμφιλιώσει ή να αντικαταστήσει κατάσταση που δεν δημιούργησε. Αυτό προέρχεται από τη συμπεριφορά που τεκμηριώνει το TrueNAS και δεν έχει παρατηρηθεί σε πραγματικό μηχάνημα. Είναι ο ίδιος τύπος κινδύνου με τον VM Manager του Unraid που συμφιλιώνει αλλαγές εκτός αυτού, μόνο οξύτερος στο TrueNAS.

3. Δίσκοι σε zvols

Οι δίσκοι VM του TrueNAS είναι συχνά zvols, συσκευές μπλοκ ZFS στο /dev/zvol/<pool>/<dataset>, όχι αρχεία qcow2. Το restic δεν μπορεί να αντιγράψει μια συσκευή μπλοκ από τη διαδρομή της όπως αντιγράφει ένα αρχείο, οπότε το BombVault αναγνωρίζει έναν δίσκο zvol στο XML του domain (<source dev="..."> αντί για <source file="...">) και τον χειρίζεται μέσω της ίδιας σύνδεσης SSH. Το κοντέινερ BombVault δεν χρειάζεται εργαλεία ZFS.

Ένα αντίγραφο ενός zvol:

  1. Το zfs snapshot <dataset>@bombvault-vm-<time> καθηλώνει μια χρονική στιγμή, και όσο τρέχει η VM.
  2. Το zfs clone -o volmode=dev -o readonly=on κάνει εκείνο το στιγμιότυπο αναγνώσιμο ως συσκευή. Το volmode=dev εμποδίζει τον host να σαρώσει τα διαμερίσματα του guest.
  3. Το dd διαβάζει τη συσκευή, και η ακατέργαστη εικόνα μπαίνει στο restic ως ένα αρχείο, /vm-disks/<dataset>.img, με ετικέτα vm:<name>:zvol:<dev>. Το restic την κόβει σε κομμάτια ανάλογα με το περιεχόμενο, οπότε τα μπλοκ που δεν άλλαξαν από το τελευταίο αντίγραφο δεν αποθηκεύονται ξανά.
  4. Το clone και το στιγμιότυπο καταστρέφονται μετά, είτε πέτυχε το αντίγραφο είτε όχι. Αν το BombVault σταμάτησε στη μέση ενός αντιγράφου, το επόμενο αντίγραφο εκείνου του zvol αφαιρεί πρώτα το στιγμιότυπο bombvault-vm-<time> και το clone του <dataset>-bombvault-vm-<time>. Αφήνει ήσυχο κάθε άλλο στιγμιότυπο, και κρατά ένα από το οποίο έγινε clone κάτι άλλο. Το αρχείο καταγραφής ονομάζει τι αφαίρεσε ή κράτησε.

Το BombVault δεν χρησιμοποιεί το zfs send γι' αυτό. Κάθε εγγραφή ενός ρεύματος send φέρει το GUID του στιγμιοτύπου και ένα τρέχον checksum, οπότε το restic δεν θα έβρισκε τίποτα από το τελευταίο αντίγραφο να ξαναχρησιμοποιήσει και θα αποθήκευε κάθε φορά ολόκληρο τον δίσκο. Μετρήθηκε στο TrueNAS SCALE 25.10 με ένα zvol 512 MiB που κρατά 200 MiB δεδομένων: το πρώτο αντίγραφο πρόσθεσε 211 MB, ένα δεύτερο χωρίς αλλαγές 52 KB, και ένα μετά από αλλαγή 1 MiB 3,6 MB. Το ίδιο zvol μέσω zfs send πρόσθεσε 214 MB σε κάθε εκτέλεση.

Κάθε εκτέλεση γράφει επίσης ένα μικρό στιγμιότυπο με ετικέτα vm:<name> με το XML του domain, αφού μπουν όλοι οι δίσκοι. Μια VM της οποίας όλοι οι δίσκοι είναι zvols δεν έχει στιγμιότυπο αρχείου, και αυτό είναι που απαριθμεί την εκτέλεση κάτω από τη VM και την κάνει επαναφέρσιμη.

Μια επαναφορά γράφει κάθε zvol πίσω στη θέση του, όπως ένας δίσκος αρχείου γράφεται πίσω στο αρχείο του, ώστε η επαναφερμένη VM να ξεκινά με τα επαναφερμένα δεδομένα:

  1. Πριν αγγιχτεί οτιδήποτε, το BombVault ελέγχει ότι η εκτέλεση κρατά εικόνα κάθε δίσκου zvol. Μια εκτέλεση που λείπει μία απορρίπτεται και η VM μένει όπως είναι.
  2. Ένα υπάρχον zvol παίρνει πρώτα ένα στιγμιότυπο, <dataset>@bombvault-before-restore-<time>, με την ώρα σε UTC όπως κάθε όνομα στιγμιοτύπου που φτιάχνει το BombVault, οπότε μπορεί να διαφέρει ώρες από το τοπικό ρολόι. Το αρχείο καταγραφής το ονομάζει, και ένα zfs rollback σε αυτό αναιρεί την επαναφορά όσο είναι το νεότερο στιγμιότυπο του zvol. Όταν υπάρχει νεότερο, όπως της επόμενης επαναφοράς, το zfs rollback -r το κάνει και καταστρέφει τα νεότερα στιγμιότυπα. Μένει μέχρι να το αφαιρέσετε με zfs destroy όταν η επαναφερμένη VM δουλεύει.
  3. Ένα zvol που δεν υπάρχει πια δημιουργείται στο μέγεθος που είχε όταν αντιγράφηκε, και ένα υπάρχον άλλου μεγέθους επιστρέφει σε εκείνο το μέγεθος.
  4. Το dd γράφει την εικόνα στο /dev/zvol/<dataset>. Με ενεργή συμπίεση, την προεπιλογή του TrueNAS, τα κενά μέρη της εικόνας επιστρέφουν ως τρύπες και δεν πιάνουν χώρο.

Μια επαναφορά σε άλλο στιγμιότυπο χρειάζεται pool προορισμού. Μετακινεί τους δίσκους αρχείων σε φάκελο προορισμού, αλλά ένας φάκελος δεν ονομάζει κανένα pool ZFS, οπότε χωρίς ένα το BombVault αρνείται την επαναφορά πριν ξεκινήσει. Δώστε το pool ως παράμετρο zvolPool του POST /api/foreign/restore: κάθε zvol κρατά τη διαδρομή του κάτω από το pool (το tank/vms/win10/disk0 προς το flashpool γίνεται flashpool/vms/win10/disk0), και το XML του domain δείχνει σε αυτό. Το παράθυρο Από παλιό φάκελο αντιγράφων στη σελίδα Επαναφορά δεν έχει πεδίο γι' αυτό, οπότε προσεγγίζεται μόνο με άμεση κλήση API. Μια επαναφορά στο ίδιο στιγμιότυπο γράφει κάθε zvol πίσω πάνω στον εαυτό του.

Η εξαγωγή ως αρχεία αφήνει έξω τα zvols. Μια VM της οποίας όλοι οι δίσκοι είναι zvols απορρίπτεται με αυτόν τον λόγο, οπότε επαναφέρετέ τη από ένα αντίγραφο. Για μια VM που έχει και δίσκους αρχείων, η εξαγωγή κρατά τους δίσκους αρχείων και μια σημείωση που ονομάζει τα zvols που άφησε έξω.

Αυτό δοκιμάστηκε στο TrueNAS SCALE 25.10 με ZFS 2.3.4: τρία αντίγραφα ενός δοκιμαστικού zvol, μια επαναφορά στη θέση του αφού το zvol είχε αντικατασταθεί και μεγαλώσει, και μια επαναφορά σε zvol που είχε διαγραφεί. Κάθε επαναφορά διαβάστηκε πίσω με το ίδιο SHA-256 με την πηγή, το zvol είχε ξανά το παλιό μέγεθός του, και κανένα στιγμιότυπο ή clone δεν έμεινε πίσω. Μια ολόκληρη VM της οποίας ο μόνος δίσκος είναι zvol αντιγράφηκε ενώ έτρεχε, με Ομαλή και με Ζωντανό, και σβηστή, και μια επαναφορά ολόκληρης VM (undefine, εγγραφή των zvols, define, εκκίνηση) έτρεξε επίσης εκεί: το zvol διαβάστηκε πίσω με το checksum της πηγής και η VM ξεκίνησε.

Οι δίσκοι αρχείων, όπως τους χρησιμοποιεί το Unraid, δεν επηρεάζονται από τίποτα από αυτά.

4. Κατάσταση vTPM

Μια VM μπορεί να έχει εικονικό TPM, που χρειάζονται το Secure Boot και οι guest Windows 11. Η κατάστασή του ζει έξω από τον δίσκο και το NVRAM, οπότε ένα αντίγραφο μόνο αυτών των δύο θα επέστρεφε έναν guest με καινούργιο, κενό TPM.

  • Ένα TPM διέλευσης, ένα πραγματικό τσιπ που περνά στον guest, ονομάζει τη διαδρομή του στο XML του domain. Το BombVault αποθηκεύει την κατάστασή του δίπλα στο NVRAM μέσω SSH και την γράφει πίσω πριν από το virsh define, με βάση την καλύτερη προσπάθεια όπως το NVRAM: μια ανάγνωση ή εγγραφή που αποτυγχάνει καταγράφεται και δεν αποτυγχάνει το αντίγραφο ή την επαναφορά.
  • Ένα εξομοιωμένο vTPM, αυτό που στήνει το TrueNAS για guests Windows 11 και Secure Boot, δεν δημοσιεύει διαδρομή κατάστασης στο XML του domain, οπότε η κατάστασή του δεν αντιγράφεται. Το BombVault δεν μαντεύει διαδρομή, και το αντίγραφο ολοκληρώνεται με μια σημείωση ότι η κατάσταση του TPM της VM δεν περιέχεται σε αυτό. Κρατήστε πρόχειρο το κλειδί ανάκτησης ενός τέτοιου guest, όπως το κλειδί BitLocker του, πριν τον επαναφέρετε.
  • Δεν μπορείτε να συνδέσετε μόνοι σας TPM σε VM του TrueNAS. Το API συσκευών VM του TrueNAS SCALE 25.10 δέχεται μόνο CDROM, DISPLAY, NIC, PCI, RAW, DISK και USB, και αρνείται το TPM ως άγνωστο τύπο.

Ο χειρισμός του TPM έχει δοκιμαστεί μόνο με unit tests και δεν έχει τρέξει σε πραγματικό guest TrueNAS με vTPM. Μια VM χωρίς TPM αντιγράφεται και επαναφέρεται ακριβώς όπως πριν.

Το NVRAM αντιγράφεται όπως συνήθως. Το TrueNAS το κρατά ανά VM στο /var/db/system/vm/nvram/<id>_<name>_VARS.fd, και το XML του domain ονομάζει αυτή τη διαδρομή.

5. Ονόματα VM στο TrueNAS

Στο Unraid το όνομα libvirt μιας VM είναι το όνομα που διαλέξατε. Το TrueNAS φτιάχνει το όνομα libvirt, και έχει αλλάξει τον τρόπο δύο φορές:

Έκδοση TrueNAS Όνομα libvirt Πού ζει το όνομά σας
25.10 "Goldeye" {id}_{name}, όπως 1_debian στο όνομα libvirt, μετά το {id}_
26 το UUID της VM, όπως 550e8400-e29b-41d4-a716-446655440000 μόνο στο <title> του XML του domain

Σε έναν host που το BombVault εντοπίζει ως TrueNAS, ή που το ονομάζει το PLATFORM=truenas, η λίστα Αντίγραφα ασφαλείας δείχνει το όνομά σας: debian αντί για 1_debian στο 25.10, και το <title> αντί για το UUID στο 26, ή το UUID όταν δεν υπάρχει τίτλος. Αυτό είναι μόνο ό,τι δείχνει η λίστα. Κάθε κλήση virsh και οι ρυθμίσεις ανά VM εξακολουθούν να χρησιμοποιούν το όνομα libvirt, οπότε το αντίγραφο και η επαναφορά ενεργούν πάντα στη σωστή VM. Στο TrueNAS 26 αυτό σημαίνει ότι μια VM που το TrueNAS δημιουργεί ξανά με νέο UUID εμφανίζεται ως νέο στοιχείο χωρίς τις ρυθμίσεις της, ακόμα κι αν το όνομά της φαίνεται ίδιο. Στο Unraid δεν αλλάζει τίποτα, ούτε για μια VM που ονομάσατε 10_Windows.

Το σχήμα του 25.10 παρατηρήθηκε σε πραγματικό μηχάνημα TrueNAS SCALE 25.10. Το σχήμα του TrueNAS 26 προέρχεται από την τεκμηρίωση του TrueNAS και έχει δοκιμαστεί μόνο με unit tests.

Αντιμετώπιση προβλημάτων

Σύμπτωμα Αιτία και διόρθωση
Η Δοκιμή σύνδεσης κρεμάει και μετά αποτυγχάνει Ο host δεν προσεγγίζεται. Ελέγξτε το βήμα 3 (δίκτυο, VLAN, firewall) και το Host SSH: Address και Port.
Permission denied (publickey) αν και το κλειδί είναι στο authorized_keys Το StrictModes του sshd απορρίπτει το αρχείο κλειδιού επειδή ένας γονικός φάκελος έχει λάθος ιδιοκτήτη ή δικαιώματα. Αυτό είναι συνηθισμένο όταν το /root/.ssh είναι σύνδεσμος προς τη μονάδα flash FAT (/boot/config/ssh/...), που είναι εγγράψιμη από όλους. Το αρχείο καταγραφής του host δείχνει Authentication refused: bad ownership or modes for directory .... Προσθέστε StrictModes no στη διαμόρφωση sshd του host στο καθολικό τμήμα, πριν από οποιοδήποτε μπλοκ Match, και μετά τρέξτε /etc/rc.d/rc.sshd restart. Το Unraid γράφει το /etc/ssh/sshd_config από την αρχή σε κάθε εκκίνηση, οπότε κάντε το μόνιμο όπως περιγράφεται παρακάτω.
Permission denied (publickey) και το κλειδί πράγματι λείπει Επαναλάβετε το βήμα 2 και ελέγξτε ότι το SSH είναι ενεργό.
Host key verification failed Τρέξτε docker exec BombVault rm -f /config/ssh/known_hosts και δοκιμάστε ξανά.
Ο έλεγχος στο βήμα 3 λέει UNREACHABLE Το κοντέινερ δεν μπορεί να φτάσει τη θύρα SSH του host. Δείτε το βήμα 3: πρόσβαση του host σε προσαρμοσμένα δίκτυα, δρομολόγηση VLAN, ή η IP shim ή LAN.
Οι μεταβλητές λείπουν κάτω από το Edit Εισαγάγετε ξανά το template. Ένα υπάρχον κοντέινερ κρατά την παλιά αποθηκευμένη διαμόρφωσή του.
Μια VM με στιγμιότυπα Unraid αποτυγχάνει και ονομάζει ένα αρχείο Η αλυσίδα backing του δίσκου δεν μπορεί να ακολουθηθεί μέχρι το τέλος. Ελέγξτε στον VM Manager ότι κάθε στιγμιότυπο εκείνου του δίσκου είναι ακόμα εκεί και ότι το αρχείο που ονομάζεται υπάρχει κάτω από το /mnt.

Περισσότερα συμπτώματα VM υπάρχουν στην Αντιμετώπιση προβλημάτων.

Διατήρηση μετά από επανεκκινήσεις

Το Unraid γράφει το /etc/ssh/sshd_config από την αρχή σε κάθε εκκίνηση, οπότε οι αλλαγές στη μεριά του host πρέπει να γίνονται ξανά στην εκκίνηση:

  • Η θύρα SSH κρατιέται στο /boot/config/ident.cfg, και ορίζεται μέσω του web UI του Unraid.
  • Το StrictModes no, αν το χρειαστήκατε παραπάνω, δεν κρατιέται. Εφαρμόστε το στην εκκίνηση από το /boot/config/go:
# /boot/config/go: keep SSH key auth working with flash-based authorized_keys
( for i in $(seq 1 30); do [ -f /etc/ssh/sshd_config ] && break; sleep 2; done
  grep -q '^StrictModes no' /etc/ssh/sshd_config || \
    sed -i '0,/^Match /s/^Match /StrictModes no\n&/' /etc/ssh/sshd_config
  # SIGHUP reloads sshd's config in place: it keeps the listener + open sessions
  # and avoids the "killing listener process / Restarting SSH server daemon"
  # warning that `rc.sshd restart` prints at boot. Only reload if sshd is already
  # up; if it starts after this runs, it reads the edited config on its own.
  pidof sshd >/dev/null && killall -HUP sshd ) &
  • Το δικό του κλειδί SSH του BombVault και το ~/.ssh/config ζουν στο /config (appdata) και φτιάχνονται ξανά σε κάθε εκκίνηση, οπότε επιβιώνουν των επανεκκινήσεων του κοντέινερ και του host.

Ασφάλεια

Το εξουσιοδοτημένο κλειδί δίνει root στον host, το ίδιο επίπεδο εμπιστοσύνης με το Docker socket που ήδη χρησιμοποιεί το BombVault. Κρατήστε το BombVault σε αξιόπιστο δίκτυο. Το κλειδί είναι ed25519, αποθηκευμένο με δικαιώματα 0600 στο appdata, και το κλειδί του host καρφιτσώνεται. Κάθε εντολή host περνά ως ξεχωριστά ορίσματα, ποτέ μέσω απομακρυσμένου shell, και η σύνδεση SSH χρησιμοποιεί BatchMode και χρονικό όριο σύνδεσης.