Im wondering how would i go on about assigning a public ipv4 to each vm thats being created.
Setup :
Host Server with 3 IPs on CentOS8
using libvirt and kvm to virtualize
Bridge br0 using eth0 as interface.
After a lot of Trial and Error i managed to do it manually by using a bridge and assigning the IP-Address to the interface of the Guest OS Network File.
Though i wish this would be automatic considering that if i reinstall the OS now it would go back to not having the IP-Address and id have to connect to the Guest and edit the ipv4-address in the network files manually everytime. How can i avoid this ?
Goal : each IPv4 is hardlocked to a Virtual Machine and will stay no matter if the OS gets reinstalled.
Optional Goal : If any IPv4 from the Host OS is unused, it should be assigned to the next VM created.
Do i have to code my own software to do this everytime or is there a simpler way ?
Best Answer
This is what DHCP is for.
You can freely choose their MAC addresses, right? Setup a DHCP server on the system in the same (possibly, virtual) ethernet segment as VMs, and bind your IPs to certain MACs.
You will also need to distribute some routes (use DHCP options 121 and 249). The machine with DHCP server itself doesn't need to have public IP or IP in the same network as all clients; the communication with DHCP server takes place when there are still no addresses configured on the client anyway.
If you use ISC DHCP, you need to do something like the following. I am assuming your host machine is your router and NAT box for VMs and it also will host your DHCP server. If you want to do other way, slight adjustments will be required:
dhcpd.conf
:probably, new versions don't need this, but mine does.
shared-network
block, put your dynamic private subnet and your public addresses as "subnets" with masks 32:I am assuming your "private" network for machines behind NAT will be 192.168.210.0/24 and the host will be .1 in that network (assigned to a bridge). Static classless routes (options 121 and 249) setting will add following routes:
which are needed for everything to work despite the fact there is no subnet containing 192.0.2.1/32 and 192.168.210.1; better try such setup in lab environment if you are unsure how this routing works
/etc/ethers
(on the host):Then make sure you assign those MACs to your important VMs within libvirt configs. Other VMs (whose MACs aren't bound) will get their addresses from the configured range as usual.
Actually I implemented and tested this setup in even "more complex" setup (DHCP, host and router all were distinct systems), also I dont' use libvirt and my host is PVE. Even PXE booting perfectly works for both "normal" subnetwork machines (like 192.168.210.0 in the example) and for "public IP" machines (like 192.0.2.1).
To allow all VMs to access Internet you have to use NAT for private IPs and to not to use it for public; it is not a problem, use the rule like
iptables -t nat -A POSTROUTING -o <physical-interface-with-public-ip> -s <private-ip-range> -j MASQUERADE
. This way, your private range will be translated to the public-facing address of the host itself, but public addresses will not get translated, but will be routed as they are. Again, it is no problem having public and private addresses on the same network segment and walking through the same virtual NIC.