Wprowadzenie do sieciowej części infrastruktury chmurowej
Chmura obliczeniowa wnika coraz głębiej w nasze życie i chyba nie ma osoby, która choć raz nie korzystała z usług chmurowych. Jednak czym dokładnie jest chmura i jak działa, niewiele osób wie, nawet na poziomie pomysłu. 5G staje się już rzeczywistością, a infrastruktura telekomunikacyjna zaczyna odchodzić od rozwiązań filarowych do rozwiązań chmurowych, tak jak miało to miejsce w przypadku przejścia z rozwiązań całkowicie sprzętowych do zwirtualizowanych „filarów”.
Dziś porozmawiamy o wewnętrznym świecie infrastruktury chmurowej, w szczególności przyjrzymy się podstawom części sieciowej.
Co to jest chmura? Ta sama wirtualizacja - widok profilu?
Więcej niż logiczne pytanie. Nie – to nie jest wirtualizacja, choć bez niej nie dałoby się tego zrobić. Przyjrzyjmy się dwóm definicjom:
Chmura obliczeniowa (zwana dalej Chmurą) to model zapewnienia przyjaznego użytkownikowi dostępu do rozproszonych zasobów obliczeniowych, które należy wdrażać i uruchamiać na żądanie, przy możliwie najniższych opóźnieniach i minimalnych kosztach dla dostawcy usług.
иртуализация - jest to możliwość podzielenia jednej jednostki fizycznej (np. serwera) na kilka wirtualnych, zwiększając w ten sposób wykorzystanie zasobów (np. miałeś 3 serwery obciążone na 25-30 procent, po wirtualizacji dostajesz załadowany 1 serwer na poziomie 80-90 proc.). Naturalnie wirtualizacja pochłania część zasobów - trzeba nakarmić hypervisora, jednak jak pokazała praktyka, gra jest warta świeczki. Idealnym przykładem wirtualizacji jest VMWare, który doskonale przygotowuje maszyny wirtualne, czy np. KVM, który ja wolę, ale to kwestia gustu.
Korzystamy z wirtualizacji nie zdając sobie z tego sprawy, a nawet routery żelazne już korzystają z wirtualizacji - na przykład w najnowszej wersji JunOS system operacyjny jest instalowany jako maszyna wirtualna na szczycie dystrybucji Linuksa czasu rzeczywistego (Wind River 9). Ale wirtualizacja to nie chmura, ale chmura nie może istnieć bez wirtualizacji.
Wirtualizacja jest jednym z elementów, na których zbudowana jest chmura.
Utworzenie chmury poprzez proste zebranie kilku hypervisorów w jedną domenę L2, dodanie kilku podręczników yaml do automatycznego rejestrowania sieci vlan przez jakiś ansible i włączenie do tego czegoś w rodzaju systemu orkiestracji w celu automatycznego tworzenia maszyn wirtualnych nie będzie działać. Będzie dokładniej, ale powstały Frankenstein nie jest chmurą, której potrzebujemy, choć dla innych może to być największe marzenie. Co więcej, jeśli weźmiesz ten sam Openstack, w zasadzie będzie to nadal Frankenstein, ale cóż, nie mówmy o tym na razie.
Rozumiem jednak, że z przedstawionej powyżej definicji nie do końca wiadomo, co tak naprawdę można nazwać chmurą.
Dlatego dokument NIST (National Institute of Standards and Technology) podaje 5 głównych cech, które powinna posiadać infrastruktura chmurowa:
Świadczenie usług na żądanie. Użytkownik musi mieć swobodny dostęp do przydzielonych mu zasobów komputera (takich jak sieci, dyski wirtualne, pamięć, rdzenie procesorów itp.), przy czym zasoby te muszą być udostępniane automatycznie – czyli bez ingerencji usługodawcy.
Szeroka dostępność usług. Dostęp do zasobów musi być zapewniony poprzez standardowe mechanizmy, umożliwiające korzystanie zarówno ze standardowych komputerów PC, jak i cienkich klientów oraz urządzeń mobilnych.
Łączenie zasobów w pule. Pule zasobów muszą być w stanie zapewnić zasoby wielu klientom jednocześnie, zapewniając, że klienci są odizolowani i wolni od wzajemnych wpływów i rywalizacji o zasoby. Do pul zaliczane są także sieci, co wskazuje na możliwość stosowania adresowania nakładającego się. Pule muszą mieć możliwość skalowania na żądanie. Zastosowanie pul umożliwia zapewnienie niezbędnego poziomu odporności na awarie zasobów oraz abstrakcję zasobów fizycznych i wirtualnych – odbiorca usługi otrzymuje po prostu zestaw zasobów, o który prosił (gdzie te zasoby są fizycznie zlokalizowane, na ilu serwery i przełączniki - dla klienta nie ma to znaczenia). Musimy jednak wziąć pod uwagę fakt, że dostawca musi zapewnić przejrzystą rezerwację tych zasobów.
Szybka adaptacja do różnych warunków. Usługi muszą być elastyczne – szybkie udostępnianie zasobów, ich redystrybucja, dodawanie lub zmniejszanie zasobów na życzenie klienta, a po stronie klienta powinno być poczucie, że zasoby chmury są nieograniczone. Na przykład, dla ułatwienia zrozumienia, nie widzisz ostrzeżenia, że część miejsca na dysku w Apple iCloud zniknęła, ponieważ dysk twardy na serwerze uległ awarii, a dyski się psują. Poza tym z Twojej strony możliwości tej usługi są niemal nieograniczone - potrzebujesz 2 TB - nie ma problemu, zapłaciłeś i otrzymałeś. Podobny przykład można podać w przypadku Google.Drive lub Yandex.Disk.
Możliwość pomiaru wykonanej usługi. Systemy chmurowe muszą automatycznie kontrolować i optymalizować zużywane zasoby, a mechanizmy te muszą być przejrzyste zarówno dla użytkownika, jak i usługodawcy. Oznacza to, że zawsze możesz sprawdzić, ile zasobów zużywasz Ty i Twoi klienci.
Warto wziąć pod uwagę fakt, że wymagania te są w większości wymaganiami dla chmury publicznej, więc dla chmury prywatnej (czyli chmury uruchamianej na potrzeby wewnętrzne firmy) wymagania te można nieznacznie zmodyfikować. Trzeba je jednak jeszcze wykonać, bo inaczej nie skorzystamy ze wszystkich korzyści, jakie niesie ze sobą chmura obliczeniowa.
Dlaczego potrzebujemy chmury?
Jednak każda nowa lub istniejąca technologia, każdy nowy protokół jest po coś tworzony (no cóż, oczywiście z wyjątkiem RIP-ng). Nikt nie potrzebuje protokołu dla samego protokołu (no cóż, oczywiście z wyjątkiem RIP-ng). Logiczne jest, że Chmura jest tworzona w celu świadczenia jakiejś usługi użytkownikowi/klientowi. Wszyscy znamy co najmniej kilka usług chmurowych, na przykład Dropbox lub Google.Docs i myślę, że większość osób z nich korzysta z powodzeniem – na przykład ten artykuł został napisany przy użyciu usługi chmurowej Google.Docs. Ale usługi chmurowe, które znamy, to tylko część możliwości chmury – a dokładniej, są to jedynie usługi typu SaaS. Usługę chmurową możemy świadczyć na trzy sposoby: w formie SaaS, PaaS lub IaaS. To, jakiej usługi potrzebujesz, zależy od Twoich pragnień i możliwości.
Przyjrzyjmy się każdemu w kolejności:
Oprogramowanie jako usługa (SaaS) to model świadczenia kompleksowej usługi dla klienta, na przykład usługi pocztowej typu Yandex.Mail czy Gmail. W tym modelu świadczenia usług Ty, jako klient, właściwie nie robisz nic poza korzystaniem z usług - to znaczy, że nie musisz myśleć o skonfigurowaniu usługi, jej odporności na awarie czy redundancji. Najważniejsze, żeby nie zdradzić swojego hasła, resztę zrobi za Ciebie dostawca tej usługi. Z punktu widzenia usługodawcy to on jest w pełni odpowiedzialny za całą usługę – od sprzętu serwerowego i systemów operacyjnych hosta, po ustawienia baz danych i oprogramowania.
Platforma jako usługa (PaaS) — korzystając z tego modelu, usługodawca udostępnia klientowi przedmiot do wykonania usługi, weźmy na przykład serwer WWW. Usługodawca udostępnił klientowi serwer wirtualny (właściwie zestaw zasobów, takich jak RAM/CPU/Magazyn/Sieć itp.), a nawet zainstalował na tym serwerze system operacyjny i niezbędne oprogramowanie, jednakże konfiguracja wszystkie te czynności wykonuje sam klient, a za wykonanie usługi odpowiada klient. Usługodawca, podobnie jak w poprzednim przypadku, odpowiada za wydajność sprzętu fizycznego, hypervisorów, samej maszyny wirtualnej, jej dostępności w sieci itp., jednak sama usługa nie leży już w jego obszarze odpowiedzialności.
Infrastruktura jako usługa (IaaS) - to podejście jest już ciekawsze, tak naprawdę usługodawca udostępnia klientowi kompletną zwirtualizowaną infrastrukturę - czyli jakiś zestaw (pulę) zasobów, jak np. rdzenie procesorów, RAM, sieci itp. Cała reszta zależy od klient – co chce zrobić z tymi zasobami w ramach przydzielonej mu puli (kontyngentu) – dla dostawcy nie jest to szczególnie istotne. Niezależnie od tego, czy klient chce stworzyć własny vEPC, czy nawet stworzyć mini operatora i świadczyć usługi komunikacyjne – bez wątpienia – zrób to. W takim scenariuszu usługodawca odpowiada za udostępnienie zasobów, ich odporność na awarie i dostępność, a także system operacyjny, który pozwala na łączenie tych zasobów i udostępnienie ich klientowi z możliwością zwiększania lub zmniejszania zasobów w dowolnym momencie na życzenie klienta. Klient samodzielnie konfiguruje wszystkie maszyny wirtualne i inne świecidełka poprzez portal samoobsługowy i konsolę, łącznie z konfiguracją sieci (z wyjątkiem sieci zewnętrznych).
Co to jest OpenStack?
We wszystkich trzech opcjach usługodawca potrzebuje systemu operacyjnego, który umożliwi stworzenie infrastruktury chmurowej. Tak naprawdę w przypadku SaaS za cały stos technologii odpowiada więcej niż jeden dział – istnieje dział odpowiedzialny za infrastrukturę – czyli dostarcza IaaS innemu działowi, ten dział dostarcza SaaS klientowi. OpenStack to jeden z chmurowych systemów operacyjnych, który pozwala zebrać kilka przełączników, serwerów i systemów pamięci masowej w jedną pulę zasobów, podzielić tę wspólną pulę na podpule (dzierżawców) i udostępnić te zasoby klientom za pośrednictwem sieci.
OpenStack to chmurowy system operacyjny, który umożliwia kontrolę dużych pul zasobów obliczeniowych, przechowywania danych i zasobów sieciowych, udostępnianych i zarządzanych poprzez API z wykorzystaniem standardowych mechanizmów uwierzytelniania.
Innymi słowy jest to zestaw projektów darmowego oprogramowania, który ma na celu tworzenie usług chmurowych (zarówno publicznych, jak i prywatnych) – czyli zestawu narzędzi, które pozwalają łączyć serwer i sprzęt przełączający w jedną pulę zasobów, zarządzać tych zasobów, zapewniając niezbędny poziom odporności na awarie.
W chwili pisania tego materiału struktura OpenStack wygląda następująco:
Każdy z komponentów wchodzących w skład OpenStack pełni określoną funkcję. Ta rozproszona architektura pozwala na włączenie do rozwiązania zestawu komponentów funkcjonalnych, których potrzebujesz. Jednakże niektóre komponenty są komponentami głównymi i ich usunięcie doprowadzi do całkowitej lub częściowej niesprawności rozwiązania jako całości. Składniki te są zwykle klasyfikowane jako:
Panel Użytkownika — Internetowy interfejs graficzny do zarządzania usługami OpenStack
Zwornik to scentralizowana usługa tożsamości, która zapewnia funkcje uwierzytelniania i autoryzacji dla innych usług, a także zarządza danymi uwierzytelniającymi użytkowników i ich rolami.
Neutron - usługa sieciowa zapewniająca łączność pomiędzy interfejsami różnych usług OpenStack (w tym łączność pomiędzy maszynami wirtualnymi i ich dostęp do świata zewnętrznego)
Żużel — zapewnia dostęp do pamięci blokowej dla maszyn wirtualnych
Nova — zarządzanie cyklem życia maszyn wirtualnych
Spojrzenie — repozytorium obrazów i migawek maszyn wirtualnych
Szybki — zapewnia dostęp do obiektu przechowywania
Ceilometr — usługa zapewniająca możliwość gromadzenia danych telemetrycznych oraz pomiaru dostępnych i zużytych zasobów
Ciepło — orkiestracja oparta na szablonach do automatycznego tworzenia i udostępniania zasobów
Można wyświetlić pełną listę wszystkich projektów i ich przeznaczenia tutaj.
Każdy komponent OpenStack to usługa, która wykonuje określoną funkcję i zapewnia interfejs API do zarządzania tą funkcją i interakcji z innymi usługami chmurowego systemu operacyjnego w celu stworzenia ujednoliconej infrastruktury. Na przykład Nova zapewnia zarządzanie zasobami obliczeniowymi i interfejs API umożliwiający dostęp do konfiguracji tych zasobów, Glance zapewnia zarządzanie obrazami i interfejs API do zarządzania nimi, Cinder zapewnia pamięć blokową i interfejs API do zarządzania nim itp. Wszystkie funkcje są ze sobą ściśle powiązane.
Jeśli jednak na to spojrzeć, wszystkie usługi działające w OpenStack są ostatecznie pewnego rodzaju maszyną wirtualną (lub kontenerem) podłączoną do sieci. Powstaje pytanie – po co nam tak wiele elementów?
Przeanalizujmy algorytm tworzenia maszyny wirtualnej i podłączania jej do sieci oraz pamięci trwałej w Openstack.
Kiedy tworzysz żądanie utworzenia maszyny, niezależnie od tego, czy jest to żądanie za pośrednictwem Horizon (pulpit nawigacyjny), czy żądanie za pośrednictwem interfejsu CLI, pierwszą rzeczą, która ma miejsce, jest autoryzacja Twojego żądania w Keystone — czy możesz utworzyć maszynę, czy ma ona prawo do korzystania z tej sieci, czy Twój limit projektu itp.
Keystone uwierzytelnia Twoje żądanie i generuje token uwierzytelniający w komunikacie odpowiedzi, który będzie dalej używany. Po otrzymaniu odpowiedzi od Keystone żądanie zostaje wysłane do Nova (nova api).
Nova-api sprawdza ważność Twojego żądania, kontaktując się z Keystone przy użyciu wcześniej wygenerowanego tokena autoryzacji
Keystone przeprowadza uwierzytelnianie i dostarcza informacji o uprawnieniach i ograniczeniach w oparciu o ten token autoryzacji.
Nova-api tworzy wpis dla nowej maszyny wirtualnej w bazie danych nova i przekazuje żądanie utworzenia maszyny do programu nova-scheduler.
Nova-scheduler wybiera hosta (węzeł komputerowy), na którym zostanie wdrożona maszyna wirtualna, na podstawie określonych parametrów, wag i stref. Rekord tego i identyfikator maszyny wirtualnej są zapisywane w bazie danych nova.
Następnie nova-scheduler kontaktuje się z nova-compute z prośbą o wdrożenie instancji. Nova-compute kontaktuje się z nova-conductor w celu uzyskania informacji o parametrach maszyny (nova-conductor to element nova, który działa jako serwer proxy pomiędzy nova-database a nova-compute, ograniczając liczbę żądań do nova-database, aby uniknąć problemów z bazą danych redukcja obciążenia konsystencji).
Nova-conductor otrzymuje żądane informacje z bazy danych nova i przekazuje je do nova-compute.
Następnie nova-compute wywołuje rzut oka w celu uzyskania identyfikatora obrazu. Glace sprawdza poprawność żądania w Keystone i zwraca żądane informacje.
Nova-compute kontaktuje się z neutronem w celu uzyskania informacji o parametrach sieci. Podobnie jak spojrzenie, neutron sprawdza poprawność żądania w Keystone, po czym tworzy wpis w bazie danych (identyfikator portu itp.), tworzy żądanie utworzenia portu i zwraca żądane informacje do nova-compute.
Nova-compute kontaktuje się z Cinder z prośbą o przydzielenie woluminu maszynie wirtualnej. Podobnie jak w przypadku „spojrzenia”, cydr sprawdza żądanie w Keystone, tworzy żądanie utworzenia wolumenu i zwraca żądane informacje.
Nova-compute kontaktuje się z libvirt z prośbą o wdrożenie maszyny wirtualnej o określonych parametrach.
Tak naprawdę pozornie prosta operacja stworzenia prostej maszyny wirtualnej zamienia się w taki wir wywołań API pomiędzy elementami platformy chmurowej. Co więcej, jak widać, nawet wcześniej wyznaczone usługi również składają się z mniejszych elementów, pomiędzy którymi zachodzi interakcja. Stworzenie maszyny to tylko niewielka część tego, co umożliwia platforma chmurowa - istnieje usługa odpowiedzialna za równoważenie ruchu, usługa odpowiedzialna za przechowywanie bloków, usługa odpowiedzialna za DNS, usługa odpowiedzialna za dostarczanie serwerów typu bare metal itp. Chmura pozwala traktować maszyny wirtualne jak stado owiec (w przeciwieństwie do wirtualizacji). Jeśli coś stanie się z Twoją maszyną w środowisku wirtualnym - przywracasz ją z kopii zapasowych itp., ale aplikacje chmurowe są zbudowane w taki sposób, że maszyna wirtualna nie odgrywa tak istotnej roli - maszyna wirtualna „umarła” - nie ma problemu - nowy jest po prostu tworzony, pojazd jest oparty na szablonie i jak to mówią, oddział nie zauważył utraty myśliwca. Naturalnie zapewnia to obecność mechanizmów orkiestracji - korzystając z szablonów Heat, można łatwo wdrożyć złożoną funkcję składającą się z kilkudziesięciu sieci i maszyn wirtualnych.
Zawsze warto mieć na uwadze, że nie ma infrastruktury chmurowej bez sieci – każdy element w taki czy inny sposób współdziała z innymi elementami za pośrednictwem sieci. Ponadto chmura ma całkowicie niestatyczną sieć. Naturalnie sieć podkładowa jest jeszcze bardziej lub mniej statyczna – nowe węzły i przełączniki nie są dodawane codziennie, ale element nakładkowy może i nieuchronnie będzie ulegał ciągłym zmianom – nowe sieci będą dodawane lub usuwane, będą pojawiać się nowe maszyny wirtualne, a stare będą umierać. A jak pamiętacie z definicji chmury podanej na samym początku artykułu, zasoby powinny być przydzielane użytkownikowi automatycznie i przy jak najmniejszej (lub jeszcze lepiej bez) interwencji ze strony dostawcy usługi. Oznacza to, że rodzaj udostępniania zasobów sieciowych, który obecnie istnieje w formie frontonu w postaci konta osobistego dostępnego przez http/https i dyżurnego inżyniera sieci Wasilija jako backend, nie jest chmurą, nawet jeśli Wasilij ma osiem rąk.
Neutron, jako usługa sieciowa, zapewnia API do zarządzania częścią sieciową infrastruktury chmurowej. Usługa zasila i zarządza częścią sieciową Openstack, udostępniając warstwę abstrakcji o nazwie Network-as-a-Service (NaaS). Oznacza to, że sieć jest tą samą wirtualną jednostką mierzalną, co na przykład wirtualne rdzenie procesorów czy ilość pamięci RAM.
Zanim jednak przejdziemy do architektury części sieciowej OpenStack, zastanówmy się, jak ta sieć działa w OpenStack i dlaczego sieć jest ważną i integralną częścią chmury.
Mamy więc dwie klienckie maszyny wirtualne RED i dwie ZIELONE maszyny wirtualne klienta. Załóżmy, że maszyny te znajdują się na dwóch hypervisorach w następujący sposób:
W tej chwili jest to tylko wirtualizacja 4 serwerów i nic więcej, ponieważ do tej pory jedyne, co zrobiliśmy, to wirtualizacja 4 serwerów, umieszczając je na dwóch serwerach fizycznych. I jak dotąd nie są nawet podłączeni do sieci.
Aby stworzyć chmurę, musimy dodać kilka komponentów. Najpierw wirtualizujemy część sieciową - musimy połączyć te 4 maszyny parami, a klienci chcą połączenia L2. Możesz użyć przełącznika i skonfigurować łącze w jego kierunku i rozwiązać wszystko za pomocą mostu linuksowego lub, dla bardziej zaawansowanych użytkowników, openvswitch (powrócimy do tego później). Ale sieci może być wiele, a ciągłe przepychanie L2 przez przełącznik nie jest najlepszym pomysłem - są różne działy, biuro obsługi, miesiące oczekiwania na zakończenie wniosku, tygodnie rozwiązywania problemów - we współczesnym świecie to podejście już nie działa. Im szybciej firma to zrozumie, tym łatwiej będzie jej działać dalej. Dlatego pomiędzy hypervisorami wybierzemy sieć L3, przez którą będą się komunikować nasze maszyny wirtualne, a na tej sieci L3 zbudujemy wirtualne sieci nakładkowe L2, w których będzie prowadzony ruch naszych maszyn wirtualnych. Jako enkapsulację możesz użyć GRE, Geneve lub VxLAN. Skupmy się na razie na tym drugim, choć nie jest to szczególnie istotne.
Musimy gdzieś zlokalizować VTEP (mam nadzieję, że wszyscy znają terminologię VxLAN). Ponieważ mamy sieć L3 wychodzącą prosto z serwerów, nic nie stoi na przeszkodzie, abyśmy umieścili VTEP na samych serwerach, a OVS (OpenvSwitch) radzi sobie z tym doskonale. W rezultacie otrzymaliśmy taki projekt:
Ponieważ ruch pomiędzy maszynami wirtualnymi musi być podzielony, porty do maszyn wirtualnych będą miały różne numery VLAN. Numer znacznika odgrywa rolę tylko w obrębie jednego wirtualnego przełącznika, ponieważ po enkapsulacji w VxLAN możemy go łatwo usunąć, ponieważ będziemy mieli VNI.
Teraz możemy bez problemu tworzyć dla nich nasze maszyny i sieci wirtualne.
Co jednak w sytuacji, gdy klient ma inną maszynę, ale znajduje się w innej sieci? Potrzebujemy rootowania między sieciami. Przyjrzymy się prostej opcji, gdy używany jest routing scentralizowany - to znaczy ruch jest kierowany przez specjalne dedykowane węzły sieci (cóż, z reguły są one połączone z węzłami kontrolnymi, więc będziemy mieli to samo).
Wydaje się, że to nic skomplikowanego – tworzymy interfejs mostkowy na węźle sterującym, kierujemy do niego ruch i stamtąd kierujemy go tam, gdzie jest to potrzebne. Problem polega jednak na tym, że klient RED chce korzystać z sieci 10.0.0.0/24, a klient ZIELONY chce korzystać z sieci 10.0.0.0/24. Oznacza to, że zaczynamy przecinać przestrzenie adresowe. Ponadto klienci nie chcą, aby inni klienci mogli kierować się do ich sieci wewnętrznych, co ma sens. Aby oddzielić sieci i ruch danych klientów, dla każdego z nich przydzielimy osobną przestrzeń nazw. Przestrzeń nazw jest w rzeczywistości kopią stosu sieciowego Linuksa, co oznacza, że klienci w przestrzeni nazw RED są całkowicie odizolowani od klientów z przestrzeni nazw GREEN (cóż, albo routing pomiędzy tymi sieciami klientów jest dozwolony przez domyślną przestrzeń nazw, albo przez sprzęt transportowy nadrzędny).
Oznacza to, że otrzymujemy następujący diagram:
Tunele L2 zbiegają się ze wszystkich węzłów obliczeniowych do węzła sterującego. węzeł, w którym znajduje się interfejs L3 dla tych sieci, każdy w dedykowanej przestrzeni nazw w celu izolacji.
Zapomnieliśmy jednak o najważniejszym. Maszyna wirtualna musi świadczyć usługę klientowi, czyli musi posiadać przynajmniej jeden interfejs zewnętrzny, poprzez który można się z nią skontaktować. Oznacza to, że musimy wyjść do świata zewnętrznego. Istnieją różne opcje tutaj. Zróbmy najprostszą opcję. Do każdego klienta dodamy jedną sieć, która będzie obowiązywać w sieci dostawcy i nie będzie się nakładać na inne sieci. Sieci mogą również przecinać się i patrzeć na różne VRF po stronie sieci dostawcy. Dane sieciowe będą również znajdować się w przestrzeni nazw każdego klienta. Jednak nadal będą wychodzić na świat zewnętrzny poprzez jeden fizyczny (lub więź, co jest bardziej logiczne). Aby oddzielić ruch kliencki, ruch wychodzący na zewnątrz będzie oznaczony tagiem VLAN przydzielonym klientowi.
W rezultacie otrzymaliśmy taki schemat:
Rozsądnym pytaniem jest, dlaczego nie utworzyć bram w samych węzłach obliczeniowych? Nie jest to duży problem, co więcej, jeśli włączysz router rozproszony (DVR), to zadziała. W tym scenariuszu rozważamy najprostszą opcję ze scentralizowaną bramą, która jest domyślnie używana w Openstack. W przypadku funkcji o dużym obciążeniu wykorzystają zarówno rozproszony router, jak i technologie akceleracyjne, takie jak SR-IOV i Passthrough, ale jak mówią, to zupełnie inna historia. Najpierw zajmijmy się podstawową częścią, a potem przejdziemy do szczegółów.
Właściwie nasz schemat jest już wykonalny, ale jest kilka niuansów:
Musimy jakoś zabezpieczyć nasze maszyny, czyli nałożyć filtr na interfejs przełącznika w kierunku klienta.
Pozwól maszynie wirtualnej automatycznie uzyskać adres IP, abyś nie musiał za każdym razem logować się do niej przez konsolę i rejestrować adres.
Zacznijmy od ochrony maszyn. Do tego możesz użyć banalnego iptables, czemu nie.
Oznacza to, że teraz nasza topologia stała się nieco bardziej skomplikowana:
Przejdźmy dalej. Musimy dodać serwer DHCP. Najbardziej idealnym miejscem do zlokalizowania serwerów DHCP dla każdego klienta będzie wspomniany już powyżej węzeł kontrolny, w którym zlokalizowane są przestrzenie nazw:
Jest jednak mały problem. A co jeśli wszystko uruchomi się ponownie i znikną wszelkie informacje o wynajmowaniu adresów na DHCP. Logiczne jest, że maszynom zostaną nadane nowe adresy, co nie jest zbyt wygodne. Są tu dwa wyjścia - albo użyj nazw domen i dodaj serwer DNS dla każdego klienta, wtedy adres nie będzie dla nas szczególnie ważny (podobnie jak część sieciowa w k8s) - ale jest problem z sieciami zewnętrznymi, ponieważ adresy można w nich nadawać także poprzez DHCP – potrzebna jest synchronizacja z serwerami DNS w platformie chmurowej i zewnętrznym serwerem DNS, co moim zdaniem nie jest zbyt elastyczne, ale jest całkiem możliwe. Lub drugą opcją jest użycie metadanych - czyli zapisanie informacji o adresie wydanym maszynie, aby serwer DHCP wiedział, jaki adres wydać maszynie, jeśli maszyna już otrzymała adres. Druga opcja jest prostsza i bardziej elastyczna, ponieważ pozwala zapisać dodatkowe informacje o samochodzie. Dodajmy teraz metadane agenta do diagramu:
Kolejną kwestią, którą również warto omówić, jest możliwość korzystania z jednej sieci zewnętrznej przez wszystkich klientów, gdyż sieci zewnętrzne, jeśli muszą obowiązywać w całej sieci, będą trudne - trzeba stale przydzielać i kontrolować przydział tych sieci. Możliwość wykorzystania jednej zewnętrznej, prekonfigurowanej sieci dla wszystkich klientów będzie bardzo przydatna podczas tworzenia chmury publicznej. Ułatwi to wdrażanie maszyn, ponieważ nie musimy sprawdzać bazy adresowej i wybierać unikalnej przestrzeni adresowej dla sieci zewnętrznej każdego klienta. Dodatkowo możemy wcześniej zarejestrować sieć zewnętrzną i w momencie wdrożenia wystarczyć będzie nam powiązanie adresów zewnętrznych z maszynami klienckimi.
I tutaj z pomocą przychodzi nam NAT - po prostu umożliwimy klientom dostęp do świata zewnętrznego poprzez domyślną przestrzeń nazw za pomocą tłumaczenia NAT. No i tu jest mały problem. Jest to dobre, jeśli serwer-klient działa jak klient, a nie jak serwer - to znaczy inicjuje, a nie akceptuje połączenia. Ale u nas będzie odwrotnie. W tym przypadku musimy wykonać docelowy NAT, aby węzeł kontrolny odbierając ruch zrozumiał, że ten ruch jest przeznaczony dla maszyny wirtualnej A klienta A, co oznacza, że musimy wykonać translację NAT z adresu zewnętrznego, na przykład 100.1.1.1 .10.0.0.1, na adres wewnętrzny 100. W tym przypadku, chociaż wszyscy klienci będą korzystać z tej samej sieci, izolacja wewnętrzna zostanie całkowicie zachowana. Oznacza to, że musimy wykonać dNAT i sNAT w węźle kontrolnym. To, czy używać jednej sieci ze zmiennymi adresami, czy sieci zewnętrznych, czy obu naraz, zależy od tego, co chcesz przenieść do chmury. Nie będziemy dodawać adresów pływających do diagramu, ale pozostawimy dodane już wcześniej sieci zewnętrzne - każdy klient ma swoją sieć zewnętrzną (na schemacie są oznaczeni jako vlan 200 i XNUMX na interfejsie zewnętrznym).
W rezultacie otrzymaliśmy ciekawe i jednocześnie przemyślane rozwiązanie, które ma pewną elastyczność, ale nie posiada jeszcze mechanizmów odporności na awarie.
Po pierwsze, mamy tylko jeden węzeł kontrolny – jego awaria doprowadzi do upadku wszystkich systemów. Aby rozwiązać ten problem, musisz uzyskać kworum co najmniej 3 węzłów. Dodajmy to do diagramu:
Naturalnie wszystkie węzły są zsynchronizowane i gdy aktywny węzeł odejdzie, inny węzeł przejmie jego obowiązki.
Następnym problemem są dyski maszyn wirtualnych. W tej chwili są one przechowywane na samych hypervisorach, a w przypadku problemów z hypervisorem tracimy wszystkie dane - a obecność nalotu tutaj nie pomoże, jeśli stracimy nie dysk, ale cały serwer. Aby to zrobić, musimy stworzyć usługę, która będzie działać jako interfejs dla pewnego rodzaju magazynu. Jaki to będzie magazyn nie jest dla nas szczególnie istotny, ale powinien chronić nasze dane przed awarią zarówno dysku, jak i węzła, a być może i całej szafy. Opcji tutaj jest kilka – są oczywiście sieci SAN z Fibre Channel, ale bądźmy szczerzy – FC to już relikt przeszłości – odpowiednik E1 w transporcie – tak, zgadzam się, nadal jest używany, ale tylko tam, gdzie jest to absolutnie niemożliwe bez niego. Dlatego w 2020 roku nie zdecydowałbym się na dobrowolne uruchomienie sieci FC, wiedząc, że istnieją inne, ciekawsze alternatywy. Choć każdy ma swoje zdanie, mogą znaleźć się tacy, którzy uwierzą, że FC ze wszystkimi jego ograniczeniami to wszystko, czego nam potrzeba – nie będę się sprzeczał, każdy ma swoje zdanie. Jednak najciekawszym rozwiązaniem moim zdaniem jest zastosowanie SDS, takiego jak Ceph.
Ceph pozwala na zbudowanie rozwiązania do przechowywania danych o wysokiej dostępności z wieloma możliwymi opcjami tworzenia kopii zapasowych, począwszy od kodów ze sprawdzaniem parzystości (analogicznie do raid 5 lub 6) kończąc na pełnej replikacji danych na różne dyski, z uwzględnieniem lokalizacji dysków w serwery, serwery w szafach itp.
Aby zbudować Ceph, potrzebujesz 3 dodatkowych węzłów. Interakcja z magazynem będzie odbywać się także poprzez sieć z wykorzystaniem usług przechowywania blokowego, obiektowego i plikowego. Dodajmy pamięć do schematu:
Uwaga: można także tworzyć hiperkonwergentne węzły obliczeniowe – jest to koncepcja łączenia kilku funkcji w jednym węźle – np. przechowywanie+obliczenia – bez przeznaczania specjalnych węzłów na przechowywanie ceph. Otrzymamy ten sam schemat odporny na błędy - ponieważ SDS będzie rezerwować dane na określonym przez nas poziomie rezerwacji. Jednak węzły hiperkonwergentne są zawsze kompromisem - ponieważ węzeł magazynowania nie tylko podgrzewa powietrze, jak się wydaje na pierwszy rzut oka (ponieważ nie ma na nim maszyn wirtualnych), ale wydaje zasoby procesora na obsługę SDS (w rzeczywistości robi wszystko replikacja i odzyskiwanie po awariach węzłów, dysków itp.). Oznacza to, że jeśli połączysz go z pamięcią masową, utracisz część mocy węzła obliczeniowego.
Trzeba tym wszystkim jakoś zarządzać - potrzebujemy czegoś, za pomocą czego będziemy mogli stworzyć maszynę, sieć, wirtualny router itp. W tym celu do węzła kontrolnego dodamy usługę, która będzie pełnić funkcję dashboardu - klient będzie mógł połączyć się z tym portalem poprzez http/https i zrobić wszystko, czego potrzebuje (no, prawie).
W rezultacie mamy teraz system odporny na awarie. Wszystkie elementy tej infrastruktury muszą być w jakiś sposób zarządzane. Wcześniej opisano, że Openstack to zbiór projektów, z których każdy zapewnia określoną funkcję. Jak widzimy, elementów do skonfigurowania i kontrolowania jest więcej niż wystarczająca liczba. Dzisiaj porozmawiamy o części sieciowej.
Architektura neutronowa
W OpenStack to Neutron odpowiada za połączenie portów maszyn wirtualnych ze wspólną siecią L2, zapewnienie routingu ruchu pomiędzy maszynami wirtualnymi znajdującymi się w różnych sieciach L2, a także routing zewnętrzny, świadczący usługi takie jak NAT, Floating IP, DHCP itp.
Na wysokim poziomie działanie usługi sieciowej (część podstawowa) można opisać następująco.
Podczas uruchamiania maszyny wirtualnej usługa sieciowa:
Tworzy port dla danej VM (lub portów) i powiadamia o tym usługę DHCP;
Tworzone jest nowe wirtualne urządzenie sieciowe (poprzez libvirt);
Maszyna wirtualna łączy się z portami utworzonymi w kroku 1;
Co dziwne, praca Neutrona opiera się na standardowych mechanizmach znanych każdemu, kto kiedykolwiek nurkował w Linuksie - przestrzenie nazw, iptables, mosty linuksowe, openvswitch, conntrack itp.
Należy od razu wyjaśnić, że Neutron nie jest kontrolerem SDN.
Neutron składa się z kilku połączonych ze sobą elementów:
Serwer neutronowy Openstack to demon obsługujący żądania użytkowników poprzez API. Demon ten nie zajmuje się rejestrowaniem żadnych połączeń sieciowych, ale dostarcza niezbędne w tym celu informacje do swoich wtyczek, które następnie konfigurują żądany element sieci. Agenci Neutron w węzłach OpenStack rejestrują się na serwerze Neutron.
Neutron-server to tak naprawdę aplikacja napisana w Pythonie, składająca się z dwóch części:
Usługa REST
Wtyczka Neutron (rdzeń/usługa)
Usługa REST przeznaczona jest do odbierania wywołań API z innych komponentów (na przykład żądania podania informacji itp.)
Wtyczki to komponenty/moduły oprogramowania wtyczek, które są wywoływane podczas żądań API, co oznacza, że za ich pośrednictwem następuje przypisanie usługi. Wtyczki dzielą się na dwa typy - service i root. Z reguły wtyczka konia odpowiada głównie za zarządzanie przestrzenią adresową i połączeniami L2 pomiędzy maszynami wirtualnymi, a wtyczki usług zapewniają już dodatkowe funkcjonalności, takie jak VPN czy FW.
Listę dostępnych obecnie wtyczek można zobaczyć na przykład tutaj
Może istnieć kilka wtyczek usług, ale może być tylko jedna wtyczka konia.
openstack-neutron-ml2 to standardowa wtyczka root Openstack. Wtyczka ta ma architekturę modułową (w przeciwieństwie do swojej poprzedniczki) i konfiguruje usługę sieciową poprzez podłączone do niej sterowniki. Samej wtyczce przyjrzymy się nieco później, ponieważ w rzeczywistości zapewnia ona elastyczność, jaką ma OpenStack w części sieciowej. Wtyczkę root można wymienić (na przykład firma Contrail Networking dokonuje takiej wymiany).
Usługa RPC (serwer Rabbitmq) — usługa zapewniająca zarządzanie kolejkami i interakcję z innymi usługami OpenStack, a także interakcję pomiędzy agentami usług sieciowych.
Agenci sieciowi — agenci zlokalizowani w każdym węźle, za pośrednictwem których konfigurowane są usługi sieciowe.
Istnieje kilka rodzajów agentów.
Głównym agentem jest Agent L2. Agenci ci działają na każdym z hypervisorów, łącznie z węzłami kontrolnymi (dokładniej na wszystkich węzłach świadczących dowolną usługę dla najemców), a ich główną funkcją jest łączenie maszyn wirtualnych ze wspólną siecią L2, a także generowanie alertów w przypadku wystąpienia jakichkolwiek zdarzeń ( na przykład wyłącz/włącz port).
Następnym, nie mniej ważnym agentem jest Agent L3. Domyślnie agent ten działa wyłącznie na węźle sieci (często węzeł sieci jest połączony z węzłem kontrolnym) i zapewnia routing pomiędzy sieciami dzierżawców (zarówno pomiędzy jego sieciami, jak i sieciami innych dzierżawców i jest dostępny dla świata zewnętrznego, zapewniając NAT, a także usługa DHCP). Jednak w przypadku korzystania z DVR (routera rozproszonego) potrzeba wtyczki L3 pojawia się również na węzłach obliczeniowych.
Agent L3 korzysta z przestrzeni nazw systemu Linux, aby zapewnić każdemu najemcy zestaw własnych izolowanych sieci oraz funkcjonalność routerów wirtualnych, które kierują ruchem i zapewniają usługi bram dla sieci warstwy 2.
Baza danych — baza danych identyfikatorów sieci, podsieci, portów, pul itp.
Tak naprawdę Neutron przyjmuje żądania API od utworzenia dowolnych podmiotów sieciowych, uwierzytelnia żądanie i poprzez RPC (jeśli uzyskuje dostęp do jakiejś wtyczki lub agenta) lub API REST (jeśli komunikuje się w SDN) przesyła do agentów (poprzez wtyczki) instrukcje niezbędne do zorganizowania żądanej usługi.
Przejdźmy teraz do instalacji testowej (jak jest ona wdrażana i co zawiera, zobaczymy w dalszej części części praktycznej) i zobaczmy, gdzie znajdują się poszczególne komponenty:
(overcloud) [stack@undercloud ~]$ openstack network agent list
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
| 10495de9-ba4b-41fe-b30a-b90ec3f8728b | Open vSwitch agent | overcloud-novacompute-1.localdomain | None | :-) | UP | neutron-openvswitch-agent |
| 1515ad4a-5972-46c3-af5f-e5446dff7ac7 | L3 agent | overcloud-controller-0.localdomain | nova | :-) | UP | neutron-l3-agent |
| 322e62ca-1e5a-479e-9a96-4f26d09abdd7 | DHCP agent | overcloud-controller-0.localdomain | nova | :-) | UP | neutron-dhcp-agent |
| 9c1de2f9-bac5-400e-998d-4360f04fc533 | Open vSwitch agent | overcloud-novacompute-0.localdomain | None | :-) | UP | neutron-openvswitch-agent |
| d99c5657-851e-4d3c-bef6-f1e3bb1acfb0 | Open vSwitch agent | overcloud-controller-0.localdomain | None | :-) | UP | neutron-openvswitch-agent |
| ff85fae6-5543-45fb-a301-19c57b62d836 | Metadata agent | overcloud-controller-0.localdomain | None | :-) | UP | neutron-metadata-agent |
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
(overcloud) [stack@undercloud ~]$
Właściwie to cała struktura Neutronu. Teraz warto poświęcić trochę czasu na wtyczkę ML2.
Warstwa modułowa 2
Jak wspomniano powyżej, wtyczka jest standardową wtyczką root OpenStack i ma architekturę modułową.
Poprzednik wtyczki ML2 miał budowę monolityczną, co nie pozwalało np. na zastosowanie miksu kilku technologii w jednej instalacji. Na przykład nie można jednocześnie używać openvswitch i linuxbridge - ani pierwszego, ani drugiego. Z tego powodu stworzono wtyczkę ML2 wraz z jej architekturą.
ML2 składa się z dwóch komponentów - dwóch typów sterowników: sterowników typu i sterowników mechanizmu.
Wpisz sterowniki określić technologie, które zostaną wykorzystane do organizacji połączeń sieciowych, np. VxLAN, VLAN, GRE. Jednocześnie sterownik pozwala na zastosowanie różnych technologii. Standardową technologią jest enkapsulacja VxLAN dla sieci nakładkowych i zewnętrznych sieci VLAN.
Sterowniki typów obejmują następujące typy sieci:
Mieszkanie - sieć bez tagowania VLAN - sieć oznaczona miejscowy — specjalny typ sieci do instalacji typu „wszystko w jednym” (takie instalacje są potrzebne programistom lub do celów szkoleniowych) GRE — sieć nakładkowa wykorzystująca tunele GRE VxLAN — sieć nakładkowa wykorzystująca tunele VxLAN
Sterowniki mechanizmu zdefiniuj narzędzia zapewniające organizację technologii określonych w sterowniku typu - na przykład openvswitch, sr-iov, opendaylight, OVN itp.
W zależności od implementacji tego sterownika wykorzystane zostaną albo agenty kontrolowane przez Neutron, albo wykorzystane zostaną połączenia z zewnętrznym kontrolerem SDN, który zajmuje się wszystkimi kwestiami związanymi z organizacją sieci L2, routingiem itp.
Przykład: jeśli używamy ML2 razem z OVS, wówczas na każdym węźle obliczeniowym, który zarządza OVS, instalowany jest agent L2. Jeżeli jednak skorzystamy np. z OVN czy OpenDayLight to wówczas kontrola OVS przechodzi pod ich jurysdykcję – Neutron poprzez wtyczkę root wydaje polecenia kontrolerowi, a ten już robi co mu każą.
Przypomnijmy sobie Open vSwitch
W tej chwili jednym z kluczowych komponentów OpenStack jest Open vSwitch.
Podczas instalacji OpenStack bez dodatkowego dostawcy SDN, takiego jak Juniper Contrail lub Nokia Nuage, OVS jest głównym składnikiem sieciowym sieci w chmurze i wraz z iptables, conntrack i przestrzeniami nazw umożliwia organizowanie pełnoprawnych sieci nakładkowych z wieloma dzierżawcami. Naturalnie komponent ten można wymienić np. w przypadku korzystania z autorskich rozwiązań SDN innych firm (dostawców).
OVS to przełącznik programowy typu open source przeznaczony do użytku w środowiskach zwirtualizowanych jako wirtualny moduł przesyłania dalej.
W tej chwili OVS ma bardzo przyzwoitą funkcjonalność, która obejmuje technologie takie jak QoS, LACP, VLAN, VxLAN, GENEVE, OpenFlow, DPDK itp.
Uwaga: OVS nie został początkowo pomyślany jako przełącznik programowy do mocno obciążonych funkcji telekomunikacyjnych, ale został zaprojektowany bardziej z myślą o funkcjach IT wymagających mniejszej przepustowości, takich jak serwer WWW lub serwer pocztowy. Jednak OVS jest dalej rozwijany, a obecne wdrożenia OVS znacznie poprawiły jego wydajność i możliwości, co pozwala na korzystanie z niego operatorom telekomunikacyjnym z mocno obciążonymi funkcjami, np. istnieje implementacja OVS ze wsparciem akceleracji DPDK.
Istnieją trzy ważne elementy OVS, o których musisz wiedzieć:
Moduł jądra — komponent znajdujący się w przestrzeni jądra, który przetwarza ruch w oparciu o reguły otrzymane od elementu sterującego;
vPrzełącznik demon (ovs-vswitchd) to proces uruchamiany w przestrzeni użytkownika, który odpowiada za zaprogramowanie modułu jądra - czyli bezpośrednio reprezentuje logikę działania przełącznika
Serwer bazy danych - lokalna baza danych znajdująca się na każdym hoście z uruchomionym OVS, w której przechowywana jest konfiguracja. Kontrolery SDN mogą komunikować się za pośrednictwem tego modułu wykorzystując protokół OVSDB.
Wszystkiemu temu towarzyszy zestaw narzędzi diagnostycznych i zarządzających, takich jak ovs-vsctl, ovs-appctl, ovs-ofctl itp.
Obecnie Openstack jest szeroko stosowany przez operatorów telekomunikacyjnych do migracji do niego funkcji sieciowych, takich jak EPC, SBC, HLR itp. Niektóre funkcje mogą działać bez problemów z OVS tak jak jest, ale np. EPC przetwarza ruch abonencki - wtedy przechodzi ogromna ilość ruchu (obecnie wielkość ruchu sięga kilkuset gigabitów na sekundę). Oczywiście kierowanie takiego ruchu przez przestrzeń jądra (ponieważ domyślnie tam znajduje się forwarder) nie jest najlepszym pomysłem. Dlatego OVS jest często wdrażany całkowicie w przestrzeni użytkownika przy użyciu technologii akceleracji DPDK w celu przekazywania ruchu z karty sieciowej do przestrzeni użytkownika z pominięciem jądra.
Uwaga: w przypadku chmury wdrożonej dla funkcji telekomunikacyjnych możliwe jest wyprowadzanie ruchu z węzła obliczeniowego z pominięciem OVS bezpośrednio do sprzętu przełączającego. Wykorzystywane są w tym celu mechanizmy SR-IOV i Passthrough.
Jak to działa na prawdziwym układzie?
Cóż, teraz przejdźmy do części praktycznej i zobaczmy, jak to wszystko działa w praktyce.
Najpierw przeprowadźmy prostą instalację Openstack. Ponieważ nie mam pod ręką zestawu serwerów do eksperymentów, prototyp złożymy na jednym serwerze fizycznym z maszyn wirtualnych. Tak, oczywiście, takie rozwiązanie nie nadaje się do celów komercyjnych, ale żeby zobaczyć przykład działania sieci w Openstack, na oko wystarczy taka instalacja. Co więcej, taka instalacja jest jeszcze bardziej interesująca do celów szkoleniowych - ponieważ można łapać ruch uliczny itp.
Ponieważ musimy zobaczyć tylko podstawową część, nie możemy korzystać z kilku sieci, ale podnieść wszystko za pomocą tylko dwóch sieci, a druga sieć w tym układzie będzie używana wyłącznie do dostępu do chmury undercloud i serwera DNS. O sieciach zewnętrznych nie będziemy na razie poruszać – to temat na osobny, duży artykuł.
Zacznijmy więc po kolei. Na początek trochę teorii. Zainstalujemy Openstack przy użyciu TripleO (Openstack na Openstack). Istotą TripleO jest to, że instalujemy Openstack all-in-one (czyli na jednym węźle), zwany undercloud, a następnie wykorzystujemy możliwości wdrożonego Openstack, aby zainstalować Openstack przeznaczony do działania, zwany overcloud. Undercloud wykorzysta swoją wrodzoną zdolność do zarządzania serwerami fizycznymi (bare metal) – projekt Ironic – w celu udostępnienia hiperwizorów, które będą pełnić rolę węzłów obliczeniowych, kontrolnych i magazynowych. Oznacza to, że do wdrażania Openstack nie używamy żadnych narzędzi innych firm - wdrażamy Openstack za pomocą Openstack. W miarę postępu instalacji stanie się to znacznie jaśniejsze, więc nie poprzestaniemy na tym i nie będziemy kontynuować.
Uwaga: w tym artykule dla uproszczenia nie zastosowałem izolacji sieci dla wewnętrznych sieci Openstack, ale wszystko jest wdrażane przy użyciu tylko jednej sieci. Jednakże obecność lub brak izolacji sieci nie wpływa na podstawową funkcjonalność rozwiązania – wszystko będzie działać dokładnie tak samo, jak przy zastosowaniu izolacji, jednak ruch będzie płynął w tej samej sieci. W przypadku instalacji komercyjnej konieczne jest oczywiście zastosowanie izolacji przy użyciu różnych sieci VLAN i interfejsów. Na przykład ruch związany z zarządzaniem pamięcią masową ceph i samym ruchem danych (dostęp maszyn do dysków itp.), gdy jest izolowany, korzysta z różnych podsieci (zarządzanie pamięcią masową i pamięć masowa), co pozwala uczynić rozwiązanie bardziej odpornym na awarie, na przykład dzieląc ten ruch , na różnych portach lub przy użyciu różnych profili QoS dla różnych ruchu, aby ruch danych nie wypierał ruchu sygnalizacyjnego. W naszym przypadku pójdą w tej samej sieci i tak naprawdę nie ogranicza nas to w żaden sposób.
Uwaga: Ponieważ będziemy uruchamiać maszyny wirtualne w środowisku wirtualnym opartym na maszynach wirtualnych, najpierw musimy włączyć wirtualizację zagnieżdżoną.
Możesz sprawdzić, czy wirtualizacja zagnieżdżona jest włączona, czy nie, w ten sposób:
[root@hp-gen9 bormoglotx]# cat /sys/module/kvm_intel/parameters/nested
N
[root@hp-gen9 bormoglotx]#
Jeśli zobaczysz literkę N, to włączamy obsługę wirtualizacji zagnieżdżonej według dowolnego poradnika, który znajdziesz w sieci, np. takie .
Musimy złożyć następujący obwód z maszyn wirtualnych:
W moim przypadku do połączenia maszyn wirtualnych, które będą częścią przyszłej instalacji (a mam ich 7, ale jak nie mam dużo zasobów, to sobie poradzę na 4), użyłem OpenvSwitch. Stworzyłem jeden mostek ovs i podłączyłem do niego maszyny wirtualne za pośrednictwem grup portów. Aby to zrobić, utworzyłem taki plik XML:
Deklarowane są tutaj trzy grupy portów - dwie dostępowe i jeden trunk (ten ostatni był potrzebny serwerowi DNS, ale możesz się bez niego obejść lub zainstalować na komputerze hosta - w zależności od tego, co jest dla Ciebie wygodniejsze). Następnie, korzystając z tego szablonu, deklarujemy nasz poprzez virsh net-define:
Uwaga: w tym scenariuszu adres na porcie ovs-br1 nie będzie dostępny, ponieważ nie ma on tagu vlan. Aby to naprawić, musisz wydać polecenie sudo ovs-vsctl set port ovs-br1 tag=100. Jednak po ponownym uruchomieniu tag ten zniknie (jeśli ktoś wie, jak sprawić, by pozostał na swoim miejscu, będę bardzo wdzięczny). Ale to nie jest tak ważne, ponieważ będziemy potrzebować tego adresu tylko podczas instalacji i nie będzie on potrzebny po pełnym wdrożeniu Openstack.
Podczas instalacji ustawiasz wszystkie niezbędne parametry, takie jak nazwa komputera, hasła, użytkownicy, serwery ntp itp., możesz od razu skonfigurować porty, ale dla mnie osobiście po instalacji łatwiej jest zalogować się do maszyny przez konsoli i popraw niezbędne pliki. Jeśli masz już gotowy obraz, możesz go użyć lub zrobić to samo, co ja - pobierz minimalny obraz Centos 7 i użyj go do zainstalowania maszyny wirtualnej.
Po udanej instalacji powinieneś mieć maszynę wirtualną, na której będziesz mógł zainstalować undercloud
[root@hp-gen9 bormoglotx]# virsh list
Id Name State
----------------------------------------------------
6 dns-server running
62 undercloud running
Najpierw zainstaluj narzędzia niezbędne do procesu instalacji:
Tworzymy użytkownika stosu, ustalamy hasło, dodajemy je do sudoera i dajemy mu możliwość wykonywania poleceń roota poprzez sudo bez konieczności podawania hasła:
Uwaga: jeśli nie planujesz instalować ceph, nie musisz wprowadzać poleceń związanych z ceph. Ja użyłem wydania Queens, ale możesz użyć dowolnego innego, według własnego uznania.
Następnie skopiuj plik konfiguracyjny Undercloud do stosu katalogu domowego użytkownika:
nazwa_hosta pod chmurą — pełna nazwa serwera undercloud, musi być zgodna z wpisem na serwerze DNS
lokalny_ip — lokalny adres w chmurze w celu zapewnienia obsługi sieci
bramka_sieci — ten sam adres lokalny, który będzie pełnił rolę bramy dostępu do świata zewnętrznego podczas instalacji węzłów overcloud, pokrywa się również z lokalnym adresem IP
undercloud_public_host — zewnętrzny adres API, przydzielany jest dowolny wolny adres z sieci udostępniającej
undercloud_admin_host wewnętrzny adres API, przypisywany jest dowolny wolny adres z sieci udostępniającej
serwery nazw_undercloud - Serwer DNS
wygeneruj_certyfikat_usługi - ta linia jest bardzo ważna w bieżącym przykładzie, ponieważ jeśli nie ustawisz jej na false, podczas instalacji pojawi się błąd, problem jest opisany w narzędziu do śledzenia błędów Red Hat
interfejs_lokalny interfejs w udostępnianiu sieci. Ten interfejs zostanie ponownie skonfigurowany podczas wdrażania w chmurze, dlatego musisz mieć dwa interfejsy w chmurze — jeden do uzyskiwania dostępu, drugi do udostępniania
lokalny_mtu — MTU. Ponieważ mamy laboratorium testowe i mam MTU 1500 na portach przełącznika OVS, konieczne jest ustawienie go na 1450, aby pakiety kapsułkowane w VxLAN mogły przejść
sieć_cidr — sieć zaopatrzeniowa
maskarada — korzystanie z NAT w celu uzyskania dostępu do sieci zewnętrznej
maskarada_sieć - sieć, która będzie NATowana
dhcp_start — adres początkowy puli adresów, z której adresy zostaną przypisane do węzłów podczas wdrażania overcloud
dhcp_end — końcowy adres puli adresów, z której adresy zostaną przypisane do węzłów podczas wdrażania overcloud
inspekcja_iprange — pula adresów niezbędnych do introspekcji (nie powinna pokrywać się z powyższą pulą)
harmonogram_max_attempts — maksymalna liczba prób instalacji overcloud (musi być większa lub równa liczbie węzłów)
Po opisaniu pliku możesz wydać polecenie wdrożenia w chmurze:
openstack undercloud install
Procedura trwa od 10 do 30 minut, w zależności od żelazka. Ostatecznie powinieneś zobaczyć takie dane wyjściowe:
vi undercloud.conf
2020-08-13 23:13:12,668 INFO:
#############################################################################
Undercloud install complete.
The file containing this installation's passwords is at
/home/stack/undercloud-passwords.conf.
There is also a stackrc file at /home/stack/stackrc.
These files are needed to interact with the OpenStack services, and should be
secured.
#############################################################################
To wyjście mówi, że pomyślnie zainstalowałeś Undercloud i możesz teraz sprawdzić status Undercloud i przystąpić do instalacji Overcloud.
Jeśli spojrzysz na wynik ifconfig, zobaczysz, że pojawił się nowy interfejs mostu
W tej chwili mamy tylko undercloud i nie mamy wystarczającej liczby węzłów, z których będzie montowany overcloud. Dlatego przede wszystkim zainstalujmy potrzebne nam maszyny wirtualne. Podczas wdrożenia undercloud sam zainstaluje system operacyjny i niezbędne oprogramowanie na maszynie overcloud – czyli nie musimy całkowicie wdrażać maszyny, a jedynie stworzyć dla niej dysk (lub dyski) i określić jego parametry – czyli w rzeczywistości otrzymujemy goły serwer bez zainstalowanego na nim systemu operacyjnego.
Przejdźmy do folderu z dyskami naszych maszyn wirtualnych i utwórzmy dyski o wymaganej wielkości:
Ponieważ działamy jako root, musimy zmienić właściciela tych dysków, aby nie mieć problemu z uprawnieniami:
[root@hp-gen9 images]# ls -lh
total 5.8G
drwxr-xr-x. 2 qemu qemu 4.0K Aug 13 16:15 backups
-rw-r--r--. 1 root root 61G Aug 14 03:07 compute-1.qcow2
-rw-r--r--. 1 root root 61G Aug 14 03:07 compute-2.qcow2
-rw-r--r--. 1 root root 61G Aug 14 03:07 control-1.qcow2
-rw-------. 1 qemu qemu 41G Aug 14 03:03 dns-server.qcow2
-rw-r--r--. 1 root root 161G Aug 14 03:07 storage-1.qcow2
-rw-r--r--. 1 root root 161G Aug 14 03:07 storage-2.qcow2
-rw-------. 1 qemu qemu 41G Aug 14 03:07 undercloud.qcow2
[root@hp-gen9 images]#
[root@hp-gen9 images]#
[root@hp-gen9 images]# chown qemu:qemu /var/lib/libvirt/images/*qcow2
[root@hp-gen9 images]# ls -lh
total 5.8G
drwxr-xr-x. 2 qemu qemu 4.0K Aug 13 16:15 backups
-rw-r--r--. 1 qemu qemu 61G Aug 14 03:07 compute-1.qcow2
-rw-r--r--. 1 qemu qemu 61G Aug 14 03:07 compute-2.qcow2
-rw-r--r--. 1 qemu qemu 61G Aug 14 03:07 control-1.qcow2
-rw-------. 1 qemu qemu 41G Aug 14 03:03 dns-server.qcow2
-rw-r--r--. 1 qemu qemu 161G Aug 14 03:07 storage-1.qcow2
-rw-r--r--. 1 qemu qemu 161G Aug 14 03:07 storage-2.qcow2
-rw-------. 1 qemu qemu 41G Aug 14 03:08 undercloud.qcow2
[root@hp-gen9 images]#
Uwaga: jeśli nie planujesz instalować ceph w celu jego przestudiowania, polecenia nie tworzą co najmniej 3 węzłów z co najmniej dwoma dyskami, ale w szablonie wskazują, że będą używane dyski wirtualne vda, vdb itp.
Świetnie, teraz musimy zdefiniować wszystkie te maszyny:
Na końcu znajduje się komenda -print-xml > /tmp/storage-1.xml, która tworzy plik xml z opisem każdej maszyny w folderze /tmp/; jeśli go nie dodasz, nie będziesz w stanie zidentyfikować maszyny wirtualne.
Teraz musimy zdefiniować wszystkie te maszyny w virsh:
virsh define --file /tmp/control-1.xml
virsh define --file /tmp/compute-1.xml
virsh define --file /tmp/compute-2.xml
virsh define --file /tmp/storage-1.xml
virsh define --file /tmp/storage-2.xml
[root@hp-gen9 ~]# virsh list --all
Id Name State
----------------------------------------------------
6 dns-server running
64 undercloud running
- compute-1 shut off
- compute-2 shut off
- control-1 shut off
- storage-1 shut off
- storage-2 shut off
[root@hp-gen9 ~]#
Teraz mały niuans - tripleO wykorzystuje IPMI do zarządzania serwerami podczas instalacji i introspekcji.
Introspekcja to proces sprawdzania sprzętu w celu uzyskania jego parametrów niezbędnych do dalszego udostępniania węzłów. Introspekcja odbywa się za pomocą ironic, usługi zaprojektowanej do współpracy z serwerami typu bare metal.
Ale tu jest problem - o ile sprzętowe serwery IPMI mają osobny port (lub port współdzielony, ale to nie jest istotne), o tyle maszyny wirtualne takich portów nie mają. Tutaj z pomocą przychodzi nam kula o nazwie vbmc - narzędzie umożliwiające emulację portu IPMI. Na ten niuans warto zwrócić uwagę szczególnie dla tych, którzy chcą założyć takie laboratorium na hypervisorze ESXI - szczerze mówiąc nie wiem, czy ma on odpowiednik vbmc, więc warto się nad tym zastanowić przed wdrożeniem wszystkiego .
Zainstaluj vbmc:
yum install yum install python2-virtualbmc
Jeśli Twój system operacyjny nie może znaleźć pakietu, dodaj repozytorium:
Myślę, że składnia poleceń jest jasna i nie wymaga wyjaśnień. Jednak na razie wszystkie nasze sesje mają status DOWN. Aby mogły przejść do statusu UP, musisz je włączyć:
[root@hp-gen9 ~]# vbmc start control-1
2020-08-14 03:15:57,826.826 13149 INFO VirtualBMC [-] Started vBMC instance for domain control-1
[root@hp-gen9 ~]# vbmc start storage-1
2020-08-14 03:15:58,316.316 13149 INFO VirtualBMC [-] Started vBMC instance for domain storage-1
[root@hp-gen9 ~]# vbmc start storage-2
2020-08-14 03:15:58,851.851 13149 INFO VirtualBMC [-] Started vBMC instance for domain storage-2
[root@hp-gen9 ~]# vbmc start compute-1
2020-08-14 03:15:59,307.307 13149 INFO VirtualBMC [-] Started vBMC instance for domain compute-1
[root@hp-gen9 ~]# vbmc start compute-2
2020-08-14 03:15:59,712.712 13149 INFO VirtualBMC [-] Started vBMC instance for domain compute-2
[root@hp-gen9 ~]#
[root@hp-gen9 ~]#
[root@hp-gen9 ~]# vbmc list
+-------------+---------+---------+------+
| Domain name | Status | Address | Port |
+-------------+---------+---------+------+
| compute-1 | running | :: | 7004 |
| compute-2 | running | :: | 7005 |
| control-1 | running | :: | 7001 |
| storage-1 | running | :: | 7002 |
| storage-2 | running | :: | 7003 |
+-------------+---------+---------+------+
[root@hp-gen9 ~]#
I ostatni akcent - musisz poprawić reguły zapory ogniowej (lub całkowicie ją wyłączyć):
Przejdźmy teraz do undercloud i sprawdźmy, czy wszystko działa. Adres hosta to 192.168.255.200, w chmurze dodaliśmy niezbędny pakiet ipmitool podczas przygotowań do wdrożenia:
[stack@undercloud ~]$ ipmitool -I lanplus -U admin -P admin -H 192.168.255.200 -p 7001 power status
Chassis Power is off
[stack@undercloud ~]$ ipmitool -I lanplus -U admin -P admin -H 192.168.255.200 -p 7001 power on
Chassis Power Control: Up/On
[stack@undercloud ~]$
[root@hp-gen9 ~]# virsh list
Id Name State
----------------------------------------------------
6 dns-server running
64 undercloud running
65 control-1 running
Jak widać, pomyślnie uruchomiliśmy węzeł kontrolny poprzez vbmc. Teraz wyłączmy to i przejdźmy dalej:
[stack@undercloud ~]$ ipmitool -I lanplus -U admin -P admin -H 192.168.255.200 -p 7001 power off
Chassis Power Control: Down/Off
[stack@undercloud ~]$ ipmitool -I lanplus -U admin -P admin -H 192.168.255.200 -p 7001 power status
Chassis Power is off
[stack@undercloud ~]$
[root@hp-gen9 ~]# virsh list --all
Id Name State
----------------------------------------------------
6 dns-server running
64 undercloud running
- compute-1 shut off
- compute-2 shut off
- control-1 shut off
- storage-1 shut off
- storage-2 shut off
[root@hp-gen9 ~]#
Kolejnym krokiem jest introspekcja węzłów, na których zostanie zainstalowany overcloud. W tym celu musimy przygotować plik json z opisem naszych węzłów. Należy pamiętać, że w przeciwieństwie do instalacji na czystych serwerach, plik wskazuje port, na którym działa vbmc dla każdej maszyny.
[root@hp-gen9 ~]# virsh domiflist --domain control-1
Interface Type Source Model MAC
-------------------------------------------------------
- network ovs-network-1 virtio 52:54:00:20:a2:2f
- network ovs-network-1 virtio 52:54:00:3f:87:9f
[root@hp-gen9 ~]# virsh domiflist --domain compute-1
Interface Type Source Model MAC
-------------------------------------------------------
- network ovs-network-1 virtio 52:54:00:98:e9:d6
[root@hp-gen9 ~]# virsh domiflist --domain compute-2
Interface Type Source Model MAC
-------------------------------------------------------
- network ovs-network-1 virtio 52:54:00:6a:ea:be
[root@hp-gen9 ~]# virsh domiflist --domain storage-1
Interface Type Source Model MAC
-------------------------------------------------------
- network ovs-network-1 virtio 52:54:00:79:0b:cb
[root@hp-gen9 ~]# virsh domiflist --domain storage-2
Interface Type Source Model MAC
-------------------------------------------------------
- network ovs-network-1 virtio 52:54:00:a7:fe:27
Uwaga: węzeł sterujący posiada dwa interfejsy, jednak w tym przypadku nie jest to istotne, w tej instalacji wystarczy nam jeden.
Teraz przygotowujemy plik json. Musimy wskazać makowy adres portu, przez który będzie realizowana administracja, parametry węzłów, nadać im nazwy i wskazać jak dostać się do ipmi:
Teraz musimy przygotować obrazy na ironię. Aby to zrobić, pobierz je za pomocą wget i zainstaluj:
(undercloud) [stack@undercloud ~]$ sudo wget https://images.rdoproject.org/queens/delorean/current-tripleo-rdo/overcloud-full.tar --no-check-certificate
(undercloud) [stack@undercloud ~]$ sudo wget https://images.rdoproject.org/queens/delorean/current-tripleo-rdo/ironic-python-agent.tar --no-check-certificate
(undercloud) [stack@undercloud ~]$ ls -lh
total 1.9G
-rw-r--r--. 1 stack stack 447M Aug 14 10:26 ironic-python-agent.tar
-rw-r--r--. 1 stack stack 1.5G Aug 14 10:26 overcloud-full.tar
-rw-------. 1 stack stack 916 Aug 13 23:10 stackrc
-rw-r--r--. 1 stack stack 15K Aug 13 22:50 undercloud.conf
-rw-------. 1 stack stack 2.0K Aug 13 22:50 undercloud-passwords.conf
(undercloud) [stack@undercloud ~]$ mkdir images/
(undercloud) [stack@undercloud ~]$ tar -xpvf ironic-python-agent.tar -C ~/images/
ironic-python-agent.initramfs
ironic-python-agent.kernel
(undercloud) [stack@undercloud ~]$ tar -xpvf overcloud-full.tar -C ~/images/
overcloud-full.qcow2
overcloud-full.initrd
overcloud-full.vmlinuz
(undercloud) [stack@undercloud ~]$
(undercloud) [stack@undercloud ~]$ ls -lh images/
total 1.9G
-rw-rw-r--. 1 stack stack 441M Aug 12 17:24 ironic-python-agent.initramfs
-rwxr-xr-x. 1 stack stack 6.5M Aug 12 17:24 ironic-python-agent.kernel
-rw-r--r--. 1 stack stack 53M Aug 12 17:14 overcloud-full.initrd
-rw-r--r--. 1 stack stack 1.4G Aug 12 17:18 overcloud-full.qcow2
-rwxr-xr-x. 1 stack stack 6.5M Aug 12 17:14 overcloud-full.vmlinuz
(undercloud) [stack@undercloud ~]$
Przesyłanie zdjęć do Undercloud:
(undercloud) [stack@undercloud ~]$ openstack overcloud image upload --image-path ~/images/
Image "overcloud-full-vmlinuz" was uploaded.
+--------------------------------------+------------------------+-------------+---------+--------+
| ID | Name | Disk Format | Size | Status |
+--------------------------------------+------------------------+-------------+---------+--------+
| c2553770-3e0f-4750-b46b-138855b5c385 | overcloud-full-vmlinuz | aki | 6761064 | active |
+--------------------------------------+------------------------+-------------+---------+--------+
Image "overcloud-full-initrd" was uploaded.
+--------------------------------------+-----------------------+-------------+----------+--------+
| ID | Name | Disk Format | Size | Status |
+--------------------------------------+-----------------------+-------------+----------+--------+
| 949984e0-4932-4e71-af43-d67a38c3dc89 | overcloud-full-initrd | ari | 55183045 | active |
+--------------------------------------+-----------------------+-------------+----------+--------+
Image "overcloud-full" was uploaded.
+--------------------------------------+----------------+-------------+------------+--------+
| ID | Name | Disk Format | Size | Status |
+--------------------------------------+----------------+-------------+------------+--------+
| a2f2096d-c9d7-429a-b866-c7543c02a380 | overcloud-full | qcow2 | 1487475712 | active |
+--------------------------------------+----------------+-------------+------------+--------+
Image "bm-deploy-kernel" was uploaded.
+--------------------------------------+------------------+-------------+---------+--------+
| ID | Name | Disk Format | Size | Status |
+--------------------------------------+------------------+-------------+---------+--------+
| e413aa78-e38f-404c-bbaf-93e582a8e67f | bm-deploy-kernel | aki | 6761064 | active |
+--------------------------------------+------------------+-------------+---------+--------+
Image "bm-deploy-ramdisk" was uploaded.
+--------------------------------------+-------------------+-------------+-----------+--------+
| ID | Name | Disk Format | Size | Status |
+--------------------------------------+-------------------+-------------+-----------+--------+
| 5cf3aba4-0e50-45d3-929f-27f025dd6ce3 | bm-deploy-ramdisk | ari | 461759376 | active |
+--------------------------------------+-------------------+-------------+-----------+--------+
(undercloud) [stack@undercloud ~]$
Sprawdzanie, czy wszystkie obrazy zostały załadowane
(undercloud) [stack@undercloud ~]$ openstack image list
+--------------------------------------+------------------------+--------+
| ID | Name | Status |
+--------------------------------------+------------------------+--------+
| e413aa78-e38f-404c-bbaf-93e582a8e67f | bm-deploy-kernel | active |
| 5cf3aba4-0e50-45d3-929f-27f025dd6ce3 | bm-deploy-ramdisk | active |
| a2f2096d-c9d7-429a-b866-c7543c02a380 | overcloud-full | active |
| 949984e0-4932-4e71-af43-d67a38c3dc89 | overcloud-full-initrd | active |
| c2553770-3e0f-4750-b46b-138855b5c385 | overcloud-full-vmlinuz | active |
+--------------------------------------+------------------------+--------+
(undercloud) [stack@undercloud ~]$
(undercloud) [stack@undercloud ~]$ openstack overcloud node import --introspect --provide inspection.json
Started Mistral Workflow tripleo.baremetal.v1.register_or_update. Execution ID: d57456a3-d8ed-479c-9a90-dff7c752d0ec
Waiting for messages on queue 'tripleo' with no timeout.
5 node(s) successfully moved to the "manageable" state.
Successfully registered node UUID b4b2cf4a-b7ca-4095-af13-cc83be21c4f5
Successfully registered node UUID b89a72a3-6bb7-429a-93bc-48393d225838
Successfully registered node UUID 20a16cc0-e0ce-4d88-8f17-eb0ce7b4d69e
Successfully registered node UUID bfc1eb98-a17a-4a70-b0b6-6c0db0eac8e8
Successfully registered node UUID 766ab623-464c-423d-a529-d9afb69d1167
Waiting for introspection to finish...
Started Mistral Workflow tripleo.baremetal.v1.introspect. Execution ID: 6b4d08ae-94c3-4a10-ab63-7634ec198a79
Waiting for messages on queue 'tripleo' with no timeout.
Introspection of node b89a72a3-6bb7-429a-93bc-48393d225838 completed. Status:SUCCESS. Errors:None
Introspection of node 20a16cc0-e0ce-4d88-8f17-eb0ce7b4d69e completed. Status:SUCCESS. Errors:None
Introspection of node bfc1eb98-a17a-4a70-b0b6-6c0db0eac8e8 completed. Status:SUCCESS. Errors:None
Introspection of node 766ab623-464c-423d-a529-d9afb69d1167 completed. Status:SUCCESS. Errors:None
Introspection of node b4b2cf4a-b7ca-4095-af13-cc83be21c4f5 completed. Status:SUCCESS. Errors:None
Successfully introspected 5 node(s).
Started Mistral Workflow tripleo.baremetal.v1.provide. Execution ID: f5594736-edcf-4927-a8a0-2a7bf806a59a
Waiting for messages on queue 'tripleo' with no timeout.
5 node(s) successfully moved to the "available" state.
(undercloud) [stack@undercloud ~]$
Jak widać na wynikach, wszystko zakończyło się bez błędów. Sprawdźmy, czy wszystkie węzły są w stanie dostępnym:
(undercloud) [stack@undercloud ~]$ openstack baremetal node list
+--------------------------------------+-----------+---------------+-------------+--------------------+-------------+
| UUID | Name | Instance UUID | Power State | Provisioning State | Maintenance |
+--------------------------------------+-----------+---------------+-------------+--------------------+-------------+
| b4b2cf4a-b7ca-4095-af13-cc83be21c4f5 | control-1 | None | power off | available | False |
| b89a72a3-6bb7-429a-93bc-48393d225838 | storage-1 | None | power off | available | False |
| 20a16cc0-e0ce-4d88-8f17-eb0ce7b4d69e | storage-2 | None | power off | available | False |
| bfc1eb98-a17a-4a70-b0b6-6c0db0eac8e8 | compute-1 | None | power off | available | False |
| 766ab623-464c-423d-a529-d9afb69d1167 | compute-2 | None | power off | available | False |
+--------------------------------------+-----------+---------------+-------------+--------------------+-------------+
(undercloud) [stack@undercloud ~]$
Jeśli węzły są w innym stanie, zwykle możliwym do zarządzania, oznacza to, że coś poszło nie tak i musisz zajrzeć do dziennika i dowiedzieć się, dlaczego tak się stało. Należy pamiętać, że w tym scenariuszu korzystamy z wirtualizacji i mogą występować błędy związane z używaniem maszyn wirtualnych lub vbmc.
Następnie musimy wskazać, który węzeł będzie realizował jaką funkcję – czyli wskazać profil, z jakim węzeł będzie wdrażany:
W prawdziwej instalacji zostaną oczywiście użyte niestandardowe szablony, w naszym przypadku znacznie skomplikuje to proces, ponieważ każda edycja w szablonie będzie musiała zostać wyjaśniona. Tak jak pisano wcześniej, wystarczy nam nawet prosta instalacja, abyśmy mogli zobaczyć jak to działa.
Uwaga: w tym przypadku zmienna qemu --libvirt-type jest konieczna, ponieważ będziemy używać wirtualizacji zagnieżdżonej. W przeciwnym razie nie będzie można uruchomić maszyn wirtualnych.
Teraz masz około godziny, a może i więcej (w zależności od możliwości sprzętu) i możesz mieć tylko nadzieję, że po tym czasie zobaczysz następujący komunikat:
Teraz masz prawie pełnoprawną wersję openstack, na której możesz się uczyć, eksperymentować itp.
Sprawdźmy, czy wszystko działa prawidłowo. W stosie katalogu domowego użytkownika znajdują się dwa pliki - jeden stackrc (do zarządzania Undercloud) i drugi overcloudrc (do zarządzania overcloud). Pliki te należy określić jako źródłowe, ponieważ zawierają informacje niezbędne do uwierzytelnienia.
(undercloud) [stack@undercloud ~]$ openstack server list
+--------------------------------------+-------------------------+--------+-------------------------+----------------+--------------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+-------------------------+--------+-------------------------+----------------+--------------+
| fd7d36f4-ce87-4b9a-93b0-add2957792de | overcloud-controller-0 | ACTIVE | ctlplane=192.168.255.15 | overcloud-full | control |
| edc77778-8972-475e-a541-ff40eb944197 | overcloud-novacompute-1 | ACTIVE | ctlplane=192.168.255.26 | overcloud-full | compute |
| 5448ce01-f05f-47ca-950a-ced14892c0d4 | overcloud-cephstorage-1 | ACTIVE | ctlplane=192.168.255.34 | overcloud-full | ceph-storage |
| ce6d862f-4bdf-4ba3-b711-7217915364d7 | overcloud-novacompute-0 | ACTIVE | ctlplane=192.168.255.19 | overcloud-full | compute |
| e4507bd5-6f96-4b12-9cc0-6924709da59e | overcloud-cephstorage-0 | ACTIVE | ctlplane=192.168.255.44 | overcloud-full | ceph-storage |
+--------------------------------------+-------------------------+--------+-------------------------+----------------+--------------+
(undercloud) [stack@undercloud ~]$
(undercloud) [stack@undercloud ~]$ source overcloudrc
(overcloud) [stack@undercloud ~]$
(overcloud) [stack@undercloud ~]$ openstack project list
+----------------------------------+---------+
| ID | Name |
+----------------------------------+---------+
| 4eed7d0f06544625857d51cd77c5bd4c | admin |
| ee1c68758bde41eaa9912c81dc67dad8 | service |
+----------------------------------+---------+
(overcloud) [stack@undercloud ~]$
(overcloud) [stack@undercloud ~]$
(overcloud) [stack@undercloud ~]$ openstack network agent list
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
| 10495de9-ba4b-41fe-b30a-b90ec3f8728b | Open vSwitch agent | overcloud-novacompute-1.localdomain | None | :-) | UP | neutron-openvswitch-agent |
| 1515ad4a-5972-46c3-af5f-e5446dff7ac7 | L3 agent | overcloud-controller-0.localdomain | nova | :-) | UP | neutron-l3-agent |
| 322e62ca-1e5a-479e-9a96-4f26d09abdd7 | DHCP agent | overcloud-controller-0.localdomain | nova | :-) | UP | neutron-dhcp-agent |
| 9c1de2f9-bac5-400e-998d-4360f04fc533 | Open vSwitch agent | overcloud-novacompute-0.localdomain | None | :-) | UP | neutron-openvswitch-agent |
| d99c5657-851e-4d3c-bef6-f1e3bb1acfb0 | Open vSwitch agent | overcloud-controller-0.localdomain | None | :-) | UP | neutron-openvswitch-agent |
| ff85fae6-5543-45fb-a301-19c57b62d836 | Metadata agent | overcloud-controller-0.localdomain | None | :-) | UP | neutron-metadata-agent |
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
(overcloud) [stack@undercloud ~]$
Moja instalacja nadal wymaga jednego małego akcentu - dodania trasy na kontrolerze, ponieważ maszyna, z którą pracuję, znajduje się w innej sieci. Aby to zrobić, przejdź do control-1 pod kontem heat-admin i zarejestruj trasę
(undercloud) [stack@undercloud ~]$ ssh [email protected]
Last login: Fri Aug 14 09:47:40 2020 from 192.168.255.1
[heat-admin@overcloud-controller-0 ~]$
[heat-admin@overcloud-controller-0 ~]$
[heat-admin@overcloud-controller-0 ~]$ sudo ip route add 10.169.0.0/16 via 192.168.255.254
Cóż, teraz możesz udać się w horyzont. Wszystkie informacje - adresy, login i hasło - znajdują się w pliku /home/stack/overcloudrc. Ostateczny diagram wygląda następująco:
Nawiasem mówiąc, w naszej instalacji adresy maszyn były nadawane przez DHCP i jak widać są nadawane „losowo”. Możesz ściśle określić w szablonie, który adres ma być dołączony do jakiej maszyny podczas wdrażania, jeśli jest to potrzebne.
Jak przepływa ruch pomiędzy maszynami wirtualnymi?
W tym artykule przyjrzymy się trzem opcjom przepuszczania ruchu
Dwie maszyny na jednym hypervisorze w jednej sieci L2
Dwie maszyny na różnych hypervisorach w tej samej sieci L2
Dwie maszyny w różnych sieciach (rootowanie międzysieciowe)
Przypadki z dostępem do świata zewnętrznego poprzez sieć zewnętrzną, z wykorzystaniem adresów zmiennoprzecinkowych, a także routingu rozproszonego, rozważymy następnym razem, na razie skupimy się na ruchu wewnętrznym.
Aby to sprawdzić, sporządźmy następujący diagram:
Stworzyliśmy 4 maszyny wirtualne - 3 w jednej sieci L2 - net-1 i 1 więcej w sieci net-2
(overcloud) [stack@undercloud ~]$ nova list --tenant 5e18ce8ec9594e00b155485f19895e6c
+--------------------------------------+------+----------------------------------+--------+------------+-------------+-----------------+
| ID | Name | Tenant ID | Status | Task State | Power State | Networks |
+--------------------------------------+------+----------------------------------+--------+------------+-------------+-----------------+
| f53b37b5-2204-46cc-aef0-dba84bf970c0 | vm-1 | 5e18ce8ec9594e00b155485f19895e6c | ACTIVE | - | Running | net-1=10.0.1.85 |
| fc8b6722-0231-49b0-b2fa-041115bef34a | vm-2 | 5e18ce8ec9594e00b155485f19895e6c | ACTIVE | - | Running | net-1=10.0.1.88 |
| 3cd74455-b9b7-467a-abe3-bd6ff765c83c | vm-3 | 5e18ce8ec9594e00b155485f19895e6c | ACTIVE | - | Running | net-1=10.0.1.90 |
| 7e836338-6772-46b0-9950-f7f06dbe91a8 | vm-4 | 5e18ce8ec9594e00b155485f19895e6c | ACTIVE | - | Running | net-2=10.0.2.8 |
+--------------------------------------+------+----------------------------------+--------+------------+-------------+-----------------+
(overcloud) [stack@undercloud ~]$
Zobaczmy na jakich hypervisorach znajdują się utworzone maszyny:
Zanim jednak przyjrzymy się przepływowi ruchu, przyjrzyjmy się, co aktualnie mamy w węźle kontrolnym (który jest także węzłem sieciowym) i węźle obliczeniowym. Zacznijmy od węzła obliczeniowego.
W tej chwili w węźle znajdują się trzy mosty ovs - br-int, br-tun, br-ex. Pomiędzy nimi, jak widzimy, znajduje się zestaw interfejsów. Aby ułatwić zrozumienie, narysujmy wszystkie te interfejsy na diagramie i zobaczmy, co się stanie.
Patrząc na adresy, do których podnoszone są tunele VxLAN, można zauważyć, że jeden tunel jest podnoszony do obliczenia-1 (192.168.255.26), drugi tunel do kontroli-1 (192.168.255.15). Ale najciekawsze jest to, że br-ex nie ma fizycznych interfejsów, a jeśli spojrzysz na to, jakie przepływy są skonfigurowane, zobaczysz, że ten most może w tej chwili jedynie ograniczać ruch.
Zgodnie z pierwszą zasadą wszystko, co wyszło z portu phy-br-ex, należy wyrzucić.
Właściwie obecnie nie ma innego miejsca, w którym ruch mógłby dopływać do tego mostu, z wyjątkiem tego interfejsu (interfejs z br-int), a sądząc po spadkach, ruch BUM został już przeniesiony na most.
Oznacza to, że ruch może opuścić ten węzeł tylko przez tunel VxLAN i nic więcej. Jeśli jednak włączysz rejestrator, sytuacja się zmieni, ale tym zajmiemy się innym razem. Używając izolacji sieci, na przykład używając vlanów, będziesz mieć nie jeden interfejs L3 w vlanie 0, ale kilka interfejsów. Jednak ruch VxLAN będzie opuszczał węzeł w ten sam sposób, ale również będzie zamknięty w jakiejś dedykowanej sieci VLAN.
Uporządkowaliśmy węzeł obliczeniowy, przejdźmy do węzła sterującego.
Właściwie można powiedzieć, że wszystko jest takie samo, ale adres IP nie znajduje się już na fizycznym interfejsie, ale na wirtualnym moście. Dzieje się tak, ponieważ ten port jest portem, przez który ruch będzie wychodził do świata zewnętrznego.
Ten port jest powiązany z mostkiem br-ex i ponieważ nie ma na nim znaczników VLAN, jest to port trunk, na którym dozwolone są wszystkie VLANy, teraz ruch wychodzi na zewnątrz bez znacznika, jak wskazuje vlan-id 0 w pliku wyjście powyżej.
Wszystko inne w tej chwili jest podobne do węzła obliczeniowego – te same mosty, te same tunele prowadzące do dwóch węzłów obliczeniowych.
W tym artykule nie będziemy rozważać węzłów magazynowania, ale dla zrozumienia należy powiedzieć, że część sieciowa tych węzłów jest banalna aż do hańby. W naszym przypadku jest tylko jeden port fizyczny (eth0) z przypisanym do niego adresem IP i tyle. Nie ma tu tuneli VxLAN, mostów tunelowych itp. - w ogóle nie ma ovów, bo nie ma to sensu. W przypadku korzystania z izolacji sieci, węzeł ten będzie miał dwa interfejsy (porty fizyczne, bodny, lub tylko dwa vlany - to nie ma znaczenia - zależy czego chcesz) - jeden do zarządzania, drugi do ruchu (zapis na dysk VM , odczyt z dysku itp.)
Ustaliliśmy, co mamy w węzłach przy braku jakichkolwiek usług. Uruchommy teraz 4 maszyny wirtualne i zobaczmy jak zmienia się opisany powyżej schemat - powinniśmy mieć porty, wirtualne routery itp.
Póki co nasza sieć wygląda tak:
Mamy dwie maszyny wirtualne na każdym węźle komputera. Używając obliczenia-0 jako przykładu, zobaczmy, jak wszystko jest uwzględnione.
[heat-admin@overcloud-novacompute-0 ~]$ sudo virsh list
Id Name State
----------------------------------------------------
1 instance-00000001 running
3 instance-00000003 running
[heat-admin@overcloud-novacompute-0 ~]$
Maszyna posiada tylko jeden interfejs wirtualny - tap95d96a75-a0:
[heat-admin@overcloud-novacompute-0 ~]$ sudo virsh domiflist instance-00000001
Interface Type Source Model MAC
-------------------------------------------------------
tap95d96a75-a0 bridge qbr95d96a75-a0 virtio fa:16:3e:44:98:20
[heat-admin@overcloud-novacompute-0 ~]$
Ten interfejs wygląda w moście Linux:
[heat-admin@overcloud-novacompute-0 ~]$ sudo brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242904c92a8 no
qbr5bd37136-47 8000.5e4e05841423 no qvb5bd37136-47
tap5bd37136-47
qbr95d96a75-a0 8000.de076cb850f6 no qvb95d96a75-a0
tap95d96a75-a0
[heat-admin@overcloud-novacompute-0 ~]$
Jak widać na wyjściu, w moście znajdują się tylko dwa interfejsy - tap95d96a75-a0 i qvb95d96a75-a0.
Tutaj warto zatrzymać się trochę na typach wirtualnych urządzeń sieciowych w OpenStack:
vtap - wirtualny interfejs podłączony do instancji (VM)
qbr – mostek pod Linuksem
qvb i qvo - para vEth podłączona do mostu Linux i mostu Open vSwitch
br-int, br-tun, br-vlan — Otwarte mosty vSwitch
patch-, int-br-, phy-br- - Otwarte interfejsy krosowe vSwitch łączące mosty
qg, qr, ha, fg, sg - Otwarte porty vSwitch używane przez urządzenia wirtualne do łączenia się z OVS
Jak rozumiesz, jeśli mamy w mostku port qvb95d96a75-a0, który jest parą vEth, to gdzieś jest jego odpowiednik, który logicznie powinien nazywać się qvo95d96a75-a0. Zobaczmy, jakie porty są w OVS.
Jak widać port jest w br-int. Br-int pełni funkcję przełącznika kończącego porty maszyny wirtualnej. Oprócz qvo95d96a75-a0 na wyjściu widoczny jest port qvo5bd37136-47. To jest port do drugiej maszyny wirtualnej. W rezultacie nasz diagram wygląda teraz tak:
Pytanie, które powinno od razu zainteresować uważnego czytelnika - jaki jest linuksowy most pomiędzy portem maszyny wirtualnej a portem OVS? Faktem jest, że do ochrony maszyny wykorzystywane są grupy bezpieczeństwa, które są niczym więcej niż iptables. OVS nie współpracuje z iptables, dlatego wymyślono tę „kulę”. Jednak staje się przestarzały - w nowych wydaniach jest zastępowany przez conntrack.
Oznacza to, że ostatecznie schemat wygląda następująco:
Dwie maszyny na jednym hypervisorze w jednej sieci L2
Ponieważ te dwie maszyny wirtualne znajdują się w tej samej sieci L2 i na tym samym hypervisorze, ruch między nimi będzie logicznie przepływał lokalnie przez br-int, ponieważ obie maszyny będą w tej samej sieci VLAN:
[heat-admin@overcloud-novacompute-0 ~]$ sudo virsh domiflist instance-00000001
Interface Type Source Model MAC
-------------------------------------------------------
tap95d96a75-a0 bridge qbr95d96a75-a0 virtio fa:16:3e:44:98:20
[heat-admin@overcloud-novacompute-0 ~]$
[heat-admin@overcloud-novacompute-0 ~]$
[heat-admin@overcloud-novacompute-0 ~]$ sudo virsh domiflist instance-00000003
Interface Type Source Model MAC
-------------------------------------------------------
tap5bd37136-47 bridge qbr5bd37136-47 virtio fa:16:3e:83:ad:a4
[heat-admin@overcloud-novacompute-0 ~]$
[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-appctl fdb/show br-int
port VLAN MAC Age
6 1 fa:16:3e:83:ad:a4 0
3 1 fa:16:3e:44:98:20 0
[heat-admin@overcloud-novacompute-0 ~]$
Dwie maszyny na różnych hypervisorach w tej samej sieci L2
Zobaczmy teraz, jak będzie przebiegał ruch między dwoma maszynami w tej samej sieci L2, ale zlokalizowanymi na różnych hypervisorach. Tak naprawdę niewiele się zmieni, po prostu ruch pomiędzy hypervisorami będzie przechodził przez tunel vxlan. Spójrzmy na przykład.
Adresy maszyn wirtualnych pomiędzy którymi będziemy oglądać ruch:
[heat-admin@overcloud-novacompute-0 ~]$ sudo virsh domiflist instance-00000001
Interface Type Source Model MAC
-------------------------------------------------------
tap95d96a75-a0 bridge qbr95d96a75-a0 virtio fa:16:3e:44:98:20
[heat-admin@overcloud-novacompute-0 ~]$
[heat-admin@overcloud-novacompute-1 ~]$ sudo virsh domiflist instance-00000002
Interface Type Source Model MAC
-------------------------------------------------------
tape7e23f1b-07 bridge qbre7e23f1b-07 virtio fa:16:3e:72:ad:53
[heat-admin@overcloud-novacompute-1 ~]$
Patrzymy na tabelę przekazywania w br-int na compute-0:
Mac znajduje się w tabeli przekierowań br-int na komputerze obliczeniowym-1 i jak widać z powyższych danych wyjściowych, jest on widoczny przez port 2, który jest portem do br-tun:
Oznacza to, że odebrany pakiet poleci do portu 3, za którym znajduje się już instancja maszyny wirtualnej-00000003.
Piękno wdrożenia Openstack do nauki w infrastrukturze wirtualnej polega na tym, że możemy łatwo przechwytywać ruch pomiędzy hypervisorami i sprawdzać, co się z nim dzieje. Oto, co teraz zrobimy: uruchom tcpdump na porcie vnet w kierunku compute-0:
[root@hp-gen9 bormoglotx]# tcpdump -vvv -i vnet3
tcpdump: listening on vnet3, link-type EN10MB (Ethernet), capture size 262144 bytes
*****************omitted*******************
04:39:04.583459 IP (tos 0x0, ttl 64, id 16868, offset 0, flags [DF], proto UDP (17), length 134)
192.168.255.19.39096 > 192.168.255.26.4789: [no cksum] VXLAN, flags [I] (0x08), vni 22
IP (tos 0x0, ttl 64, id 8012, offset 0, flags [DF], proto ICMP (1), length 84)
10.0.1.85 > 10.0.1.88: ICMP echo request, id 5634, seq 16, length 64
04:39:04.584449 IP (tos 0x0, ttl 64, id 35181, offset 0, flags [DF], proto UDP (17), length 134)
192.168.255.26.speedtrace-disc > 192.168.255.19.4789: [no cksum] VXLAN, flags [I] (0x08), vni 22
IP (tos 0x0, ttl 64, id 59124, offset 0, flags [none], proto ICMP (1), length 84)
10.0.1.88 > 10.0.1.85: ICMP echo reply, id 5634, seq 16, length 64
*****************omitted*******************
Pierwsza linia pokazuje, że Patek z adresu 10.0.1.85 trafia na adres 10.0.1.88 (ruch ICMP), jest opakowany w pakiet VxLAN z vni 22 i pakiet przechodzi z hosta 192.168.255.19 (compute-0) do hosta 192.168.255.26 .1 (obliczenie-XNUMX). Możemy sprawdzić, czy VNI odpowiada temu określonemu w ovs.
Wróćmy do tej linii action=load:0->NXM_OF_VLAN_TCI[],load:0x16->NXM_NX_TUN_ID[],output:2. 0x16 to vni w szesnastkowym systemie liczbowym. Przekształćmy tę liczbę do systemu 16:
16 = 6*16^0+1*16^1 = 6+16 = 22
Oznacza to, że vni odpowiada rzeczywistości.
Druga linijka pokazuje ruch powrotny, no cóż, nie ma co tego tłumaczyć, tam wszystko jest jasne.
Dwie maszyny w różnych sieciach (routing międzysieciowy)
Ostatnim przypadkiem na dziś jest routing pomiędzy sieciami w ramach jednego projektu z wykorzystaniem routera wirtualnego. Rozważamy przypadek bez rejestratora (przyjrzymy się temu w innym artykule), więc routing odbywa się po węźle sieci. W naszym przypadku węzeł sieciowy nie jest umieszczony w osobnej jednostce i znajduje się na węźle sterującym.
Najpierw zobaczmy, że routing działa:
$ ping 10.0.2.8
PING 10.0.2.8 (10.0.2.8): 56 data bytes
64 bytes from 10.0.2.8: seq=0 ttl=63 time=7.727 ms
64 bytes from 10.0.2.8: seq=1 ttl=63 time=3.832 ms
^C
--- 10.0.2.8 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 3.832/5.779/7.727 ms
Ponieważ w tym przypadku pakiet musi udać się do bramy i tam zostać trasowany, musimy znaleźć makowy adres bramy, dla czego w tym przypadku patrzymy na tablicę ARP:
$ arp
host-10-0-1-254.openstacklocal (10.0.1.254) at fa:16:3e:c4:64:70 [ether] on eth0
host-10-0-1-1.openstacklocal (10.0.1.1) at fa:16:3e:e6:2c:5c [ether] on eth0
host-10-0-1-90.openstacklocal (10.0.1.90) at fa:16:3e:83:ad:a4 [ether] on eth0
host-10-0-1-88.openstacklocal (10.0.1.88) at fa:16:3e:72:ad:53 [ether] on eth0
Zobaczmy teraz, dokąd powinien zostać wysłany ruch z miejscem docelowym (10.0.1.254) fa:16:3e:c4:64:70:
Ruch dotarł do węzła kontrolnego, więc musimy się do niego udać i zobaczyć, jak będzie przebiegał routing.
Jak pamiętacie, węzeł kontrolny w środku wyglądał dokładnie tak samo jak węzeł obliczeniowy - te same trzy mosty, tylko br-ex miał fizyczny port, przez który węzeł mógł wysyłać ruch na zewnątrz. Utworzenie instancji zmieniło konfigurację węzłów obliczeniowych - do węzłów dodano linuxowy most, iptables i interfejsy. Stworzenie sieci i wirtualnego routera odcisnęło także swoje piętno na konfiguracji węzła sterującego.
Jest zatem oczywiste, że adres MAC bramy musi znajdować się w tabeli przekazywania br-int w węźle sterującym. Sprawdźmy czy tam jest i gdzie szuka:
Komputer Mac jest widoczny z portu qr-0c52b15f-8f. Jeśli wrócimy do listy portów wirtualnych w Openstack, to ten typ portu służy do podłączania różnych urządzeń wirtualnych do OVS. Mówiąc dokładniej, qr to port routera wirtualnego, który jest reprezentowany jako przestrzeń nazw.
Zobaczmy, jakie przestrzenie nazw znajdują się na serwerze:
Aż trzy egzemplarze. Ale sądząc po nazwach, możesz odgadnąć cel każdego z nich. Do instancji z ID 0 i 1 wrócimy później, teraz interesuje nas przestrzeń nazw qrouter-0a4d2420-4b9c-46bd-aec1-86a1ef299abe:
[heat-admin@overcloud-controller-0 ~]$ sudo ip netns exec qrouter-0a4d2420-4b9c-46bd-aec1-86a1ef299abe ip route
10.0.1.0/24 dev qr-0c52b15f-8f proto kernel scope link src 10.0.1.254
10.0.2.0/24 dev qr-92fa49b5-54 proto kernel scope link src 10.0.2.254
[heat-admin@overcloud-controller-0 ~]$
Ta przestrzeń nazw zawiera dwie wewnętrzne przestrzenie, które utworzyliśmy wcześniej. Oba porty wirtualne zostały dodane do br-int. Sprawdźmy adres MAC portu qr-0c52b15f-8f, ponieważ ruch, sądząc po docelowym adresie MAC, trafiał do tego interfejsu.
Oznacza to, że w tym przypadku wszystko działa zgodnie z prawami standardowego routingu. Ponieważ ruch jest kierowany do hosta 10.0.2.8, musi wyjść przez drugi interfejs qr-92fa49b5-54 i przejść przez tunel vxlan do węzła obliczeniowego:
[heat-admin@overcloud-controller-0 ~]$ sudo ip netns exec qrouter-0a4d2420-4b9c-46bd-aec1-86a1ef299abe arp
Address HWtype HWaddress Flags Mask Iface
10.0.1.88 ether fa:16:3e:72:ad:53 C qr-0c52b15f-8f
10.0.1.90 ether fa:16:3e:83:ad:a4 C qr-0c52b15f-8f
10.0.2.8 ether fa:16:3e:6c:ad:9c C qr-92fa49b5-54
10.0.2.42 ether fa:16:3e:f5:0b:29 C qr-92fa49b5-54
10.0.1.85 ether fa:16:3e:44:98:20 C qr-0c52b15f-8f
[heat-admin@overcloud-controller-0 ~]$
Wszystko jest logiczne, bez niespodzianek. Zobaczmy gdzie makowy adres hosta 10.0.2.8 jest widoczny w br-int:
Ruch kierowany jest do tunelu w celu obliczenia-1. Cóż, na compute-1 wszystko jest proste - z br-tun pakiet trafia do br-int, a stamtąd do interfejsu maszyny wirtualnej:
Sprawdźmy, czy to rzeczywiście jest poprawny interfejs:
[heat-admin@overcloud-novacompute-1 ~]$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02429c001e1c no
qbr3210e8ec-c0 8000.ea27f45358be no qvb3210e8ec-c0
tap3210e8ec-c0
qbre7e23f1b-07 8000.b26ac0eded8a no qvbe7e23f1b-07
tape7e23f1b-07
[heat-admin@overcloud-novacompute-1 ~]$
[heat-admin@overcloud-novacompute-1 ~]$ sudo virsh domiflist instance-00000004
Interface Type Source Model MAC
-------------------------------------------------------
tap3210e8ec-c0 bridge qbr3210e8ec-c0 virtio fa:16:3e:6c:ad:9c
[heat-admin@overcloud-novacompute-1 ~]$
Właściwie przeszliśmy przez cały pakiet. Myślę, że zauważyłeś, że ruch przechodził przez różne tunele vxlan i wychodził z różnymi VNI. Zobaczmy, jakie to są VNI, po czym zbierzemy zrzut na porcie kontrolnym węzła i upewnimy się, że ruch odbywa się dokładnie tak, jak opisano powyżej.
Zatem tunel do obliczenia-0 ma następujące działania=load:0->NXM_OF_VLAN_TCI[],load:0x16->NXM_NX_TUN_ID[],output:3. Przekonwertujmy 0x16 na system dziesiętny:
0x16 = 6*16^0+1*16^1 = 6+16 = 22
Tunel do obliczenia-1 ma następujący VNI:actions=load:0->NXM_OF_VLAN_TCI[],load:0x63->NXM_NX_TUN_ID[],output:2. Przekonwertujmy 0x63 na system dziesiętny:
0x63 = 3*16^0+6*16^1 = 3+96 = 99
Cóż, teraz spójrzmy na zrzut:
[root@hp-gen9 bormoglotx]# tcpdump -vvv -i vnet4
tcpdump: listening on vnet4, link-type EN10MB (Ethernet), capture size 262144 bytes
*****************omitted*******************
04:35:18.709949 IP (tos 0x0, ttl 64, id 48650, offset 0, flags [DF], proto UDP (17), length 134)
192.168.255.19.41591 > 192.168.255.15.4789: [no cksum] VXLAN, flags [I] (0x08), vni 22
IP (tos 0x0, ttl 64, id 49042, offset 0, flags [DF], proto ICMP (1), length 84)
10.0.1.85 > 10.0.2.8: ICMP echo request, id 5378, seq 9, length 64
04:35:18.710159 IP (tos 0x0, ttl 64, id 23360, offset 0, flags [DF], proto UDP (17), length 134)
192.168.255.15.38983 > 192.168.255.26.4789: [no cksum] VXLAN, flags [I] (0x08), vni 99
IP (tos 0x0, ttl 63, id 49042, offset 0, flags [DF], proto ICMP (1), length 84)
10.0.1.85 > 10.0.2.8: ICMP echo request, id 5378, seq 9, length 64
04:35:18.711292 IP (tos 0x0, ttl 64, id 43596, offset 0, flags [DF], proto UDP (17), length 134)
192.168.255.26.42588 > 192.168.255.15.4789: [no cksum] VXLAN, flags [I] (0x08), vni 99
IP (tos 0x0, ttl 64, id 55103, offset 0, flags [none], proto ICMP (1), length 84)
10.0.2.8 > 10.0.1.85: ICMP echo reply, id 5378, seq 9, length 64
04:35:18.711531 IP (tos 0x0, ttl 64, id 8555, offset 0, flags [DF], proto UDP (17), length 134)
192.168.255.15.38983 > 192.168.255.19.4789: [no cksum] VXLAN, flags [I] (0x08), vni 22
IP (tos 0x0, ttl 63, id 55103, offset 0, flags [none], proto ICMP (1), length 84)
10.0.2.8 > 10.0.1.85: ICMP echo reply, id 5378, seq 9, length 64
*****************omitted*******************
Pierwszy pakiet to pakiet vxlan z hosta 192.168.255.19 (obliczenie-0) do hosta 192.168.255.15 (kontrola-1) z vni 22, wewnątrz którego pakiet ICMP jest pakowany z hosta 10.0.1.85 do hosta 10.0.2.8. Jak obliczyliśmy powyżej, vni odpowiada temu, co widzieliśmy na wyjściu.
Drugi pakiet to pakiet vxlan z hosta 192.168.255.15 (kontrola-1) do hosta 192.168.255.26 (compute-1) z vni 99, wewnątrz którego pakiet ICMP jest pakowany z hosta 10.0.1.85 do hosta 10.0.2.8. Jak obliczyliśmy powyżej, vni odpowiada temu, co widzieliśmy na wyjściu.
Następne dwa pakiety to ruch zwrotny z 10.0.2.8, a nie 10.0.1.85.
Oznacza to, że ostatecznie otrzymaliśmy następujący schemat węzła sterującego:
Wygląda na to, że to wszystko? Zapomnieliśmy o dwóch przestrzeniach nazw:
Skoro już rozmawialiśmy o architekturze platformy chmurowej, dobrze byłoby, gdyby maszyny otrzymywały adresy automatycznie z serwera DHCP. Są to dwa serwery DHCP dla naszych dwóch sieci 10.0.1.0/24 i 10.0.2.0/24.
Sprawdźmy, czy to prawda. W tej przestrzeni nazw jest tylko jeden adres - 10.0.1.1 - adres samego serwera DHCP, który jest również zawarty w br-int:
W rezultacie otrzymujemy następujący zestaw usług w węźle sterującym:
No cóż, pamiętajcie - to tylko 4 maszyny, 2 sieci wewnętrzne i jeden router wirtualny... Nie mamy tu teraz sieci zewnętrznych, kilka różnych projektów, każdy z własnymi sieciami (nakładającymi się) i mamy router rozproszony został wyłączony i ostatecznie na stanowisku testowym znalazł się przecież tylko jeden węzeł kontrolny (dla odporności na błędy wymagane jest kworum trzech węzłów). Logiczne jest, że w handlu wszystko jest „trochę” bardziej skomplikowane, ale na tym prostym przykładzie rozumiemy, jak to powinno działać – czy masz 3, czy 300 przestrzeni nazw jest oczywiście ważne, ale z punktu widzenia działania całego struktury, nic się nie zmieni... dopóki nie podłączysz SDN jakiegoś dostawcy. Ale to zupełnie inna historia.
Mam nadzieję, że było ciekawie. Jeśli masz jakieś uwagi/uzupełnienia, lub gdzieś, gdzie bez ogródek nakłamałem (jestem człowiekiem i moja opinia zawsze będzie subiektywna) - napisz, co należy poprawić/dodać, a my wszystko poprawimy/dodamy.
Na zakończenie chciałbym powiedzieć kilka słów na temat porównania Openstack (zarówno standardowego, jak i dostawcy) z rozwiązaniem chmurowym firmy VMWare - w ciągu ostatnich kilku lat zbyt często zadawano mi to pytanie i szczerze mówiąc, jestem już tym zmęczony, ale jednak. Moim zdaniem bardzo trudno porównać te dwa rozwiązania, jednak z całą pewnością możemy stwierdzić, że oba rozwiązania mają wady i przy wyborze jednego rozwiązania trzeba rozważyć zalety i wady.
Jeśli OpenStack jest rozwiązaniem zorientowanym na społeczność, to VMWare ma prawo robić tylko to, co chce (czytaj – co jest dla niego opłacalne) i jest to logiczne – ponieważ jest to firma komercyjna, która jest przyzwyczajona do zarabiania pieniędzy na swoich klientach. Jest jednak jedno duże i grube ALE - można z OpenStack np. od Nokii zejść i przy niewielkich nakładach przejść na rozwiązanie np. Junipera (Contrail Cloud), ale raczej nie uda się wyjść z VMWare . U mnie te dwa rozwiązania wyglądają tak - Openstack (sprzedawca) to prosta klatka, w której jesteś umieszczony, ale masz klucz i w każdej chwili możesz wyjść. VMWare to złota klatka, właściciel ma klucz do klatki i będzie cię to dużo kosztować.
Nie promuję ani pierwszego produktu, ani drugiego - wybierasz, czego potrzebujesz. Ale gdybym miał taki wybór, wybrałbym oba rozwiązania – VMWare dla chmury IT (niskie obciążenia, łatwe zarządzanie), OpenStack od jakiegoś dostawcy (Nokia i Juniper dostarczają bardzo dobre rozwiązania „pod klucz”) – dla chmury Telecom. Nie używałbym Openstack do czystego IT - to jak strzelanie do wróbli z armaty, ale nie widzę żadnych przeciwwskazań, aby go używać poza redundancją. Jednak używanie VMWare w telekomunikacji przypomina ciągnięcie kruszonego kamienia fordem raptorem – z zewnątrz jest pięknie, ale kierowca musi odbyć 10 przejazdów zamiast jednego.
Według mnie największą wadą VMWare jest jego całkowita zamknięcie - firma nie poda Ci żadnych informacji jak to działa np. vSAN czy co jest w jądrze hypervisora - to się po prostu nie opłaca - tzn. nigdy nie zostań ekspertem VMWare - bez wsparcia dostawcy jesteś skazany na porażkę (bardzo często spotykam ekspertów VMWare, których zaskakują trywialne pytania). Dla mnie VMWare kupuje auto z zamkniętą maską - tak, być może masz specjalistów, którzy potrafią wymienić pasek rozrządu, ale maskę może otworzyć tylko ten, który Ci sprzedał to rozwiązanie. Osobiście nie lubię rozwiązań, do których nie mogę się dopasować. Powiesz, że być może nie będziesz musiał zaglądać pod maskę. Tak, jest to możliwe, ale zajrzę do Ciebie, gdy będziesz musiał złożyć dużą funkcję w chmurze z 20-30 maszyn wirtualnych, 40-50 sieci, z czego połowa chce wyjść na zewnątrz, a druga połowa prosi o Przyspieszenie SR-IOV, w przeciwnym razie będziesz potrzebować więcej kilkudziesięciu tych samochodów - w przeciwnym razie wydajność nie będzie wystarczająca.
Istnieją inne punkty widzenia, więc tylko Ty możesz zdecydować, co wybrać i, co najważniejsze, będziesz wtedy odpowiedzialny za swój wybór. To tylko moja opinia - osoby, która widziała i dotykała co najmniej 4 produkty - Nokię, Juniper, Red Hat i VMWare. To znaczy, że mam z czym porównać.