Verbinde Server in unterschiedlichen RZs per vSwitch

Verbinde Server in unterschiedlichen RZs per vSwitch

Am 04. September 2018 hat Hetzner ein neues Feature seinen Kunden zur Verfügung gestellt:

Ein vSwitch ist ein Switch, der per SDN (Software-defined Networking) Host in unterschiedlichen Rechenzentren (DCs) in einem Netz zusammenbringen kann.

Was für einen Vorteil hat dies? Manchmal benötigt man ein privates Netzwerk zwischen einzelnen Server, um z.B. Cluster funktionen abbilden zu können (z.B. einen Proxmox Cluster für HA).

Bislang war es notwendig, wenn man einzelne Server in einem privaten Netzwerk verbinden zu wollen, dies mit anderen Mitteln (z.B. Tinc) zu tun. Die Einrichtung war bei mehreren beteiligten System sehr komplex, da Tinc ein Mesh basiertes VPN ist. Zudem wurde der Traffic über das öffentliche Netzwerkinterface geroutet, welches zum einen sehr langsam war und zum anderen in das normale Trafficlimit eingangen ist.

Das neue vSwitch Feature kann als Hetzner Kunde kostenlos verwendet werden. Soll auch externer Traffic über den vSwitch betrieben werden – hierzu später mehr – greift ein Traffic-Limit für ausgehende Daten von 1TB/Monat. Danach fallen die üblichen Traffickosten an – aktuell 1,19 € für jedes zusätzliche ausgehende TB.

Vorwort

Die Einrichtung erfolgt über den Hetzner Robot. Unter der Rubrik Server existiert nun ein weiterer Eintrag vSwitches.

Ich möchte nun anhand eines Beispieles beschreiben, wie zwei Server, welche in zwei unterschiedlichen DCs betrieben werden, über einen vSwitch in einem gemeinsammem privaten Netzwerk verbunden werden können.

Die folgende Beschreibung ist aus dem offiziellen Eintrag im Hetzner Wiki abgeleitet. Das zu Grunde liegene OS ist in beiden Fällen die default Debian Installation von Hetzner. Diese wird Nachfolgend dann noch auf Proxmox aktualisiert. Dies wird aber in einem nächsten Post beschrieben werden.

Gegeben sind zwei Server host2 und host3 in zwei unterschiedlichen Rechenzentren (FSN1-DC5 und FSN1-DC10). Beide Server besitzen schon eine externe IP, über welche Sie aus dem Internet erreichbar sind (144.xyz.xyz.149, host2 und 46.xyz.xyz.134, host3)

Wir möchten nun erreichen, dass sich beide Server über einen interne IP im Netzwerk von vSwitch erreichen können (10.10.10.2, host2 und 10.10.10.3, host3).

Zudem lassen sich an einen vSwitch auch IP-Blöcke für externe IPs binden, welche dann frei an alle Server im vSwitch Netzwerk verteilen lassen (142.xyz.xyz.162, host2 und 142.xyz.xyz.163, host3). Das folgende Bild veranschaulicht den Aufbau:

Setup

Als erstes legen wir einen vSwitch an:

Die VLAN-ID habe ich auf 4000 gelassen. Man kann nun einzelne Server anhand des Hostnamens oder der Server ID suchen und hinzufügen. Wie das UI zeigt, lassen sich maximal 100 Server in maximal 100 vSwitches zusammenfassen.

Setup der lokalen IPs

Die Netzwerkonfiguration muss auf allen Systemen erfolgen, die Teil des vSwitch Netzwerk sein sollen. Wir fangen mit der Konfiguration der lokalen IPs an.

Beginnen wir als mit unserem ersten System: host2. Das initial Netzwerk sieh folgendermaßen aus:

root@host2 ~ # ip addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether d4:11:22:33:44:ff
    inet 144.xyz.xyz.149/27 brd 144.xyz.xyz.159 scope global enp2s0
       valid_lft forever preferred_lft forever
    inet6 2a01::…:2/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::…2b0c/64 scope link
       valid_lft forever preferred_lft forever

Wichtig ist der Name des Netzwerk Devices (enp2s0). Hiervon wird unser neues vSwitch Device abgeleitet. Wir erstellen nun unser vSwitch Device (die MTU wir auf 1400 gesenkt, die VLAN-ID ist 4000). Die lokale IP wird auf 10.10.10.2 gesetzt:

root@host2 ~ # ip link add link enp2s0 name enp2s0.4000 type vlan id 4000
root@host2 ~ # ip link set enp2s0.4000 mtu 1400
root@host2 ~ # ip link set dev enp2s0.4000 up
…
root@host2 ~ # ip addr add 10.10.10.2/24 brd 10.10.10.255 dev enp2s0.4000

Die neue Konfiguration sieht nun wie folgt aus:

root@host2 ~ # ip addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether d4:11:22:33:44:ff
    inet 144.xyz.xyz.149/27 brd 144.xyz.xyz.159 scope global enp2s0
       valid_lft forever preferred_lft forever
    inet6 2a01::…:2/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::…2b0c/64 scope link
       valid_lft forever preferred_lft forever
3: enp2s0.4000@enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP group default qlen 1000
    link/ether d4:11:22:33:44:0c brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.2/24 brd 10.10.10.255 scope global enp2s0.4000
       valid_lft forever preferred_lft forever
    inet6 fe80::…:2b0c/64 scope link
       valid_lft forever preferred_lft forever

Gleiches erfolgt nun für Host3:

root@host3 ~ # ip addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 10:11:22:33:44:2b brd ff:ff:ff:ff:ff:ff
    inet 46.4.80.134/27 brd 46.4.80.159 scope global enp3s0
       valid_lft forever preferred_lft forever
    inet6 2a01::…:2/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::…:e32b/64 scope link
       valid_lft forever preferred_lft forever

Wir erstellen nun auch hier das vSwitch Device. Man beachte das andere Netzwerk Device enp3s0.

root@host3 ~ # ip link add link enp3s0 name enp3s0.4000 type vlan id 4000
root@host3 ~ # ip link set enp3s0.4000 mtu 1400
root@host3 ~ # ip link set dev enp3s0.4000 up
…
root@host3 ~ # ip addr add 10.10.10.3/24 brd 10.10.10.255 dev enp3s0.4000

Es sollte nun möglich sein, von host2 die IP 10.10.10.3 zu erreichen und umgekehrt:

root@host2 ~ # ping 10.10.10.3
PING 10.10.10.3 (10.10.10.3) 56(84) bytes of data.
64 bytes from 10.10.10.3: icmp_seq=1 ttl=64 time=0.329 ms
…
root@host3 ~ # ping 10.10.10.2
PING 10.10.10.2 (10.10.10.2) 56(84) bytes of data.
64 bytes from 10.10.10.2: icmp_seq=1 ttl=64 time=0.307 ms

public IPs

Wie bereits erwähnt, ist es möglich, an einen vSwitch mehrere public IP Adressen zu binden. Dies passiert ebenfalls per Robot:

Am aktuellen vSwitch hängt ein /29 subnet. Jeder (aber nur einer!) Server, der im vSwitch Netzwerk hängt, kann nun eine dieser IPs verwenden.

Wir begeben uns wieder ins Terminal auf host2 und fügen eine neue Route hinzu:

root@host2 ~ # echo "1 vswitch" >> /etc/iproute2/rt_tables
root@host2 ~ # ip addr add 142.xyz.xyz.162/29 dev enp2s0.4000
root@host2 ~ # ip rule add from 142.xyz.xyz.162 lookup vswitch
root@host2 ~ # ip rule add to 142.xyz.xyz.162 lookup vswitch
root@host2 ~ # ip route add default via 142.xyz.xyz.161 dev enp2s0.4000 table vswitch

In der neuen Netzwerkkonfiguration sollte nun die neue IP auch auftauchen:

root@host2 ~ # ip addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether d4:11:22:33:44:ff
    inet 144.xyz.xyz.149/27 brd 144.xyz.xyz.159 scope global enp2s0
       valid_lft forever preferred_lft forever
    inet6 2a01::…:2/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::…2b0c/64 scope link
       valid_lft forever preferred_lft forever
3: enp2s0.4000@enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP group default qlen 1000
    link/ether d4:11:22:33:44:0c brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.2/24 brd 10.10.10.255 scope global enp2s0.4000
       valid_lft forever preferred_lft forever
    inet6 fe80::…:2b0c/64 scope link
       valid_lft forever preferred_lft forever
    inet 142.xyz.xyz.162/29 scope global enp2s0.4000
       valid_lft forever preferred_lft forever

Auf host3 erfolgt die Konfiguration identisch:

 echo "1 vswitch" >> /etc/iproute2/rt_tables
 ip addr add 142.xyz.xyz.163/29 dev enp3s0.4000
 ip rule add from 142.xyz.xyz.163 lookup vswitch
 ip rule add to 142.xyz.xyz.163 lookup vswitch
 ip route add default via 142.xyz.xyz.161 dev enp3s0.4000 table vswitch

Beide Server sollten nun über beide öffentlichen IPs erreichbar sein (e.g. ein installierter nginx sollte im Browser erreichbar sein).

Benchmark

Es stellt sich die Frage, welche use cases mit so einem SDN umgesetzt werden können. Abschließend also eine einfache Benchmark. Wir wollen ein ubuntu ISO Image jeweils über die unterschiedlichen Verbindungen von einem Server auf den anderen übertragen:

root@host2 ~ # du -sh *
813M    ubuntu-18.04.1-live-server-amd64.iso

Wie wir sehen, ist das Image gut 800Mb groß.

Zuerst übertragen wir das Image über die privaten IPs (10.10.10.2 zu 10.10.10.3).

root@host2 ~ # scp -vr ubuntu-18.04.1-live-server-amd64.iso root@10.10.10.3:/root/ubuntu1.iso
ubuntu-18.04.1-live-server-amd64.iso                            100%  812MB  91.9MB/s   00:08

Der Vollständigkeit halber auch noch mal in Gegenrichtung:

root@host3 ~ # scp -vr ubuntu1.iso root@10.10.10.2:/root/ubuntu1.iso
ubuntu-18.04.1-live-server-amd64.iso                            100%  812MB  91.9MB/s   00:08

Als nächstes verwenden wir die beiden externen IPs, die über den vSwitch erreichbar sind:

root@host2 ~ # scp -vr ubuntu-18.04.1-live-server-amd64.iso root@142.xyz.xyz.163:/root/ubuntu2.iso
ubuntu-18.04.1-live-server-amd64.iso                            100%  812MB  89.7MB/s   00:09

Als nächstes verwenden wir die externen IPs des Host Systems (der DNS Eintrag host3.foo.bar löst auf die externe IP 46.xyz.xyz.134 auf)

root@host2 ~ # scp -vr ubuntu-18.04.1-live-server-amd64.iso root@host3.foo.bar:/root/ubuntu3.iso
ubuntu-18.04.1-live-server-amd64.iso                            100%  812MB  34.4MB/s   00:23

Wir können erkennen, dass die Verbindung über das interne SDN deutlich schneller ist. Zudem wird dieser Traffic weder vom Limit der Server, noch vom Limit des vSwitches abgezogen.

Fazit

Hetzner bietet mit dem neuen vSwitch Feature eine interessante Erweiterung, um auch komplexeres Use Cases abbilden zu können. Vom Aufsetzen eines internen Management Netzwerks, über eine Backup Verbindung bis zu einem automatisiertem Fail-Over Verhalten lassen sich unterschiedliche Konfigurationen erstellen.

Natürlich wird erst die Zeit sagen können, wie stabil und performant diese neue SDN Funktion tatsächlich ist.


Cover Image: https://www.pexels.com/photo/eight-electrical-metric-meters-942316/

Philipp Haußleiter

7 Gedanken zu “Verbinde Server in unterschiedlichen RZs per vSwitch

    1. Hallo Rico,

      bedingt durch das Hetzner VPN Setup ist das sehr komplex geworden.
      Ich habe aber dann angefangen, mich mit Open vSwitch zu befassen.
      Sobald ich Zeit habe, schreibe ich das mal zusammen.

  1. Hallo Philipp,
    vielen Dank für Dein Tutorial. Ich konnte dies gt bei 3/4 Servern einbauen.
    Bei dem 4. habe ich jedoch ein Problem, beim Anlegen des Links z.B.
    ip link add link eth0 name eth0.4000 type vlan id 4000

    erhalte ich den Fehler „RTNETLINK answers: Operation not supported“

    Hier komme ich nu leider nicht weiter, hast Du eine Idee?

    Danke Tom

    1. Hallo Tom,
      ich kann es versuchen :-).
      Kannst Du kurz sagen welche Linux Distribution und welche Kernel Version uname -r Du hast?
      Hast Du vielleicht den Kernel aktualisiert und das System nicht neu gestartet?

  2. Hallo Philip,

    ein Reboot hatte das Problem behoben, Danke für Dein Hilfsangebot.
    Eine Frage, wie baue ich das ganze jetzt statisch ein? Nach Reboots ist die Einstellung ja wieder weg.

    Ich nutzt CentOS8

    LG Tom

  3. Hallo.

    Danke erstmal für das Tutorial. Es funktioniert soweit bei mir mit der Verbindung meiner beiden ubuntu dedicated servern.
    Ich habe nur das Problem, dass nach einem Neustart der Server die vlans weg sind.
    Ich hab es auch wie in den Hetznerdocs beschrieben versucht, doch Netplan meckert rum beim generieren der configs.
    Wie kann ich die vlans nach einem Neustart erhalten?

    Danke im Voraus

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert