
Rappel de l’état à la fin de l’E11 #
À la fin de l’E11, les filets de sécurité sont opérationnels :
graph TB
subgraph MATRIX["CLUSTER MATRIX"]
Morpheus["Morpheus
10.10.10.5
ZFS mirror NVMe"]
Neo["Neo
10.10.10.6
LVM SSD SATA
⚠️ migration ZFS à venir"]
end
Oracle["oracle
192.168.0.50
corosync-qnetd
3 votes ✅"]
ns1["ns1.dns.allfabox.fr
10.10.10.53
RPi 3B — Primary ✅"]
LXC107["LXC 107 — PBS 4.2.1
10.10.10.7 ✅"]
LXC130["LXC 130 — Smarthome ✅"]
Morpheus <-->|corosync| Neo
Morpheus <-->|TCP 5403| Oracle
Neo <-->|TCP 5403| Oracle
Morpheus --> LXC107
Morpheus --> LXC130
style Morpheus fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style Neo fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style Oracle fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style ns1 fill:#f3e8ff,stroke:#7e22ce,stroke-width:2px,color:#000
style LXC107 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style LXC130 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
- QDevice oracle → quorum à 3 votes, cluster stable même si un nœud tombe ✅
- Technitium ns1 sur RPi (10.10.10.53) → résolution DNS homelab opérationnelle ✅
- Routes réseau double NAT → oracle atteint le cluster Proxmox ✅
- Neo toujours en LVM → c’est l’objet de cet épisode
Partie 1 — Réinstallation de Neo en ZFS #
Prérequis vérifiés avant de commencer #
✅ QDevice oracle actif → si Neo tombe, Morpheus garde le quorum
✅ PBS mirroré sur Morpheus → 14 groupes, 0 perte de données
✅ LXC Smarthome sur Morpheus → domotique continue de tourner
✅ RPi DNS opérationnel → DNS tient sans LXC 253
flowchart TD
A["Vérifications préalables
QDevice ✅ | PBS mirroré ✅
DNS RPi ✅ | Smarthome ✅"]
B["Dernière synchro PBS
14 groupes — 0 perte de données"]
C["pvecm delnode neo
Retrait propre du cluster"]
D["Boot ISO Proxmox 9.2
Ventoy — ZFS RAID0 single disk"]
E["Installation Proxmox sur Neo
sda: Crucial BX500 931.5 Go
DNS: 10.10.10.53 RPi"]
F["pvecm add 10.10.10.5
Réintégration au cluster"]
G["pvecm qdevice setup --force
Reconfiguration QDevice"]
H["Nettoyage artefacts
LXC et VM fantômes"]
I["Neo ZFS opérationnel ✅
rpool: 897 Go disponibles"]
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
G --> H
H --> I
style A fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style B fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style C fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style D fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style E fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style F fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style G fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style H fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style I fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
Dernière synchronisation PBS #
On s’assure de synchroniser une dernière fois notre datastore PBS.
pct exec 107 -- proxmox-backup-manager sync-job run neo-pbs-sync
# → 14 groups, 0 snapshots nouveaux, TASK OK ✅
Retrait de Neo du cluster #
# Depuis Morpheus
pvecm delnode neo
Installation Proxmox 9.2 sur Neo (ZFS) #
Boot sur ISO Proxmox 9.2 via Ventoy, avec les paramètres :
Filesystem : ZFS (RAID0 — single disk)
Disk : sda (Crucial BX500 931.5 Go)
Hostname : neo.pve.allfabox.fr
IP : 10.10.10.6/24
Gateway : 10.10.10.1
DNS : 10.10.10.53 ← le RPi !
Résultat ZFS sur Neo #
rpool : ONLINE, 897 Go disponibles (single SSD SATA)
Réintégration au cluster #
# Sur Morpheus : récupérer l'empreinte du certificat du cluster
pvecm fingerprint
# → 2A:3F:...:9C
pvecm fingerprint, ou laissez Proxmox l’afficher : si vous omettez --fingerprint, la jonction passe en mode interactif et vous demande de confirmer l’empreinte avant de continuer.
# Sur Neo : ajouter Morpheus dans /etc/hosts
echo "10.10.10.5 morpheus.allfabox.lan" >> /etc/hosts
# Rejoindre le cluster avec l'empreinte récupérée
pvecm add 10.10.10.5 --fingerprint 2A:3F:...:9C
# → successfully added node 'Neo' to cluster ✅
Reconfiguration du QDevice sur Neo #
apt install -y corosync-qdevice
pvecm qdevice setup 192.168.0.50 --force
Nettoyage des anciens artefacts #
Après réintégration, les anciens LXC et datastores LVM apparaissent en fantômes. Nettoyage :
# Supprimer les configs LXC fantômes
rm /etc/pve/nodes/Neo/lxc/230.conf
rm /etc/pve/nodes/Neo/lxc/253.conf
rm /etc/pve/nodes/Neo/qemu-server/500.conf
rm /etc/pve/nodes/Neo/qemu-server/999.conf
Partie 2 — Stockage ZFS unifié et DNS secondaire #
Storage ZFS cluster-wide #
Après réintégration de Neo, il fallait déclarer son storage ZFS. Deux approches s’offraient à nous, et le choix conditionne toute la suite. Mais avant cela, un mot sur la notion de storage chez Proxmox.
Qu’est-ce qu’un « storage » sous Proxmox ? #
Sous Proxmox VE, un storage est une abstraction : un emplacement déclaré où Proxmox sait lire et écrire des données. Ce n’est pas le disque physique lui-même, mais une définition logique qui dit à Proxmox « voici un endroit utilisable, voici son type et voici ce qu’on a le droit d’y mettre ».
Chaque storage possède trois caractéristiques essentielles :
| Caractéristique | Rôle | Exemple |
|---|---|---|
| ID | Le nom logique par lequel on le référence partout | datastore, local, local-zfs |
| Type | La technologie de stockage sous-jacente | zfspool, lvmthin, dir, nfs, cephfs |
| Content | Les types de données autorisés | images (disques VM), rootdir (disques LXC), backup, iso, vztmpl |
Toutes les définitions vivent dans un seul fichier, /etc/pve/storage.cfg. Point crucial en cluster : ce fichier est stocké dans le système de fichiers cluster Proxmox (pmxcfs), donc toute modification est automatiquement répliquée sur l’ensemble des nœuds.
graph TB
CFG["/etc/pve/storage.cfg
(répliqué via pmxcfs)"]
subgraph S1["storage « datastore »"]
T1["Type: zfspool"]
C1["Content: images, rootdir"]
end
DISK["Disque physique réel
rpool/datastore (ZFS local)"]
VM["Disque d'une VM/LXC
datastore:subvol-XXX-disk-0"]
CFG --> S1
VM -->|référence l'ID| S1
S1 -->|pointe vers| DISK
style CFG fill:#f3e8ff,stroke:#7e22ce,stroke-width:2px,color:#000
style T1 fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style C1 fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style DISK fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style VM fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
datastore:...). Proxmox traduit cet ID, via storage.cfg, vers l’emplacement réel sur le nœud courant. C’est précisément cette indirection qui rend la migration entre nœuds possible.
Les deux approches possibles #
graph TB
subgraph MAUVAIS["❌ Approche naïve — un storage par nœud"]
direction LR
M1["Morpheus
storage: morpheus-datastore"]
N1["Neo
storage: neo-datastore"]
M1 -.->|migration
renommage manuel
du disque requis| N1
end
subgraph BON["✅ Approche cluster-wide — un seul ID"]
direction LR
M2["Morpheus
storage: datastore"]
N2["Neo
storage: datastore"]
M2 -->|migration
référence identique
aucun renommage| N2
end
MAUVAIS ~~~ BON
style M1 fill:#fee2e2,stroke:#991b1b,stroke-width:2px,color:#000
style N1 fill:#fee2e2,stroke:#991b1b,stroke-width:2px,color:#000
style M2 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style N2 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
Plutôt que de créer un storage neo-datastore séparé, on adopte la logique d’un storage cluster-wide avec le même nom sur tous les nœuds — comme dans les architectures Proxmox multi-nœuds professionnelles.
L’idée : un seul ID Proxmox datastore, déclaré une fois dans /etc/pve/storage.cfg (fichier répliqué automatiquement sur tout le cluster), et disponible à la fois sur Morpheus et Neo. Sur chaque nœud, cet ID pointe vers le dataset ZFS local rpool/datastore.
Le concept clé : même nom logique, données locales distinctes #
C’est le point qui prête à confusion. Ce n’est PAS du stockage partagé. Il n’y a aucun disque commun entre les deux nœuds. Chaque nœud écrit sur son propre pool ZFS local — Morpheus sur ses NVMe en mirror, Neo sur son SSD SATA.
graph TB
subgraph CLUSTER["Cluster Matrix — ID Proxmox unique : « datastore »"]
direction LR
subgraph M["Morpheus"]
MZ["rpool/datastore
NVMe mirror local"]
end
subgraph N["Neo"]
NZ["rpool/datastore
SSD SATA local"]
end
end
APP["Disque d'un LXC/VM
référencé : datastore:subvol-XXX-disk-0"]
APP -->|sur Morpheus| MZ
APP -->|sur Neo| NZ
style MZ fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style NZ fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style APP fill:#f3e8ff,stroke:#7e22ce,stroke-width:2px,color:#000
datastore), mais chacun écrit sur son disque ZFS local. Un LXC sur Neo n’accède pas aux données de Morpheus — c’est la réplication ZFS (configurée plus loin) qui copie les datasets d’un nœud à l’autre.
Mise en œuvre #
Bonne nouvelle : il n’y a rien à éditer à la main. Le storage datastore existait déjà sur Morpheus (créé lors d’un épisode précédent). Il suffit de créer le dataset ZFS côté Neo, puis d’étendre le storage existant aux deux nœuds avec une seule commande pvesm.
Étape 1 — Créer le dataset ZFS sur Neo. Le storage Proxmox attend de trouver rpool/datastore localement ; il faut donc le créer côté Neo (il existe déjà sur Morpheus) :
# Sur Neo — créer le dataset ZFS local
zfs create rpool/datastore
Étape 2 — Rattacher Neo au storage existant. Une seule commande suffit : pvesm set met à jour la définition du storage pour y ajouter Neo. Pas besoin d’ouvrir un éditeur :
# Depuis n'importe quel nœud — étendre le storage aux deux nœuds
pvesm set datastore --nodes morpheus,neo
Étape 3 — Vérifier. Sur chaque nœud, le storage datastore doit apparaître active. Sur Neo, on attend les ~897 Go du SSD SATA :
# Sur Neo
pvesm status
# Name Type Status Total Used Available %
# datastore zfspool active 897 Go 0 B 897 Go 0% ✅
Info : La commande pvesm set écrit elle-même dans /etc/pve/storage.cfg — vous n’éditez jamais ce fichier manuellement. Comme il vit dans le système de fichiers cluster (pmxcfs), la modification est automatiquement répliquée sur tous les nœuds. À titre informatif, voici à quoi ressemble la définition résultante :
# /etc/pve/storage.cfg (généré par pvesm)
zfspool: datastore # ← un seul ID logique pour tout le cluster
pool rpool/datastore # ← le dataset ZFS local, identique sur chaque nœud
content images,rootdir # ← disques de VMs (images) et de LXC (rootdir)
nodes morpheus,neo # ← les deux nœuds qui exposent ce storage
sparse 1 # ← allocation fine (thin provisioning) ZFS
datastore:subvol-XXX-disk-0, qu’ils soient sur Morpheus ou Neo. Proxmox résout cette référence vers le rpool/datastore local du nœud qui héberge la machine. Résultat : les migrations entre nœuds n’exigent aucun renommage de disque, la réplication ZFS est directe, et la configuration reste parfaitement homogène.
Le vrai objectif : faire circuler les VMs et LXC entre les deux nœuds #
Le storage datastore partagé entre les deux nœuds est le socle qui rend cela possible. Concrètement, ce que l’on veut, c’est que l’image disque d’une VM ou d’un LXC existe des deux côtés : sur le ZFS de Morpheus et sur le ZFS de Neo. Comme les deux nœuds parlent ZFS et exposent le même ID datastore, Proxmox peut répliquer ces images disque d’un pool à l’autre, puis basculer la machine sur le nœud qui possède déjà sa copie.
graph LR
subgraph M["Morpheus (nœud actif)"]
VMM["LXC 130 — Smarthome
datastore:subvol-130-disk-0"]
end
subgraph N["Neo (nœud de secours)"]
VMN["Copie répliquée
datastore:subvol-130-disk-0"]
end
UP["LXC 130 redémarré sur Neo ✅"]
VMM ==>|réplication ZFS
snapshots incrémentaux
toutes les X min| VMN
VMN -.->|en cas de panne
de Morpheus| UP
style VMM fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style VMN fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style UP fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
Sans cet ID commun, rien de tout cela ne fonctionne :
- Migration à froid / à chaud : déplacer manuellement un LXC de Morpheus vers Neo pour faire une maintenance, sans toucher à sa configuration.
- Réplication ZFS native : Proxmox envoie périodiquement les snapshots ZFS incrémentaux de
datastorevers l’autre nœud — seuls les blocs modifiés transitent. - HA Manager : si Morpheus tombe, le HA Manager redémarre automatiquement les machines sur Neo, à partir de la dernière copie répliquée.
zfs send/zfs receive) de façon efficace. Couplé au storage datastore partagé, cela transforme deux serveurs indépendants en un cluster capable de faire basculer une charge d’un nœud à l’autre — la bascule (réplication + HA) fait l’objet des sections suivantes.
LXC 253 — Technitium DNS secondaire #
Avant de créer le LXC, il faut s’assurer que le point de montage (mountpoint) du dataset ZFS sur Neo est aligné sur celui de Morpheus (/datastore).
mountpoint est le répertoire du système de fichiers où ZFS « branche » le dataset. Par défaut, ZFS hérite du nom du pool et monte rpool/datastore sous /rpool/datastore. Or sur Morpheus, ce même dataset est monté sous /datastore. Si les deux nœuds n’utilisent pas le même chemin, les disques de LXC/VMs (rootfs) ne se retrouveront pas au même endroit après une réplication ou une migration — d’où l’importance d’aligner les deux nœuds.
Étape 1 — Vérifier le mountpoint actuel sur Neo :
# Sur Neo — afficher le point de montage du dataset
zfs get mountpoint rpool/datastore
# NAME PROPERTY VALUE SOURCE
# rpool/datastore mountpoint /rpool/datastore default ← à corriger
La colonne SOURCE indique default : ZFS a choisi le chemin tout seul (/rpool/datastore), il ne correspond pas à Morpheus.
Étape 2 — Forcer le mountpoint sur /datastore pour l’aligner sur Morpheus :
# Sur Neo — fixer explicitement le point de montage
zfs set mountpoint=/datastore rpool/datastore
ZFS démonte puis remonte immédiatement le dataset au nouvel emplacement — aucun redémarrage requis. La valeur passe alors en SOURCE local, c’est-à-dire définie manuellement et non plus héritée.
Étape 3 — Confirmer l’alignement :
# Sur Neo — vérifier que le chemin est désormais /datastore
zfs get mountpoint rpool/datastore
# NAME PROPERTY VALUE SOURCE
# rpool/datastore mountpoint /datastore local ✅
Les deux nœuds montent maintenant leur dataset rpool/datastore sous le même chemin /datastore. La réplication et les migrations de LXC/VMs retrouveront leurs disques à l’identique des deux côtés.
Le template est accessible via le NFS iso-neo monté depuis Morpheus. Le chemin correct depuis Neo est /mnt/pve/iso-neo/template/cache/ :
pct create 253 /mnt/pve/iso-neo/template/cache/debian-13-standard_13.1-2_amd64.tar.zst \
--hostname ns2 \
--ostype debian \
--arch amd64 \
--cores 1 \
--memory 512 \
--swap 512 \
--rootfs datastore:8 \
--net0 name=eth0,bridge=vmbr0,firewall=1,gw=10.10.20.1,ip=10.10.20.53/24,tag=20,type=veth \
--onboot 1 \
--startup order=1 \
--unprivileged 1 \
--tags "prod;dns" \
--password
pct set 253 --features nesting=1
pct start 253
Installation de Technitium sur ns2 :
pct exec 253 -- bash -c "apt update && apt install -y curl && \
curl -sSL https://download.technitium.com/dns/install.sh | bash"
Rejoindre le cluster Technitium #
Depuis l’interface de ns2 (http://10.10.20.53:5380) :
Administration → Cluster → Join Cluster
Secondary Node IP : 10.10.20.53
Primary Node URL : https://ns1.dns.allfabox.fr:53443/
Primary Node IP : 10.10.10.53
Certificate : Ignore Certificate Validation Errors
Username : admin
Password : (mot de passe ns1)
ns2 rejoint le cluster et se synchronise automatiquement avec ns1. ✅
État du cluster après migration Neo #
pvecm status
Name : MATRIX
Expected votes : 3
Total votes : 3
Flags : Quorate Qdevice
Morpheus 10.10.10.5 1 vote A,V,NMW ✅
Neo 10.10.10.6 1 vote A,V,NMW ✅
Qdevice oracle 1 vote ✅
graph TB
subgraph MorpheusG["Morpheus — nœud principal"]
MorpheusNode["Morpheus
10.10.10.5
ZFS mirror 2x NVMe
storage: datastore"]
LXC107["LXC 107 — PBS 4.2.1
10.10.10.7"]
LXC130["LXC 130 — Smarthome"]
end
subgraph NeoG["Neo — nœud secondaire"]
NeoNode["Neo
10.10.10.6
ZFS single SSD 897 Go
storage: datastore"]
LXC253["LXC 253 — ns2
10.10.20.53"]
end
QDevice["oracle
192.168.0.50
corosync-qnetd
VM Freebox Ultra"]
subgraph DNSCluster["DNS Cluster Technitium"]
ns1["ns1.dns.allfabox.fr
10.10.10.53 — RPi 3B
Primary ✅"]
ns2["ns2.dns.allfabox.fr
10.10.20.53 — LXC 253
Secondary ✅"]
end
MorpheusNode <-->|corosync| NeoNode
MorpheusNode <--> QDevice
NeoNode <--> QDevice
MorpheusNode --> LXC107
MorpheusNode --> LXC130
NeoNode --> LXC253
LXC253 -.- ns2
ns1 <-->|synchro cluster| ns2
style MorpheusNode fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style NeoNode fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style QDevice fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style LXC107 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style LXC130 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style LXC253 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style ns1 fill:#f3e8ff,stroke:#7e22ce,stroke-width:2px,color:#000
style ns2 fill:#f3e8ff,stroke:#7e22ce,stroke-width:2px,color:#000
Post-installation #
Durcissement SSH sur Neo #
Après réinstallation, on applique une configuration SSH durcie. Deux points critiques pour la compatibilité Proxmox :
PermitRootLogin prohibit-password— root autorisé par clé uniquement (nécessaire pour les migrations, la réplication ZFS et les opérations pvecm entre nœuds)AllowUsers allfab root— root doit être explicitement dans la liste
Attention :
PermitRootLogin no+AllowUsers allfabsansrootcassera les migrations live, la réplication ZFS et toutes les opérations inter-nœuds de Proxmox.
cat > /etc/ssh/sshd_config << 'EOF'
Port 22
ListenAddress 0.0.0.0
Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
AuthorizedKeysFile .ssh/authorized_keys
PubkeyAuthentication yes
AuthenticationMethods publickey
PermitRootLogin prohibit-password
ClientAliveInterval 60
ClientAliveCountMax 100
Compression delayed
SyslogFacility AUTH
LogLevel INFO
MaxAuthTries 3
MaxSessions 3
MaxStartups 5:30:20
AllowUsers allfab root
LoginGraceTime 30
PasswordAuthentication no
PermitEmptyPasswords no
StrictModes yes
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com
Ciphers aes256-ctr,aes128-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
KexAlgorithms diffie-hellman-group18-sha512,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512
IgnoreRhosts yes
HostbasedAuthentication no
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
UsePAM yes
X11Forwarding no
PrintMotd no
TCPKeepAlive no
AcceptEnv LANG LC_*
Subsystem sftp internal-sftp
EOF
# Vérifier la syntaxe avant de recharger
sshd -t && echo "Config OK" && systemctl restart ssh
Nettoyage des références à l’ancien PBS de Neo #
Maintenant que Neo est réinstallé en ZFS et que PBS tourne dans le LXC 107 sur Morpheus, il faut supprimer toutes les références à l’ancien PBS bare metal de Neo.
pct exec 107 -- bash
# Supprimer le sync job
proxmox-backup-manager sync-job remove neo-pbs-sync
# Supprimer le remote
proxmox-backup-manager remote remove neo-pbs
# Vérifier
proxmox-backup-manager sync-job list
proxmox-backup-manager remote list
# Depuis Morpheus — supprimer le storage PVE
pvesm remove local-lvm-backup
L’ancien PBS de Neo n’a plus aucune référence dans l’infrastructure. ✅
Partie 3 — DNS zone allfabox.fr et Split Horizon #
Création de la zone allfabox.fr sur ns1 #
Dans l’interface Technitium de ns1 (http://10.10.10.53:5380) :
Zones → Add Zone
Zone Name : allfabox.fr
Type : Primary Zone
Catalog Zone : cluster-catalog.dns.allfabox.fr
Zone Serial : Use SOA Serial Date Scheme ✅
Configuration de l’app Split Horizon #
Apps → Split Horizon → Config
{
"enableAddressTranslation": true,
"domainGroupMap": {},
"networkGroupMap": {},
"networks": {
"unifi": [
"10.10.10.0/24",
"10.10.20.0/24",
"10.10.30.0/24",
"10.10.70.0/24",
"192.168.0.100/32",
"192.168.0.254/32"
]
},
"groups": []
}
Enregistrements APP Split Horizon #
Tous les enregistrements utilisent le même template :
{
"unifi": ["10.99.99.10"],
"0.0.0.0/0": ["82.66.24.30"]
}
Liste des enregistrements créés :
@ APP SplitHorizon.SimpleAddress
* APP SplitHorizon.SimpleAddress
dns APP SplitHorizon.SimpleAddress
*.dns APP SplitHorizon.SimpleAddress
home APP SplitHorizon.SimpleAddress
*.home APP SplitHorizon.SimpleAddress
garage APP SplitHorizon.SimpleAddress
*.garage APP SplitHorizon.SimpleAddress
scaleway APP SplitHorizon.SimpleAddress
*.scaleway APP SplitHorizon.SimpleAddress
garmin APP SplitHorizon.SimpleAddress
*.garmin APP SplitHorizon.SimpleAddress
hetzner APP SplitHorizon.SimpleAddress
*.hetzner APP SplitHorizon.SimpleAddress
perfecthomelab CNAME allfab.github.io
Validation du Split Horizon #
# Depuis morpheus (réseau unifi) → doit retourner 10.99.99.10
dig @10.10.10.53 allfabox.fr
# → 10.99.99.10 ✅
# Depuis l'extérieur → doit retourner 82.66.24.30
dig @1.1.1.1 allfabox.fr
# → 82.66.24.30 ✅
Propagation DNS sur l’infrastructure #
morpheus → DNS 10.10.10.53 / 10.10.20.53 ✅
neo → DNS 10.10.10.53 / 10.10.20.53 ✅
LXC (tous) → héritent de l'hôte ✅
UCG VLANs → DNS 10.10.10.53 / 10.10.20.53 ✅
oracle → DNS via netplan (routes statiques) ✅
Désactivation de ns1 Freebox #
Une fois la migration validée, l’ancien serveur DNS Freebox (192.168.0.153) est désactivé. ✅
Partie 4 — Réplication ZFS et HA Manager #
Politique de réplication #
La réplication Proxmox utilise zfs send/receive pour synchroniser les disques des LXC vers neo. Elle ne réplique que les datasets ZFS — les bind mounts vers les disques hôtes (mergerfs, tank, etc.) ne sont pas répliqués.
Après analyse des mountpoints de chaque LXC, seuls 3 LXC sont candidats à une réplication utile :
ct:110 - frontend → disque racine uniquement (config Traefik/Authelia)
ct:120 - elephant → disque racine uniquement (config PostgreSQL)
ct:130 - smarthome → disque racine + données HA
Les autres LXC (142 Nextcloud, 143 Immich, 150 Webapps, etc.) ont tous des bind mounts vers des données volumineuses non réplicables — le job PBS hebdomadaire est plus adapté pour eux.
Configuration des jobs de réplication #
# LXC 130 - smarthome (toutes les 2h)
pvesr create-local-job 130-0 neo --schedule '*/2:00'
# LXC 110 - frontend (1x/jour à 2h)
# Via l'UI : schedule 02:00
# LXC 120 - elephant (toutes les 2h)
# Via l'UI : schedule */2:00
Vérification :
pvesr list
JobID Target Schedule Enabled
110-0 local/neo 02:00 yes
120-0 local/neo */2:00 yes
130-0 local/neo */2:00 yes
Activation du HA Manager #
Important : activer la HA sur un LXC avant que sa première réplication soit terminée est risqué. Attendre que
pvesr statusafficheOKpour le LXC concerné.
ha-manager add ct:130 --state started --max_restart 1 --max_relocate 1
ha-manager add ct:110 --state started --max_restart 1 --max_relocate 1
ha-manager add ct:120 --state started --max_restart 1 --max_relocate 1
Test de bascule #
# Mettre morpheus en maintenance
ha-manager crm-command node-maintenance enable morpheus
# Surveiller la bascule
ha-manager status
# → service ct:130 (neo, started) ✅
# Remettre morpheus en service
ha-manager crm-command node-maintenance disable morpheus
# Vérifier le failback automatique
ha-manager status
# → service ct:130 (morpheus, started) ✅
La bascule et le retour automatique fonctionnent parfaitement. Home Assistant reste accessible pendant toute la durée du test.
État final du HA Manager #
ha-manager status
quorum : OK
fencing : armed (CRM watchdog active)
lrm morpheus: active, watchdog active
lrm neo : idle, watchdog standby
ct:110 (morpheus, started) ✅ frontend
ct:120 (morpheus, started) ✅ elephant (PostgreSQL)
ct:130 (morpheus, started) ✅ smarthome (Home Assistant)
Architecture finale du cluster MATRIX #
graph TB
subgraph MATRIX["CLUSTER MATRIX — HA opérationnel"]
subgraph MorpheusG["Morpheus — nœud principal"]
MorpheusNode["Morpheus
10.10.10.5
ZFS mirror 2x NVMe"]
LXC107["LXC 107 — PBS
10.10.10.7"]
LXC110["LXC 110 — Frontend HA
Traefik/Authelia"]
LXC120["LXC 120 — Elephant HA
PostgreSQL/PostGIS"]
LXC130["LXC 130 — Smarthome HA
Home Assistant"]
end
subgraph NeoG["Neo — nœud secondaire"]
NeoNode["Neo
10.10.10.6
ZFS single SSD 897 Go"]
LXC253["LXC 253 — ns2
10.10.20.53"]
end
Oracle["oracle
192.168.0.50
QDevice VM Freebox"]
end
subgraph DNSCluster["DNS Cluster Technitium"]
ns1["ns1.dns.allfabox.fr
10.10.10.53 — RPi 3B"]
ns2["ns2.dns.allfabox.fr
10.10.20.53 — LXC 253"]
end
MorpheusNode <-->|corosync + réplication ZFS| NeoNode
MorpheusNode <-->|TCP 5403| Oracle
NeoNode <-->|TCP 5403| Oracle
MorpheusNode --> LXC107
MorpheusNode --> LXC110
MorpheusNode --> LXC120
MorpheusNode --> LXC130
NeoNode --> LXC253
LXC253 -.- ns2
ns1 <-->|synchro cluster| ns2
style MorpheusNode fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style NeoNode fill:#dbeafe,stroke:#1e40af,stroke-width:2px,color:#000
style Oracle fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#000
style LXC107 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style LXC110 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style LXC120 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style LXC130 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style LXC253 fill:#dcfce7,stroke:#166534,stroke-width:2px,color:#000
style ns1 fill:#f3e8ff,stroke:#7e22ce,stroke-width:2px,color:#000
style ns2 fill:#f3e8ff,stroke:#7e22ce,stroke-width:2px,color:#000
Bilan : est-ce vraiment de la HA ? #
Oui, et le test le confirme. En cas de panne de morpheus :
morpheus tombe
↓ ~30 secondes (détection corosync + QDevice)
HA Manager bascule ct:110, ct:120, ct:130 sur neo
↓ ~2 minutes
Traefik, PostgreSQL et Home Assistant opérationnels sur neo 😴
| Critère | Ce cluster | Enterprise |
|---|---|---|
| Bascule automatique | ✅ | ✅ |
| RTO | ~2-3 min | ~1 min |
| RPO | ~2h (réplication) | ~0 |
| Coût | 0 € | $$$ |
Pour un homelab domotique, le rapport qualité/complexité/coût est imbattable.
Ce qui reste optionnel #
- Scaleway S3 — reconfigurer le backup offsite
- Réplication PBS —
rpool/backupsvers neo (données de backup) - DNSSEC sur la zone
allfabox.fr - Restriction firewall — limiter la règle Oracle QDevice au port TCP 5403 uniquement