Wydawać by się mogło, że zainstalowanie CloudStack to nic trudnego, i tak jest. Trzeba jednak dokładnie zaplanować jak będziemy używać sieci i przestrzeni dyskowej i odpowiednio skonfigurować hosta lub hosty do pełnienia funkcji serwera zarządczego i wirtualizatora. W tym poście omówię dokładnie konfigurację sieci na poziomie serwera, pierwsza jest oparta na mostkach a druga na OpenvSwitch (obydwie wykluczają się wzajemnie). Systemem operacyjnym jest najnowszy CentOS 7 (w wersji minimal install), na czas instalacji i konfiguracji proponuję wyłączyć SELinux i FirewallD (do ustawień zapory jeszcze powrócimy). Na potrzeby tego artykułu założyłem że serwer jest wyposażony w minimum dwie karty sieciowe, nie będziemy używać LACP, użyjemy jednej sieci domyślnej bez tagowania (VLAN1) i kilku sieci tagowanych. W przypadku braku w waszej domowej infrastrukturze sieci tagowanej możecie użyć sieci nie tagowanych do wszystkiego, modyfikując odpowiednio konfigurację.
W przypadku CloudStack całością procesu konfiguracji sieci po stronie KVM i systemu operacyjnego (np. w trakcie uruchamiania VM) zarządza CloudStack Agent instalowany na każdym hoście. Konfiguracja ta wymaga podania nazw dla sieci rozróżnianych na poziomie CloudStack. Sieci te to management, public, guest i opcjonalnie storage. Nazwy sieci muszą odpowiadać nazwie cloudbrN, gdzie N to numer (nie musi być kolejny), standardowy schemat to:
cloudbr0 – public
cloudbr1 – mgmt
cloudbr2 – guest
Wszystkie sieci mogą współdzielić jeden mostek podpięty do interfejsu zsumowanego LACP (bond), panuje tutaj dowolność konfiguracji. Sieci i ich nazwy definiujemy na poziomie Zony w sekcji sieci fizyczne (będzie o tym dalej). Wygląda to tak (KVM traffic label):
Nazwa sieci cloudbrN jest jednocześnie nazwą mostka sieciowego (ethernet bridge), nazwy te muszą być tożsame (CloudStack Agent <-> host) i spójne na przestrzeni całego klastra. W pliku konfiguracyjnym agenta sieci są precyzyjnie opisane. Interfejs sieciowy cloudbrN musi być zawsze podniesiony (UP), jeśli przejdzie w stan zatrzymania (Down), przestanie działać cała (np. public) sieć. Liczba zdefiniowanych sieci na poziomie CloudStack nie przekłada się wprost na liczbę interfejsów cloudbrN na poziomie hosta. Na poziomie hosta tworzone są dynamicznie interfejsy vnet zgodnie z potrzebami. Zdefiniowane na poziomie hosta interfejsy nie muszą mieć przypisanych adresów IP ale mogą, sieć management musi mieć przypisany adres IP (z wiadomych względów). Temat stworzenia mostka sieciowego jest prosty, omówiłem go w tym artykule (wystarczy jeden mostek i jedna sieć lub tyle mostków ile potrzebujemy). Tak wyglądają interfejsy sieciowe na poziomie hosta z wykorzystaniem mostków sieciowych przy uruchomionych VM (cloud0 i virbr0 są tworzone automatycznie) :
Tutaj zajmiemy się siecią opartą na OpenvSwitch (konfiguracja sugerowana i zgodna z nie tagowaną siecią). Niestety nie ma pakietów z OpenvSwitch na CentOS 7, musimy je przygotować sami, na początek instalujemy wymagane pakiety (całość procesu zajmuje 2 minuty):
W tym momencie mamy uruchomiony poprawnie OpenvSwitch, zanim przeprowadzimy jego konfigurację, należy przygotować pliki interfejsów sieciowych i wgrać je do /etc/sysconfig/network-scripts. Dla każdej karty sieciowej tworzymy plik ifcfg-ens160 z zawartością (gdzie ens160 to oczywiście przykład):
NAME=ens160 DEVICE=ens160 ONBOOT=yes USERCTL=no BOOTPROTO=static PEERDNS=no IPV6INIT=no IPV6_AUTOCONF=no DEVICETYPE=ovs TYPE=OVSPort OVS_BRIDGE=br0 MTU=9000 check_link_down() { return 1; }
Jak widać, w moim przypadku mamy MTU ustawione na 9000, jeśli w Waszej sieci nie ma włączonych Jumbo Frame to tę linię wystarczy skasować.
Ja stworzyłem interfejs zsumowany Bond typu Aktywny-Pasywny (Backup) dla dwóch kart sieciowych ens3s0 i ens5s0, plik o nazwie ifcfg-bond0:
DEVICE=bond0
ONBOOT=yes
DEVICETYPE=ovs
TYPE=OVSBond
OVS_BRIDGE=br0
BOOTPROTO=none
BOND_IFACES=”ens3s0 ens5s0″
OVS_OPTIONS=”bond_mode=active-backup lacp=off other_config:bond-detect-mode=miimon other_config:bond-miimon-interval=100″
HOTPLUG=no
Powyższe zostawiam jako przykład, w międzyczasie musiałem przejść z fizycznych serwerów na maszyny wirtualne (zagnieżdżone KVM w ESXi) i aktualizuję sieć pod nie aby całość artykułów była spójna. Wirtualne hosty są podłączone pod port grupę typu Trunk, wyżej wymienione informacje nie ulegają zmianie.
Tworzymy teraz pliki dla interfejsów cloudbrN, każdy na innym VLAN („br0 70”), oczywiście wystarczy usunąć VLAN i MTU aby działało wszystko w sieci nie tagowanej z MTU 1500. Pliki ifcfg-cloudbrN:
DEVICE=cloudbr0
ONBOOT=yes
DEVICETYPE=ovs
TYPE=OVSBridge
IPV6INIT=no
IPV6_AUTOCONF=no
BOOTPROTO=static
HOTPLUG=no
OVS_EXTRA=”br-set-external-id $DEVICE bridge-id $DEVICE”
OVS_OPTIONS=”br0 70″
IPADDR=192.168.70.71
NETMASK=255.255.255.0
DNS1=192.168.0.30
DNS2=192.168.0.200
MTU=9000
GATEWAY=192.168.70.1
DEVICE=cloudbr1
ONBOOT=yes
DEVICETYPE=ovs
TYPE=OVSBridge
IPV6INIT=no
IPV6_AUTOCONF=no
BOOTPROTO=static
HOTPLUG=no
OVS_EXTRA=”br-set-external-id $DEVICE bridge-id $DEVICE”
OVS_OPTIONS=”br0 90″
MTU=9000
DEVICE=cloudbr2
ONBOOT=yes
DEVICETYPE=ovs
TYPE=OVSBridge
IPV6INIT=no
IPV6_AUTOCONF=no
BOOTPROTO=static
HOTPLUG=no
OVS_EXTRA=”br-set-external-id $DEVICE bridge-id $DEVICE”
OVS_OPTIONS=”br0 30″
MTU=9000
Pliki mostków głównych (br), ifcfg-br0:
DEVICE=br0
ONBOOT=yes
HOTPLUG=no
BOOTPROTO=none
DEVICETYPE=ovs
TYPE=OVSBridge
Powyższa konfiguracja dotyczy pojedynczej karty sieciowej w konfiguracji Trunk dla OpenvSwitch, każdorazowy restart hosta powoduje założenie ww interfejsów od nowa w konfiguracji OvS.
Teraz przystępujemy do konfiguracji OpenvSwitch (moja konfiguracja na cztery karty) w konsoli (nie przez ssh):
ovs-vsctl add-br br0
ovs-vsctl add-bond br0 bond0 enp3s0 enp5s0
ovs-vsctl add-br mgmt0 br0 50
ovs-vsctl add-br cloudbr0 br0 0
ovs-vsctl add-br cloudbr1 br0 61
ovs-vsctl add-br br1
ovs-vsctl add-bond br1 bond1 ens2f0 ens2f1
ovs-vsctl add-br mgmt1 br1 60
W ramach wyjaśnień, tworzymy mostek br0 do którego podpinamy bond0, ustawiamy tagi VLAN, tworzymy mostki mgmt0 i cloudbrN. Ważne, że dla cloudbr0 ustawiamy tag 0, czyli natywny (na porcie mamy Trunk i domyślny VLAN 60). Jeśli nie posiadasz sieci z VLAN to taka konfiguracja z cloudbr0 tag 0 zadziała poprawnie dla wszystkich sieci (public, mgmt, guest) dokładnie tak samo jak w przypadku zwykłego mostka sieciowego. Tak jak wspominałem wcześniej, standardowe mostki sieciowe wchodzą w interakcję z OpenvSwitch, dlatego należy je wyłączyć. Tworzymy plik /etc/modprobe.d/blacklist.conf z zawartością: blacklist bridge
Dodatkowo w pliku /etc/sysctl.conf dodajemy dyrektywy:
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
Restartujemy hosta, po restarcie wygląda to tak:
Konstrukcja całości jest bardzo czytelna jak widać (mostek cloud0 jest zakładany przez CloudStack Agent). Ważna informacja, dla danego mostka (br) tylko jeden port może mieć ustawiony tag 0 (brak VLAN). Przy poprawnej konfiguracji możemy się swobodnie komunikować z hostem poprzez interfejs cloud0. W następnej części omówimy dokładnie przestrzeń dyskową (Primary i Secondary Storage) oraz zestawimy klaster MariaDB, skonfigurujemy też KeepaliveD, HAProxy.
EDIT:
Od wersji 4.11 Cloudstack wspiera sieci gościa L2, oznacza to, że VM wstaje bez sieci (jest wpięta bezpośrednio w OpenvSwitch i wszystko pozyskuje z zewnętrznego DHCP) a cała konfiguracja musi zostać dostarczona spoza Cloudstack (brak wirtualnego routera). Jest to dość ciekawa opcja (rzekłbym, że rewolucyjna dla CloudStack), jeśli ktoś chce zachować pełną obsługę sieci po stronie fizycznej (switche, routery) to już może (jak w VMware).