587 lines
20 KiB
Markdown
587 lines
20 KiB
Markdown
# 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
|
|
|
|
- **Auto-Detect** aller Nodes, Bridges, IPs und Netzwerke
|
|
- Koordinierte Migration aller Nodes in einem Durchgang
|
|
- **Multi-NIC-Support** — erkennt automatisch Management-, Ceph-Public- und Ceph-Cluster-Bridges
|
|
- 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
|
|
- **Passwort-Auth via `.env`** — unabhängig von `/etc/pve`, funktioniert immer
|
|
- 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
|
|
- `sshpass` — wird beim ersten Start automatisch installiert falls nicht vorhanden
|
|
- Root-Passwort der Proxmox-Nodes (alle Nodes müssen das gleiche Passwort haben)
|
|
- 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 <repo-url> proxmox-cluster-network-changer
|
|
|
|
# .env erstellen
|
|
cd proxmox-cluster-network-changer
|
|
cp .env.example .env
|
|
nano .env # SSH_PASSWORD=dein-root-passwort eintragen
|
|
```
|
|
|
|
## SSH-Authentifizierung
|
|
|
|
Das Tool nutzt `sshpass` mit dem Root-Passwort aus der `.env`-Datei. Key-basierte Auth funktioniert bei Proxmox nicht zuverlässig, weil `/etc/pve/priv/authorized_keys` verschwindet wenn `pve-cluster` gestoppt wird.
|
|
|
|
```bash
|
|
# .env-Datei erstellen
|
|
echo 'SSH_PASSWORD=dein-root-passwort' > .env
|
|
```
|
|
|
|
> **Hinweis:** Alle Nodes müssen das gleiche Root-Passwort haben (bei Proxmox-Clustern üblich).
|
|
|
|
## 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:
|
|
|
|
```
|
|
============================================================
|
|
Proxmox Cluster Network Changer
|
|
============================================================
|
|
|
|
[SSH] Passwort-Authentifizierung aktiv (via sshpass)
|
|
|
|
=== 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: 10.0.1.0/24
|
|
|
|
=== Phase 2: Migration planen ===
|
|
|
|
[Netzwerk-Erkennung]
|
|
vmbr0: Management/Corosync (192.168.0.0/24)
|
|
vmbr1: Ceph Cluster (10.0.1.0/24)
|
|
|
|
[Management-Netzwerk (Corosync)]
|
|
Aktuell: 192.168.0.0/24
|
|
Neues Management-Netzwerk (z.B. 172.0.2.0/16): 172.0.2.0/16
|
|
Neues Gateway [172.0.0.1]: 172.0.2.1
|
|
|
|
[Management IP-Mapping]
|
|
pve1: 192.168.0.101 -> [172.0.2.101]:
|
|
pve2: 192.168.0.102 -> [172.0.2.102]:
|
|
|
|
[Ceph Netzwerke]
|
|
Ceph Public: gleich wie Management -> wird automatisch mit umgezogen
|
|
Ceph Cluster (10.0.1.0/24) auf separater NIC -> eigenes Mapping
|
|
|
|
Migration durchführen? [j/N]: j
|
|
```
|
|
|
|
Das Tool erkennt automatisch welche Bridges welche Netzwerke tragen.
|
|
Wenn Ceph Public/Cluster auf separaten NICs liegen, werden die IPs einzeln pro Node abgefragt.
|
|
|
|
### 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-port PORT` | SSH-Port (Standard: 22) |
|
|
| `--env-file PFAD` | Pfad zur .env-Datei (Standard: `.env`) |
|
|
|
|
### `.env`-Datei
|
|
|
|
| Variable | Beschreibung |
|
|
|---|---|
|
|
| `SSH_PASSWORD` | **Pflicht.** Root-Passwort für SSH (alle Nodes gleich) |
|
|
| `SSH_USER` | SSH-Benutzer (Standard: `root`) |
|
|
|
|
## Was wird geändert?
|
|
|
|
| Datei | Wo | Was |
|
|
|---|---|---|
|
|
| `/etc/network/interfaces` | Jeder Node | Alle Bridge-IPs (Management, Ceph), 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 |
|
|
| `/etc/pve/storage.cfg` | Cluster-FS | monhost-IPs für CephFS- und RBD-Storage |
|
|
|
|
## 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 → `/etc/pve` unmounted
|
|
4. Corosync-Config wird direkt geschrieben (`/etc/corosync/corosync.conf`)
|
|
5. `/etc/hosts` wird aktualisiert
|
|
6. `/etc/network/interfaces` wird aktualisiert + Netzwerk-Reload:
|
|
- Remote-Nodes zuerst (fire-and-forget via `nohup`)
|
|
- Lokaler Node zuletzt
|
|
- Verifikation der neuen IPs mit Retry
|
|
7. Services starten (pve-cluster, corosync), Quorum abwarten, Ceph aktualisieren
|
|
|
|
> SSH funktioniert durchgehend via `sshpass` — unabhängig von `/etc/pve`.
|
|
|
|
## 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. Rescue-IPs werden durch `ifreload -a` 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
|
|
|
|
### Workaround: Corosync zeigt noch alte IPs in der GUI
|
|
|
|
Falls nach der Migration in der Proxmox-GUI unter **Datacenter → Cluster** noch die alten IPs stehen, wurde `/etc/pve/corosync.conf` nicht aktualisiert. Das passiert weil `/etc/pve` während der Migration read-only ist und die Config nur direkt nach `/etc/corosync/corosync.conf` geschrieben wird. Aktuelle Versionen des Tools aktualisieren `/etc/pve/corosync.conf` automatisch nach dem Quorum.
|
|
|
|
```bash
|
|
# 1. Prüfen was wo drin steht:
|
|
grep -A1 ring0_addr /etc/corosync/corosync.conf
|
|
grep -A1 ring0_addr /etc/pve/corosync.conf
|
|
|
|
# 2. Wenn /etc/corosync/corosync.conf die neuen IPs hat:
|
|
cp /etc/corosync/corosync.conf /etc/pve/corosync.conf
|
|
|
|
# 3. Falls auch /etc/corosync/corosync.conf die alten IPs hat,
|
|
# manuell editieren (IPs anpassen):
|
|
nano /etc/pve/corosync.conf
|
|
|
|
# 4. config_version in /etc/pve/corosync.conf hochzählen
|
|
# (Pflicht, damit alle Nodes die Änderung übernehmen)
|
|
# Die Zeile steht ganz oben/oder fast unten in der Datei im totem {} Block:
|
|
#
|
|
# totem {
|
|
# ...
|
|
# config_version: 4 <-- diese Zahl um 1 erhöhen (z.B. 4 -> 5)
|
|
# }
|
|
#
|
|
# Aktuelle Version anzeigen:
|
|
grep config_version /etc/pve/corosync.conf
|
|
|
|
# 5. Corosync neu starten:
|
|
systemctl restart corosync
|
|
```
|
|
|
|
### Workaround: Ceph MON-Map manuell aktualisieren
|
|
|
|
Falls nach der Migration `ceph-mon` und `ceph-mgr` nicht starten (z.B. weil eine ältere Version des Tools die MON-Map nicht aktualisiert hat), muss die Ceph MON-Map manuell korrigiert werden. Die MON-Map ist eine interne Datenbank in der die MON-Adressen gespeichert sind — ein reines Update der `ceph.conf` reicht nicht.
|
|
|
|
**Wichtig:** Die MON-Map muss auf allen Nodes identisch sein (gleiche Epoch), sonst crasht Ceph mit `notify_rank_removed`. Deshalb: auf **einem** Node erstellen und auf die anderen kopieren.
|
|
|
|
**Schritt 1: MON auf allen Nodes stoppen**
|
|
|
|
```bash
|
|
# Auf JEDEM Node:
|
|
systemctl stop ceph-mon@$(hostname)
|
|
```
|
|
|
|
**Schritt 2: MON-Map auf dem ersten Node erstellen**
|
|
|
|
```bash
|
|
# Auf pve1 (oder einem beliebigen Node):
|
|
ceph-mon -i $(hostname) --extract-monmap /tmp/monmap
|
|
monmaptool --print /tmp/monmap
|
|
|
|
# Alte Einträge entfernen (für jeden MON-Node)
|
|
monmaptool --rm pve1 /tmp/monmap
|
|
monmaptool --rm pve2 /tmp/monmap
|
|
monmaptool --rm pve3 /tmp/monmap
|
|
|
|
# Neue Einträge mit neuen IPs hinzufügen
|
|
monmaptool --addv pve1 [v2:172.0.2.101:3300/0,v1:172.0.2.101:6789/0] /tmp/monmap
|
|
monmaptool --addv pve2 [v2:172.0.2.102:3300/0,v1:172.0.2.102:6789/0] /tmp/monmap
|
|
monmaptool --addv pve3 [v2:172.0.2.103:3300/0,v1:172.0.2.103:6789/0] /tmp/monmap
|
|
|
|
# Ergebnis prüfen
|
|
monmaptool --print /tmp/monmap
|
|
|
|
# Injizieren und MON starten
|
|
ceph-mon -i $(hostname) --inject-monmap /tmp/monmap
|
|
systemctl start ceph-mon@$(hostname)
|
|
```
|
|
|
|
**Schritt 3: Autoritative Map holen und auf die anderen Nodes kopieren**
|
|
|
|
```bash
|
|
# Auf pve1 (wo der MON jetzt läuft):
|
|
ceph mon getmap -o /tmp/monmap_auth
|
|
|
|
# Auf die anderen Nodes kopieren:
|
|
scp /tmp/monmap_auth root@172.0.2.102:/tmp/monmap
|
|
scp /tmp/monmap_auth root@172.0.2.103:/tmp/monmap
|
|
```
|
|
|
|
**Schritt 4: Auf jedem weiteren Node injizieren und starten**
|
|
|
|
```bash
|
|
# Auf pve2, pve3, etc.:
|
|
ceph-mon -i $(hostname) --inject-monmap /tmp/monmap
|
|
systemctl start ceph-mon@$(hostname)
|
|
systemctl restart ceph-mgr@$(hostname)
|
|
systemctl restart ceph-osd.target
|
|
systemctl restart ceph-mds@$(hostname) # nur wenn CephFS vorhanden
|
|
rm -f /tmp/monmap
|
|
```
|
|
|
|
> **Hinweis:** Node-Namen und IPs an das eigene Setup anpassen. Aktuelle Versionen des Tools aktualisieren die MON-Map automatisch.
|
|
|
|
### Fehlerbehebung: Ghost-Monitor entfernen (z.B. "Unknown" MON auf falschem Node)
|
|
|
|
Falls nach der Migration ein Monitor auf einem Node auftaucht, der eigentlich keinen MON haben sollte (z.B. `mon.pvetest04` zeigt "Unknown" im Dashboard), wurde versehentlich eine MON-Map auf einen Nicht-MON-Node injiziert. Aktuelle Versionen des Tools erkennen automatisch welche Nodes tatsächlich einen MON betreiben und überspringen die anderen.
|
|
|
|
**Symptom:** Im Ceph-Dashboard oder bei `ceph -s` erscheint ein zusätzlicher Monitor mit Status "Unknown" oder "out of quorum" auf einem Node, der nie einen MON hatte.
|
|
|
|
**Schritt 1: Ghost-Monitor aus dem Cluster entfernen**
|
|
|
|
```bash
|
|
# Auf einem Node mit funktionierendem MON:
|
|
ceph mon remove pvetest04 # Name des Ghost-Monitors anpassen
|
|
|
|
# Prüfen ob der Ghost weg ist:
|
|
ceph mon stat
|
|
ceph -s
|
|
```
|
|
|
|
**Schritt 2: Reste auf dem betroffenen Node aufräumen**
|
|
|
|
```bash
|
|
# Auf dem Node, der den Ghost-Monitor hatte (z.B. pvetest04):
|
|
systemctl stop ceph-mon@$(hostname)
|
|
systemctl disable ceph-mon@$(hostname)
|
|
|
|
# MON-Datenverzeichnis entfernen (falls vorhanden):
|
|
rm -rf /var/lib/ceph/mon/ceph-$(hostname)
|
|
|
|
# Prüfen ob noch MON-Prozesse laufen:
|
|
ps aux | grep ceph-mon
|
|
# Wenn nur der grep-Prozess selbst erscheint, ist alles sauber:
|
|
# root 137377 0.0 0.0 6332 2176 pts/0 S+ 08:00 0:00 grep ceph-mon
|
|
# -> Kein ceph-mon läuft mehr, alles OK.
|
|
#
|
|
# Falls noch ein echter ceph-mon-Prozess läuft (z.B. /usr/bin/ceph-mon ...):
|
|
kill <PID>
|
|
```
|
|
|
|
**Schritt 3: ceph.conf bereinigen (falls nötig)**
|
|
|
|
```bash
|
|
# Prüfen ob eine [mon.pvetest04]-Sektion existiert:
|
|
grep -A3 '\[mon.pvetest04\]' /etc/pve/ceph.conf
|
|
|
|
# Falls ja, diese Sektion aus /etc/pve/ceph.conf entfernen:
|
|
nano /etc/pve/ceph.conf
|
|
# -> Die komplette [mon.pvetest04]-Sektion löschen
|
|
|
|
# Ebenso die IP aus der mon_host-Zeile entfernen, falls dort gelistet:
|
|
grep mon_host /etc/pve/ceph.conf
|
|
```
|
|
|
|
> **Hinweis:** Dieses Problem tritt nur bei älteren Versionen des Tools auf. Aktuelle Versionen erkennen die tatsächlichen MON-Nodes anhand der `[mon.X]`-Sektionen in `ceph.conf`, der `mon_host`-Liste oder durch Prüfung des `/var/lib/ceph/mon/`-Verzeichnisses.
|
|
|
|
### Fehlerbehebung: "X daemons have recently crashed" Warnung entfernen
|
|
|
|
Nach der Migration kann im Ceph-Dashboard unter **Health** folgende Warnung erscheinen:
|
|
|
|
```
|
|
Status: HEALTH_WARN
|
|
! clock skew detected on mon.pvetest03
|
|
! 23 daemons have recently crashed
|
|
```
|
|
|
|

|
|
|
|
Die Crash-Meldungen stammen von den Daemon-Neustarts während der Migration und sind nicht kritisch. Ceph speichert Crash-Dumps unter `/var/lib/ceph/crash/` und meldet diese solange sie nicht archiviert wurden.
|
|
|
|
**Crash-Dumps anzeigen:**
|
|
|
|
```bash
|
|
ceph crash ls
|
|
```
|
|
|
|
**Alle Crash-Dumps als gelesen markieren (archivieren):**
|
|
|
|
```bash
|
|
ceph crash archive-all
|
|
```
|
|
|
|
**Prüfen ob die Warnung weg ist:**
|
|
|
|
```bash
|
|
ceph -s
|
|
# -> HEALTH_OK (oder nur noch clock skew, falls NTP nicht synchron)
|
|
```
|
|
|
|
> **Hinweis:** Falls zusätzlich `clock skew detected` angezeigt wird, NTP auf den betroffenen Nodes prüfen: `systemctl status chrony` oder `systemctl status ntp`. Nach einer Migration mit Neustarts kann die Uhrzeit kurzzeitig abweichen — das korrigiert sich in der Regel automatisch.
|
|
|
|
### Fehlerbehebung: CephFS/RBD-Storage nicht erreichbar nach Migration
|
|
|
|
Nach der Migration kann CephFS nicht erreichbar sein, weil der Kernel-Mount noch die alten MON-IPs cached. Das passiert unabhängig davon, ob `monhost` in der `storage.cfg` steht oder nicht. Aktuelle Versionen des Tools machen den Remount automatisch.
|
|
|
|
**Symptom:** CephFS-Storage zeigt Fehler in der GUI, `mount | grep ceph` zeigt alte IPs:
|
|
|
|
```
|
|
172.0.4.1,172.0.4.2,172.0.4.3:/ on /mnt/pve/cephfs type ceph (...)
|
|
```
|
|
|
|
**Fall 1: Keine `monhost`-Einträge in storage.cfg (Standard bei Proxmox)**
|
|
|
|
Proxmox holt sich die MON-IPs automatisch aus `/etc/ceph/ceph.conf`. Es reicht ein Remount:
|
|
|
|
```bash
|
|
# Auf JEDEM Node:
|
|
umount /mnt/pve/cephfs
|
|
mount /mnt/pve/cephfs
|
|
|
|
# Prüfen ob die neuen IPs verwendet werden:
|
|
mount | grep ceph
|
|
```
|
|
|
|
**Fall 2: Explizite `monhost`-Einträge in storage.cfg**
|
|
|
|
```bash
|
|
# 1. Prüfen ob monhost-Einträge vorhanden sind:
|
|
grep monhost /etc/pve/storage.cfg
|
|
|
|
# 2. Falls ja, monhost für CephFS aktualisieren (neue MON-IPs kommasepariert):
|
|
pvesm set cephfs --monhost 192.168.101.1,192.168.101.2,192.168.101.3
|
|
|
|
# 3. Falls RBD-Storage vorhanden:
|
|
pvesm set data --monhost 192.168.101.1,192.168.101.2,192.168.101.3
|
|
|
|
# 4. Dann Remount auf JEDEM Node:
|
|
umount /mnt/pve/cephfs
|
|
mount /mnt/pve/cephfs
|
|
```
|
|
|
|
> **Hinweis:** Die Storage-Namen (`cephfs`, `data`) können bei jedem Setup anders heißen. Mit `pvesm status` werden alle konfigurierten Storages angezeigt.
|
|
|
|
## Hinweise
|
|
|
|
- Das Tool muss als **root** ausgeführt werden
|
|
- Alle Nodes müssen das gleiche Root-Passwort haben
|
|
- 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 werden durch `ifreload -a` automatisch entfernt
|
|
- Bridges werden automatisch erkannt — keine manuelle Angabe nötig
|
|
- Beim Netzwerk-Reload werden Remote-Nodes zuerst umgestellt (fire-and-forget), der lokale Node zuletzt — so schneidet sich das Tool nicht selbst die Verbindung ab
|
|
- Getestet mit Proxmox VE 7.x und 8.x
|
|
|
|
## Projektstruktur
|
|
|
|
```
|
|
proxmox-cluster-network-changer/
|
|
├── main.py # Entry-Point, CLI, .env-Loader
|
|
├── 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 via sshpass (Passwort-Auth)
|
|
├── config_parser.py # Parser für Corosync/Ceph/Network Configs
|
|
├── models.py # Dataclasses (NodeInfo, CorosyncConfig, etc.)
|
|
├── .env.example # Vorlage für SSH-Credentials
|
|
└── requirements.txt # Keine externen Dependencies
|
|
```
|
|
|
|
## Typische Szenarien
|
|
|
|
### Szenario 1: Normaler Umzug (alles funktioniert noch)
|
|
|
|
```bash
|
|
echo 'SSH_PASSWORD=dein-passwort' > .env
|
|
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
|
|
```
|