Ich frage mich, wie ich vorgehen soll, um jeder erstellten VM eine öffentliche IPv4-Adresse zuzuweisen.
Setup: Hostserver mit 3 IPs auf CentOS8 unter Verwendung von libvirt und kvm, um Bridge br0 mit eth0 als Schnittstelle zu virtualisieren.
Nach viel Herumprobieren habe ich es geschafft, es manuell zu machen, indem ich eine Bridge verwendet und die IP-Adresse der Schnittstelle der Netzwerkdatei des Gastbetriebssystems zugewiesen habe.
Ich wünschte allerdings, das würde automatisch passieren, wenn man bedenkt, dass bei einer Neuinstallation des Betriebssystems die IP-Adresse wieder fehlt und ich mich jedes Mal mit dem Gast verbinden und die IPv4-Adresse in den Netzwerkdateien manuell bearbeiten muss. Wie kann ich das vermeiden?
Ziel: Jede IPv4 ist fest an eine virtuelle Maschine gebunden und bleibt bestehen, unabhängig davon, ob das Betriebssystem neu installiert wird.
Optionales Ziel: Wenn eine IPv4-Adresse des Host-Betriebssystems ungenutzt ist, sollte sie der nächsten erstellten VM zugewiesen werden.
Muss ich dafür jedes Mal meine eigene Software programmieren oder gibt es einen einfacheren Weg?
Antwort1
Hierfür ist DHCP da.
Sie können ihre MAC-Adressen frei wählen, oder? Richten Sie einen DHCP-Server auf dem System im selben (möglicherweise virtuellen) Ethernet-Segment wie VMs ein und binden Sie Ihre IPs an bestimmte MACs.
Sie müssen auch einige Routen verteilen (verwenden Sie die DHCP-Optionen 121 und 249). Die Maschine mit dem DHCP-Server selbst muss keine öffentliche IP-Adresse oder IP-Adresse im selben Netzwerk wie alle Clients haben; die Kommunikation mit dem DHCP-Server findet statt, wenn auf dem Client ohnehin noch keine Adressen konfiguriert sind.
Wenn Sie ISC DHCP verwenden, müssen Sie etwa Folgendes tun. Ich gehe davon aus, dass Ihr Host-Rechner Ihr Router und Ihre NAT-Box für VMs ist und auch Ihren DHCP-Server hosten wird. Wenn Sie es anders machen möchten, sind geringfügige Anpassungen erforderlich:
- Definieren Sie die Optionen 121 und 249 irgendwo oben im
dhcpd.conf
:
option rfc3442-classless-static-routes code 121 = array of integer 8;
option ms-classless-static-routes code 249 = array of integer 8;
Neuere Versionen benötigen dies wahrscheinlich nicht, meine jedoch schon.
- Erstellen Sie einen
shared-network
Block, setzen Sie Ihr dynamisches privates Subnetz und Ihre öffentlichen Adressen als „Subnetze“ mit den Masken 32:
option routers 192.168.210.1;
option domain-name-servers 8.8.8.8, 8.8.4.4;
shared-network libvirt-vm-net {
subnet 192.168.210.0 netmask 255.255.255.0 {
range 192.168.210.2 192.168.210.254;
}
subnet 192.0.2.1 netmask 255.255.255.255 {
option rfc3442-classless-static-routes 32, 192,168,210,1, 0,0,0,0, 0, 192,168,210,1;
option ms-classless-static-routes 32, 192,168,210,1, 0,0,0,0, 0, 192,168,210,1;
}
...
}
Ich gehe davon aus, dass Ihr „privates“ Netzwerk für Maschinen hinter NAT 192.168.210.0/24 ist und der Host in diesem Netzwerk .1 ist (einer Bridge zugewiesen). Die Einstellung „Statische klassenlose Routen“ (Optionen 121 und 249) fügt folgende Routen hinzu:
ip route add 192.168.210.1 dev eth0
ip route add default via 192.168.210.1
die benötigt werden, damit alles funktioniert, auch wenn es kein Subnetz mit 192.0.2.1/32 und 192.168.210.1 gibt; wenn Sie sich nicht sicher sind, wie dieses Routing funktioniert, probieren Sie ein solches Setup besser in einer Laborumgebung aus
- Erstellen Sie Hostdefinitionen mit den gewünschten MAC-Adressen, die an Ihre statischen IP-Adressen gebunden sind:
host public-server-1 { hardware ethernet 00:11:22:33:44:55; fixed-address 192.0.2.1; }
...
- Fügen Sie für diese MACs statische Nachbareinträge („ARP“) hinzu
/etc/ethers
(auf dem Host):
00:11:22:33:44:55 192.0.2.1
...
- Fügen Sie über die entsprechende Bridge-Schnittstelle statische Routen zu diesen Adressen hinzu. Ich weiß nicht, wie das mit der Standardnetzwerkkonfiguration Ihrer Betriebssystemdistribution geht, aber die allgemeine Linux-Methode sieht folgendermaßen aus:
ip route add 192.0.2.1 dev br0
...
Stellen Sie dann sicher, dass Sie diese MACs Ihren wichtigen VMs in den Libvirt-Konfigurationen zuweisen. Andere VMs (deren MACs nicht gebunden sind) erhalten ihre Adressen wie üblich aus dem konfigurierten Bereich.
Tatsächlich habe ich dieses Setup in einem noch „komplexeren“ Setup implementiert und getestet (DHCP, Host und Router waren alle unterschiedliche Systeme), außerdem verwende ich kein Libvirt und mein Host ist PVE. Sogar das PXE-Booten funktioniert sowohl für „normale“ Subnetzmaschinen (wie 192.168.210.0 im Beispiel) als auch für „öffentliche IP“-Maschinen (wie 192.0.2.1) einwandfrei.
Um allen VMs den Internetzugang zu ermöglichen, müssen Sie NAT für private IPs verwenden und nicht für öffentliche. Das ist kein Problem, verwenden Sie die Regel wie iptables -t nat -A POSTROUTING -o <physical-interface-with-public-ip> -s <private-ip-range> -j MASQUERADE
. Auf diese Weise wird Ihr privater Bereich in die öffentliche Adresse des Hosts selbst übersetzt, öffentliche Adressen werden jedoch nicht übersetzt, sondern so weitergeleitet, wie sie sind. Auch hier ist es kein Problem, öffentliche und private Adressen im selben Netzwerksegment zu haben und über dieselbe virtuelle Netzwerkkarte zu laufen.