In diesem Artikel wird erklärt, die man seine VMs an die Außenwelt anbinden kann. Es wird der aktuelle Status nach Teil 1 dieser Artikelserie vorausgesetzt.

Inhalt

Vorwort

Das Setup, welches ich hier vorstelle mag, zumindest für den Betrieb in einem Rechenzentrum, sehr speziell sein, aber man kann es recht einfach so abändern, dass es zu den eigenen Bedürfnissen passt.

Das Setup

Das Setup meines Hostsystems ist ähnlich zu einem Rechner, der im privaten LAN steht. Ich habe ein Netz zugewiesen bekommen (Nehmen wir hier einfach mal als Beispiel 192.168.199.0/24 (Mir ist klar, dass dies ein privates Subnetz ist, aber es ist ja auch nur ein Beispiel)), bei dem ich mir jede beliebige IP raus nehmen kann.

Der Knackpunkt an der Sache ist, dass:

  1. Das Netz nicht auf meinen Server gerouted wird, sondern die IPs via ARP verteilt werden (Wie in einem normalen LAN)
  2. Sich das Gateway innerhalb dieses Netzes befindet (sagen wir mal 192.168.199.1)

Überlegungen

  • Ich möchte die IP-Adressen, welche mir zugewiesen worden sind mit den VMs nutzen.
  • Ich möchte dies so effizient wie möglich tun (Keine IP-s verschwenden für subnetierung)
  • Virtuelle MAC-Adressen sind nicht global eindeutig
    • Gefahr der Doppelbelegung
      • MAC-Adressen müssen im Rechenzentrum unsichtbar sein
  • Erzeugter Traffic muss den VMs zugeordnet werden können
    • keine von LibVirt erzeugten dynamischen NICs, sondern persistente NICs

 

Konzept

Diese Überlegungen brachten mich auf folgendes Konzept. Da ich persistente NICs für die VMs haben wollte durften diese nicht über LibVirt erstellt werden. Hierfür habe ich mich dann für den TUN/TAP-Treiber entschieden, mit dem man persistente(bis zum nächsten reboot) virtuelle NICs erstellen kann. So erhält jede VM ein eigenes tap-device. Um meine Maschinen im Netz unsichtbar zu machen, dürfen sie keinen direkten Zugang dazu haben, sondern müssen über den Host gerouted werden. Eine bridge der virtuellen NICs mit eth0 (der physikalischen NIC) fällt also flach. Stattdessen habe ich eine bridge über alle tap devices erstellt.

Aktuelle Situation der möglichen Kommunikation: VM <-> VM [check] VM <-> Host [check] VM <-> Internet [nicht check]

Damit meine VMs die Außenwelt erreichen können, muss diese ja wissen, dass die Pakete, die zu den IPs der VMs gehen vorher über mein Hostsystem geleitet werden müssen.

Da mein Hoster (warum auch immer) diese Route nicht in den Core-Router eintragen wollte, musste ich mir anders helfen. Hier kam dann Proxy-ARP ins Spiel. Der Host nimmt also jetzt stellvertretend für die VMs alle Pakete an und leitet diese dann weiter.

Soweit so gut, kommen wir nun zu der Umsetzung des Ganzen.

 

Umsetzung

Bei der Umsetzung gehen wir davon aus, dass die jeweiligen virtuellen NICs bereits erstellt worden sind (siehe Teil 1 dieser Artikelreihe). Wir brauchen also als erstes eine Bridge. Diese legen wir mit folgendem Befehl an:
brctl addbr br0
Zu dieser Bridge fügen wir jetzt unsere NICs hinzu. Ich werde dass hier jetzt einmal mit dem tap1 aus Teil 1 erledigen.
brctl addif br0 tap1
Als nächstes müssen wir IP-Forwarding und Proxy-ARP aktivieren:
#IP-Forwarding aktivieren
echo 1 > /proc/sys/net/ipv4/conf/all/forwarding

#Proxy-ARP aktivieren echo 1 > /proc/sys/net/ipv4/conf/br0/proxy_arp echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp

Bis hier hin nimmt der Host jetzt alle Pakete an, die von den VMs an das Gateway gehen. Um Pakete von außen an die VMs weiter zu leiten muss für jede verwendete IP noch eine Route gesetzt werden. Ich mache das hier beispielhaft mal für die IP 192.168.199.123

route add -host 192.168.199.123 dev br0
Nun kann innerhalb der VM die IP 192.168.123 mit der Netzmaske 255.255.255.0 und dem Gateway 192.168.199.1 eingerichtet werden und ist darüber von außen erreichbar.

  Damit diese Einstellungen auch nach dem Booten erhalten bleiben empfiehlt es sich ein init-script zu erstellen. Sollte einem das zuviel Aufwand sein, kann man auch alle Befehle in die /etc/rc.local vor die Zeile mit dem “exit 0” schreiben.