KVM VMs mit Bonding und VLANs und Cisco Switchen auf CentOS 6/7 bridgen

Wer große Rechner mit KVM und vielen VMs hat kommt vielleicht an einen Punkt an dem Ihm das Gigabit Interface nicht mehr reicht. Dann gibt es verschiedene Varianten die Bandbreite zu erhöhen.

Eine einfache Variante ist es auf ein 10 Gigabit Interface zu nutzen. Schnell einfach und schön, wenn man die Möglichkeit hat.

Alternativ kann man auch einzelne Gigabit Interfaces nutzen und die Rechner darauf verteilen. Das ist einfach und benötigt wenig Konfiguration, ist allerdings auch nur wenig flexibel und man muss immer aufpassen auf welchen Interface man einen Rechner anlegt.

Es gibt aber auch eine schicke Lösung für dieses Problem. Das Zusammenfassen von Interfacen. Dabei agieren <N> Interface wie ein einzelnes, erhöhen dabei aber die Gesamtbandbreite und sind untereinander Fehlertolerant. Ein entsprechendes Setup soll hier anhand von Cisco Switchen erläutert werden.

Achtung, Portchannel bei Cisco und Bonding unter Linux meinen bei uns das gleiche, bitte nicht verwirren lassen.

Auf dem Cisco

Zuerst wird einen passenden Portchannel auf dem Cisco angelegt. Dazu loggt man sich ein, enabled sich  (falls nötig) und wechselt in den configure Modus.

conf t

Nun wird das Interface angelegt, dabei wird „Po“ bzw. „Portchannel“ durchnumeriert. Zu beachten ist das der Interface Name wirklich frei ist.Wird versehentlich eine existierender Portchannel verwendet kann dies zu Streß mit dem Netzwerkadmin führen ;-).

interface <freies!!! po device> z.B. po1
description Mein_Schoener_neuer_Portchannel

Natürlich fügt man auch eine sprechende Description ein, spätestens in drei Monaten ist man froh darüber.

Anschließend wird die Encapsulation des Portchannels eingestellt, also das Verfahren mit dem die VLANs übertragen werden. Vielleicht ist das in der Konfiguration schon default, schadet aber nichts. Der Modus wird auf Trunk umgestellt, damit überträgt der Switch alle VLANs an diesem Port. Das ist prinzipiell nicht wirklich sicher, deswegen kann man einem Trunkport Accesslisten geben, dazu sollte man sich auf jeden Fall informieren.

switchport trunk encapsulation dot1q
switchport mode trunk
no ip address
end

Zusätzlich wird dem Port noch gesagt das er keine IP-Adresse hat, das scheint auf diversen Switchen nicht unbedingt nötig zu sein, stand aber in meiner Doku so und schadet nicht. Mit „end“ wird die Konfiguration abgeschlossen.

Damit ist der eigentliche Portchannel konfiguriert. Nun müssen diesem Portchannel noch die entsprechenden Interfaces zugeteilt werden, welche dann zusammengefaßt werden.

Im configure Modus des Switches (oder des Stacks) wählt man dazu das Interface aus welches man konfigurieren will, versieht es mit einer Description (ich würde TRUNK und einen Hinweis auf den Portchannel vorkommen lassen). Dazu wird auch wieder die Encapsulation eingestellt (diese kann einen andere sein, muß aber durchgängig überall gleich sein).

conf t
int <einzelnes bonding interfaces>
desc host.domain.tld-PCH-TRUNK
switchport trunk encapsulation dot1q
switchport mode trunk
no ip address
no shut

Zusätzlich teilt man dem Port noch seinen Modus mit, sagt auch Ihm das er keine IP braucht und setzt den Port auf „no shut“ also auf an.

Nun kommt die Konfiguration des Link Aggregation Control Protocol welches beschreibt wie Switche und Server physische Verbindungen zusammenfassen. Das ganze ist nach IEEE 802.3ad spezifiziert. Dabei gibt man das Protokoll an (es gibt viele, oft proprietäre), für mich hat sich dabei LACP bewährt. Und es wird das Interface dem eigentlichen Portchannel zugewiesen.

channel-protocol lacp
channel-group <int> mode passive #<<--- Portchannel Interface Nummer
end

Da der Linuxtreiber per default im passive Mode arbeitet verwenden wir diesen. Dabei wird von beiden Seiten keine negoation durchgeführt wird.

Damit ist die Ciso Konfiguration abgeschlossen. Bitte das „write“ nicht vergessen, sonst wird es beim nächsten reboot des switches böse ;-).

Auf Linux

Auf den Linux Rechnern reicht für das Interface eine minimale Konfiguration. In diesem Beispiel verwenden wir Interface 1 bis 3 (eth1 bis eth3) für einen 3 Gigabit Portchannel und eth0 als Admin Netz für den Host. Theoretisch könnte man auch den Bond selbst für das Admin Netz verwenden, allerdings ist ein reines eth einfach stabiler und wird auch bei Auslastung des Bonds nicht eingeschränkt.

Physikalische INterfaces

Konfiguration aus /etc/sysconfig/network-scripts/ifcfg-eth1

IPV6INIT=no
BOOTPROTO=none
DEVICE=eth1
ONBOOT=yes
HWADDR=xx:xx:xx:xx:xx:xx
UUID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx
TYPE=Ethernet
DEFROUTE=no
PEERDNS=no
PEERROUTES=no
IPV4_FAILURE_FATAL=no
IPV6_AUTOCONF=no
IPV6_DEFROUTE=no
IPV6_PEERDNS=no
IPV6_PEERROUTES=no
IPV6_FAILURE_FATAL=no
NAME="System eth1"
MASTER=bond0
SLAVE=yes
USERCTL=no

Das meiste sind Defaultwerte, wichtig sind neben den Hardware spezifischen Werten wie Userid und Macadresse noch die Master Einstellung auf das erste Bonding Interface (bond0) und die Slave Einstellung um das Device als Slave dem Bond0 zu zu ordnen. Unter CentOS 6 können diverse Einstellungen entfallen und einfach nur Master und Slave ergänzt werden.

Bonding INterface

Als erstes muss das Linux Kernel Modul (der Treiber) für das Bonding geladen werden. Dazu passt man /etc/modprobe.d/bonding.conf an und füllt sie entsprechend mit:

alias bond0 bonding

Nun könnte man booten oder das Modul einfach mit modprobe laden.

modprobe bonding mode=4 miimon=100

Mit der Datei /etc/sysconfig/network-scripts/ifcfg-bond0 konfigurieren wir den Bond.

DEVICE=bond0
ONBOOT=yes
BOOTPROTO=none
USERCTL=no
BONDING_OPTS="mode=4 miimon=100"

Die Konfiguration ist auch recht übersichtlich, da der Bond nur virtuell existiert haben wir keine Hardware spezifischen Einträge. Das Device heißt bond0 (es kann heißen wie es will, ich würde aber etwas sprechendes nehmen). Beim Booten soll es gestartet werden, wir benötigen kein Boot Protokoll wie DHCP oder STATIC weil wir keine IP Konfiguration auf dem Interface haben. Der Mode 4 bei den Bonding Options besagt das ein IEEE 802.3 ad Tunnel verwendet werden soll und miimon gibt an wie oft (in Millisekunden) der Link der einzelnen Bond Interfaces überwacht werden soll. Weitere Parameter finden sich in der CentOS Doku.

Soweit so gut, bisher können wir noch nicht viel mit dem Interface anfangen, es fällt maximal das default VLAN raus. In der Regel möchte man aber gezielt (verschiedene VLANs) für seine VMs zur Verfügung haben. Dazu müssen nun die einzelnen VLANs konfiguriert werden und im Anschluß Bridges für KVM.

VLAN INterfaces

Um VLAN Interfaces anzulegen reicht es aus eine entsprechende Konfiguration zu erstellen und VLAN=yes zu sagen.

DEVICE=bond0.20
VLAN=yes
ONBOOT=yes
TYPE=Ethernet

Mit der obigen Konfiguration wird das VLAN 20 auf dem Rechner zur Verfügung gestellt. Würde man eine IP-Adresse auf dem Interface Konfigurieren hätte man nun einen Multi-Homed-Host mit einem Interface in zwei Netzen. Wir lassen jedoch alle weitere Konfiguration weg, da wir lediglich unsere VMs im entsprechenden Netz betreiben wollen.

Bridge INterfaces

Um die Netzwerke an KVM zu übergeben benötigt man Bridges (Brücken). Diese vermitteln zwischen unseren (virtuellen) Hardware Interfacen und dem Hypervisor.

Mit dem Befehl brctl kann man die Bridges verwalten. Die erste Bridge wird wie folgt angelegt:

brctl addbr br0

Damit ist das eigentliche Bridgedevice angelegt, uns fehlt aber noch die eigentliche Zuordnung zum Physikalischen Interface. Dazu benötigen wir eine weitere Anweisung:

brctl addif br0 bond0.20

Nun ist festgelegt welches Interface die Brigde versorgt. Man könnte also auch sagen „VLAN 20 liegt auf br0“. Damit das ganze nach dem Booten auch noch funktioniert und über die ifup Scripte gestartet werden kann muss dazu natürlich auch noch Konfiguration her.

In /etc/sysconfig/network-scripts/ifcfg-bond0.20 ergänzen wir dazu die Bridgeinformation:

DEVICE=bond0.20
VLAN=yes
ONBOOT=yes
TYPE=Ethernet
BRIDGE=br0

Und legen in /etc/sysconfig/network-scripts/ifcfg-br0

DEVICE=br0
TYPE=Bridge
BOOTPROTO=none
ONBOOT=yes
DELAY=0

die Konfiguration der Bridge an. Nun überprüfen wir mit brctl show unsere Konfiguration:

bridge name bridge id STP enabled interfaces
br0 8000.xxxxxxxxxxxx no bond0.20

Ein ifup br0 macht unsere Bridge für das System verfügbar. Mit ip a sehen wir unsere Bridge.

5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
 link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
 inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link 
 valid_lft forever preferred_lft forever

Nun sollte man einmal booten und schauen ob auch alle Interface up kommen wie man es erwartet.

Im Virtmanager

kvm_nic_selectionAb sofort sollten jetzt die Brigdes im der NIC selection im Virt-Manager auftauchen. Hier ein Ausschnitt auf einem Host mit mehreren VLANs. Durch die Auswahl einer Bridge kann man den Host jetzt in das entsprechende Netz packen.

Ich hoffe das hilf dem einem oder anderen.

Schreibe einen Kommentar

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