# Proxmox Cluster Network Changer Migriert ein komplettes Proxmox-Cluster (inkl. Ceph) von einem Netzwerk in ein anderes. **Problem:** Wenn man bei einem Proxmox-Cluster die IPs ändert, verliert man das Quorum und `/etc/pve` wird read-only — dann kann man weder Corosync noch Ceph über das Cluster-Dateisystem konfigurieren. Dieses Tool löst das Problem durch eine koordinierte Migration aller Nodes. ## Features - Automatische Erkennung aller Nodes, IPs und Konfigurationen - Koordinierte Migration aller Nodes in einem Durchgang - Ceph-Support (Public Network, Cluster Network, MON-Adressen) - Funktioniert auch bei **gebrochenem Quorum** (z.B. wenn ein Node bereits manuell geändert wurde) - **Rescue-Netzwerk** — temporäres Emergency-Netz wenn sich Nodes nicht mehr erreichen können - Automatische Backups aller Konfigurationen vor der Migration - Dry-Run-Modus zum gefahrlosen Testen - Verifikation nach der Migration ## Voraussetzungen - Python 3.9+ (auf Proxmox standardmäßig vorhanden) - Root-Zugriff auf dem Node, auf dem das Tool läuft - SSH-Zugriff (Key-basiert) zu allen anderen Cluster-Nodes (oder Konsolenzugriff für Rescue-Modus) - Keine externen Python-Pakete nötig (nur stdlib) ## Installation ```bash # Auf einen Proxmox-Node kopieren scp -r proxmox-cluster-network-changer/ root@pve1:/root/ # Oder direkt klonen cd /root git clone proxmox-cluster-network-changer ``` ## Verwendung ### Aktuelle Konfiguration anzeigen (Discovery) ```bash python3 main.py --discover ``` Zeigt an: - Alle Cluster-Nodes mit IPs - Corosync-Konfiguration - Ceph-Netzwerke und MON-Hosts - Quorum-Status - Welche Nodes erreichbar sind ### Dry-Run (nichts wird geändert) ```bash python3 main.py --dry-run ``` Durchläuft den kompletten Prozess, zeigt alle geplanten Änderungen an, schreibt aber nichts. ### Migration durchführen ```bash python3 main.py ``` Das Tool führt interaktiv durch den Prozess: ``` === Phase 1: Discovery === [Corosync] Cluster: mycluster Nodes gefunden: 4 - pve1 (ID: 1) -> 192.168.0.101 - pve2 (ID: 2) -> 192.168.0.102 - pve3 (ID: 3) -> 192.168.0.103 - pve4 (ID: 4) -> 192.168.0.104 [Ceph] Public Network: 192.168.0.0/24 Cluster Network: 192.168.0.0/24 === Phase 2: Migration planen === Neues Netzwerk (z.B. 172.0.2.0/16): 172.0.2.0/16 Neues Gateway [172.0.0.1]: 172.0.2.1 [IP-Mapping] pve1: 192.168.0.101 -> [172.0.2.101]: pve2: 192.168.0.102 -> [172.0.2.102]: pve3: 192.168.0.103 -> [172.0.2.103]: pve4: 192.168.0.104 -> [172.0.2.104]: Migration durchführen? [j/N]: j ``` ### Optionen | Option | Beschreibung | |---|---| | `--dry-run` | Nur anzeigen, nichts ändern | | `--discover` | Nur aktuelle Config anzeigen | | `--rescue` | Rescue-Modus: Emergency-Netzwerk einrichten | | `--rescue-commands SUBNET` | Nur Rescue-Befehle ausgeben (z.B. `10.99.99.0/24`) | | `--ssh-key PFAD` | Pfad zum SSH-Key (Standard: Default-Key) | | `--ssh-port PORT` | SSH-Port (Standard: 22) | ## Was wird geändert? | Datei | Wo | Was | |---|---|---| | `/etc/network/interfaces` | Jeder Node | Bridge-IP, Gateway | | `/etc/hosts` | Jeder Node | Hostname-zu-IP-Zuordnung | | `/etc/corosync/corosync.conf` | Jeder Node | Corosync Ring-Adressen | | `/etc/pve/ceph.conf` | Cluster-FS | public_network, cluster_network, MON-Adressen | ## Migrationsablauf (Phase 4) 1. Neue Konfigurationen werden auf alle Nodes verteilt (Staging) 2. Corosync wird auf allen Nodes gestoppt 3. pve-cluster (pmxcfs) wird gestoppt 4. Corosync-Config wird direkt geschrieben (`/etc/corosync/corosync.conf`) 5. `/etc/hosts` wird aktualisiert 6. `/etc/network/interfaces` wird aktualisiert + Netzwerk-Reload (`ifreload -a`) 7. Services werden gestartet, Quorum abgewartet, Ceph aktualisiert ## Rescue-Netzwerk (Emergency Mode) **Szenario:** PVE01 hat bereits eine neue IP, PVE02-04 sind noch im alten Netz. Kein Node kann die anderen erreichen. ### Schnell: Nur Befehle anzeigen ```bash python3 main.py --rescue-commands 10.99.99.0/24 ``` Ausgabe: ``` RESCUE BEFEHLE Subnetz: 10.99.99.0/24 | Bridge: vmbr0 pve1 (192.168.0.101): ip addr add 10.99.99.1/24 dev vmbr0 pve2 (192.168.0.102): ip addr add 10.99.99.2/24 dev vmbr0 pve3 (192.168.0.103): ip addr add 10.99.99.3/24 dev vmbr0 pve4 (192.168.0.104): ip addr add 10.99.99.4/24 dev vmbr0 Zum Entfernen: ip addr del 10.99.99.1/24 dev vmbr0 # pve1 ip addr del 10.99.99.2/24 dev vmbr0 # pve2 ip addr del 10.99.99.3/24 dev vmbr0 # pve3 ip addr del 10.99.99.4/24 dev vmbr0 # pve4 ``` Diese Befehle über IPMI/iLO/iDRAC/KVM-Konsole auf jedem Node ausführen. ### Interaktiv: Rescue + Migration ```bash python3 main.py --rescue ``` oder einfach starten — wenn Nodes nicht erreichbar sind, wird automatisch gefragt: ```bash python3 main.py ``` ``` 3 Node(s) nicht erreichbar. Rescue-Netzwerk einrichten? [J/n]: j ``` Ablauf: 1. Du gibst ein freies Subnetz an (z.B. `10.99.99.0/24`) 2. Das Tool zeigt für jeden Node den `ip addr add` Befehl 3. Auf dem lokalen Node wird die IP automatisch gesetzt 4. Du führst die Befehle auf den anderen Nodes per Konsole aus 5. Das Tool testet die Verbindung und liest die Configs 6. Danach läuft die normale Migration 7. Am Ende werden die Emergency-IPs automatisch entfernt ### Wann brauche ich das? - Ein oder mehrere Nodes haben bereits manuell eine neue IP bekommen - Die Nodes liegen in verschiedenen Subnetzen - SSH zwischen den Nodes funktioniert nicht mehr - Du hast aber noch Zugriff auf die Konsolen (IPMI/iLO/iDRAC/KVM) ## Gebrochenes Quorum Wenn bereits ein Node manuell geändert wurde und das Quorum verloren ist: - Das Tool erkennt den Zustand automatisch in der Discovery-Phase - Nicht erreichbare Nodes werden per Hostname gesucht - Configs werden direkt geschrieben (nicht über `/etc/pve/`) - Nach dem Netzwerk-Reload wird `pvecm expected 1` genutzt, um Quorum zu erzwingen - Danach wird Ceph über das Cluster-Dateisystem aktualisiert ## Backups Vor der Migration werden automatisch Backups erstellt: ``` /root/network-migration-backup-20260304_143022/ ├── etc_network_interfaces ├── etc_hosts ├── etc_corosync_corosync.conf ├── etc_ceph_ceph.conf ├── etc_pve_corosync.conf └── etc_pve_ceph.conf ``` ### Restore (manuell) ```bash # Beispiel: Netzwerk-Config wiederherstellen cp /root/network-migration-backup-*/etc_network_interfaces /etc/network/interfaces ifreload -a # Corosync wiederherstellen cp /root/network-migration-backup-*/etc_corosync_corosync.conf /etc/corosync/corosync.conf systemctl restart corosync ``` ## Empfohlene Reihenfolge bei Problemen 1. `pvecm status` — Cluster-Status prüfen 2. `pvecm expected 1` — Quorum erzwingen (Notfall) 3. `ceph -s` — Ceph-Status prüfen 4. `ceph -w` — Ceph-Recovery beobachten 5. `journalctl -u corosync` — Corosync-Logs prüfen 6. `journalctl -u pve-cluster` — pmxcfs-Logs prüfen ## Hinweise - Das Tool muss als **root** ausgeführt werden - SSH-Keys müssen **vorher** zwischen den Nodes eingerichtet sein (bei Proxmox-Clustern standardmäßig der Fall) - VMs/CTs werden **nicht** automatisch migriert oder gestoppt — das Netzwerk wird im laufenden Betrieb geändert - Nach der Migration sollten VM-Netzwerke (Bridges in VM-Configs) geprüft werden, falls diese sich auf spezifische IPs beziehen - Die Emergency-IPs (`ip addr add`) sind temporär und überleben keinen Reboot — sie werden nur zur SSH-Kommunikation während der Migration genutzt - Getestet mit Proxmox VE 7.x und 8.x ## Projektstruktur ``` proxmox-cluster-network-changer/ ├── main.py # Entry-Point, CLI mit allen Optionen ├── discovery.py # Phase 1: Cluster-Config lesen & parsen ├── planner.py # Phase 2: IP-Mapping, neue Configs generieren ├── backup.py # Phase 3: Backup aller Configs ├── migrator.py # Phase 4: Migration durchführen (7 Schritte) ├── verifier.py # Phase 5: Post-Migration Checks ├── rescue.py # Rescue-Netzwerk (Emergency Mode) ├── ssh_manager.py # SSH-Verbindungen (lokal + remote) ├── config_parser.py # Parser für Corosync/Ceph/Network Configs ├── models.py # Dataclasses (NodeInfo, CorosyncConfig, etc.) └── requirements.txt # Keine externen Dependencies ``` ## Typische Szenarien ### Szenario 1: Normaler Umzug (alles funktioniert noch) ```bash python3 main.py --dry-run # Erst testen python3 main.py # Dann ausführen ``` ### Szenario 2: Ein Node wurde bereits manuell geändert PVE01 hat schon die neue IP, PVE02-04 noch die alte. Kein SSH möglich. ```bash # Option A: Rescue-Befehle anzeigen und manuell ausführen python3 main.py --rescue-commands 10.99.99.0/24 # -> Befehle auf allen Nodes per IPMI/KVM eingeben # -> Dann normal starten: python3 main.py --rescue # Option B: Einfach starten, das Tool fragt automatisch python3 main.py # -> "3 Node(s) nicht erreichbar. Rescue-Netzwerk einrichten? [J/n]" ``` ### Szenario 3: Nur Discovery (schauen was los ist) ```bash python3 main.py --discover ``` ### Szenario 4: Cluster komplett kaputt, kein Quorum ```bash python3 main.py --rescue # Das Tool: # 1. Richtet Emergency-Netzwerk ein # 2. Liest Configs über Emergency-IPs # 3. Migriert alles # 4. Erzwingt Quorum mit 'pvecm expected 1' # 5. Schreibt Ceph-Config direkt (nicht über /etc/pve) # 6. Räumt Emergency-IPs auf ```