Wprowadzenie do sieciowej części infrastruktury chmurowej

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:
Wprowadzenie do sieciowej części infrastruktury chmurowej
Zdjęcie zrobione z openstack.org

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.

  1. 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.
  2. 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).
  3. Nova-api sprawdza ważność Twojego żądania, kontaktując się z Keystone przy użyciu wcześniej wygenerowanego tokena autoryzacji
  4. Keystone przeprowadza uwierzytelnianie i dostarcza informacji o uprawnieniach i ograniczeniach w oparciu o ten token autoryzacji.
  5. Nova-api tworzy wpis dla nowej maszyny wirtualnej w bazie danych nova i przekazuje żądanie utworzenia maszyny do programu nova-scheduler.
  6. 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.
  7. 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).
  8. Nova-conductor otrzymuje żądane informacje z bazy danych nova i przekazuje je do nova-compute.
  9. Następnie nova-compute wywołuje rzut oka w celu uzyskania identyfikatora obrazu. Glace sprawdza poprawność żądania w Keystone i zwraca żądane informacje.
  10. 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.
  11. 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.
  12. 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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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.

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

  1. Tworzy port dla danej VM (lub portów) i powiadamia o tym usługę DHCP;
  2. Tworzone jest nowe wirtualne urządzenie sieciowe (poprzez libvirt);
  3. 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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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 ~]$ 

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:


[root@hp-gen9 ~]# virsh net-dumpxml ovs-network-1        
<network>
  <name>ovs-network-1</name>
  <uuid>7a2e7de7-fc16-4e00-b1ed-4d190133af67</uuid>
  <forward mode='bridge'/>
  <bridge name='ovs-br1'/>
  <virtualport type='openvswitch'/>
  <portgroup name='trunk-1'>
    <vlan trunk='yes'>
      <tag id='100'/>
      <tag id='101'/>
      <tag id='102'/>
    </vlan>
  </portgroup>
  <portgroup name='access-100'>
    <vlan>
      <tag id='100'/>
    </vlan>
  </portgroup>
  <portgroup name='access-101'>
    <vlan>
      <tag id='101'/>
    </vlan>
  </portgroup>
</network>

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:


virsh net-define ovs-network-1.xml 
virsh net-start ovs-network-1 
virsh net-autostart ovs-network-1 

Teraz edytujemy konfiguracje portów hypervisora:


[root@hp-gen9 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens1f0   
TYPE=Ethernet
NAME=ens1f0
DEVICE=ens1f0
TYPE=OVSPort
DEVICETYPE=ovs
OVS_BRIDGE=ovs-br1
ONBOOT=yes
OVS_OPTIONS="trunk=100,101,102"
[root@hp-gen9 ~]
[root@hp-gen9 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ovs-br1 
DEVICE=ovs-br1
DEVICETYPE=ovs
TYPE=OVSBridge
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.255.200
PREFIX=24
[root@hp-gen9 ~]# 

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.

Następnie tworzymy maszynę undercloud:


virt-install  -n undercloud --description "undercloud"  --os-type=Linux  --os-variant=centos7.0  --ram=8192  --vcpus=8  --disk path=/var/lib/libvirt/images/undercloud.qcow2,bus=virtio,size=40,format=qcow2 --network network:ovs-network-1,model=virtio,portgroup=access-100 --network network:ovs-network-1,model=virtio,portgroup=access-101 --graphics none  --location /var/lib/libvirt/boot/CentOS-7-x86_64-Minimal-2003.iso --extra-args console=ttyS0

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:

sudo yum update -y
sudo yum install -y net-tools
sudo yum install -y wget
sudo yum install -y ipmitool

Instalacja pod chmurą

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:


useradd stack
passwd stack

echo “stack ALL=(root) NOPASSWD:ALL” > /etc/sudoers.d/stack
chmod 0440 /etc/sudoers.d/stack

Teraz podajemy pełną nazwę Undercloud w pliku hosts:


vi /etc/hosts

127.0.0.1   undercloud.openstack.rnd localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

Następnie dodajemy repozytoria i instalujemy potrzebne nam oprogramowanie:


sudo yum install -y https://trunk.rdoproject.org/centos7/current/python2-tripleo-repos-0.0.1-0.20200409224957.8bac392.el7.noarch.rpm
sudo -E tripleo-repos -b queens current
sudo -E tripleo-repos -b queens current ceph
sudo yum install -y python-tripleoclient
sudo yum install -y ceph-ansible

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:


cp /usr/share/instack-undercloud/undercloud.conf.sample ~/undercloud.conf

Teraz musimy poprawić ten plik, dostosowując go do naszej instalacji.

Musisz dodać te linie na początku pliku:

vi undercloud.conf
[DEFAULT]
undercloud_hostname = undercloud.openstack.rnd
local_ip = 192.168.255.1/24
network_gateway = 192.168.255.1
undercloud_public_host = 192.168.255.2
undercloud_admin_host = 192.168.255.3
undercloud_nameservers = 192.168.255.253
generate_service_certificate = false
local_interface = eth0
local_mtu = 1450
network_cidr = 192.168.255.0/24
masquerade = true
masquerade_network = 192.168.255.0/24
dhcp_start = 192.168.255.11
dhcp_end = 192.168.255.50
inspection_iprange = 192.168.255.51,192.168.255.100
scheduler_max_attempts = 10

Przejdźmy więc do ustawień:

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

[stack@undercloud ~]$ ifconfig
br-ctlplane: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 192.168.255.1  netmask 255.255.255.0  broadcast 192.168.255.255
        inet6 fe80::5054:ff:fe2c:89e  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:2c:08:9e  txqueuelen 1000  (Ethernet)
        RX packets 14  bytes 1095 (1.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 20  bytes 1292 (1.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Wdrożenie w chmurze będzie teraz przeprowadzane za pośrednictwem tego interfejsu.

Z poniższego wyniku widać, że mamy wszystkie usługi w jednym węźle:

(undercloud) [stack@undercloud ~]$ openstack host list
+--------------------------+-----------+----------+
| Host Name                | Service   | Zone     |
+--------------------------+-----------+----------+
| undercloud.openstack.rnd | conductor | internal |
| undercloud.openstack.rnd | scheduler | internal |
| undercloud.openstack.rnd | compute   | nova     |
+--------------------------+-----------+----------+

Poniżej znajduje się konfiguracja części sieciowej undercloud:


(undercloud) [stack@undercloud ~]$ python -m json.tool /etc/os-net-config/config.json 
{
    "network_config": [
        {
            "addresses": [
                {
                    "ip_netmask": "192.168.255.1/24"
                }
            ],
            "members": [
                {
                    "dns_servers": [
                        "192.168.255.253"
                    ],
                    "mtu": 1450,
                    "name": "eth0",
                    "primary": "true",
                    "type": "interface"
                }
            ],
            "mtu": 1450,
            "name": "br-ctlplane",
            "ovs_extra": [
                "br-set-external-id br-ctlplane bridge-id br-ctlplane"
            ],
            "routes": [],
            "type": "ovs_bridge"
        }
    ]
}
(undercloud) [stack@undercloud ~]$

Instalacja w chmurze

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:


cd /var/lib/libvirt/images/
qemu-img create -f qcow2 -o preallocation=metadata control-1.qcow2 60G
qemu-img create -f qcow2 -o preallocation=metadata compute-1.qcow2 60G
qemu-img create -f qcow2 -o preallocation=metadata compute-2.qcow2 60G
qemu-img create -f qcow2 -o preallocation=metadata storage-1.qcow2 160G
qemu-img create -f qcow2 -o preallocation=metadata storage-2.qcow2 160G

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:


virt-install --name control-1 --ram 32768 --vcpus 8 --os-variant centos7.0 --disk path=/var/lib/libvirt/images/control-1.qcow2,device=disk,bus=virtio,format=qcow2 --noautoconsole --vnc  --network network:ovs-network-1,model=virtio,portgroup=access-100 --network network:ovs-network-1,model=virtio,portgroup=trunk-1 --dry-run --print-xml > /tmp/control-1.xml  

virt-install --name storage-1 --ram 16384 --vcpus 4 --os-variant centos7.0 --disk path=/var/lib/libvirt/images/storage-1.qcow2,device=disk,bus=virtio,format=qcow2 --noautoconsole --vnc  --network network:ovs-network-1,model=virtio,portgroup=access-100 --dry-run --print-xml > /tmp/storage-1.xml  

virt-install --name storage-2 --ram 16384 --vcpus 4 --os-variant centos7.0 --disk path=/var/lib/libvirt/images/storage-2.qcow2,device=disk,bus=virtio,format=qcow2 --noautoconsole --vnc  --network network:ovs-network-1,model=virtio,portgroup=access-100 --dry-run --print-xml > /tmp/storage-2.xml  

virt-install --name compute-1 --ram 32768 --vcpus 12 --os-variant centos7.0 --disk path=/var/lib/libvirt/images/compute-1.qcow2,device=disk,bus=virtio,format=qcow2 --noautoconsole --vnc  --network network:ovs-network-1,model=virtio,portgroup=access-100 --dry-run --print-xml > /tmp/compute-1.xml  

virt-install --name compute-2 --ram 32768 --vcpus 12 --os-variant centos7.0 --disk path=/var/lib/libvirt/images/compute-2.qcow2,device=disk,bus=virtio,format=qcow2 --noautoconsole --vnc  --network network:ovs-network-1,model=virtio,portgroup=access-100 --dry-run --print-xml > /tmp/compute-2.xml 

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:

yum install -y https://www.rdoproject.org/repos/rdo-release.rpm

Teraz konfigurujemy narzędzie. Wszystko tutaj jest banalne aż do hańby. Teraz logiczne jest, że na liście vbmc nie ma serwerów


[root@hp-gen9 ~]# vbmc list

[root@hp-gen9 ~]# 

Aby się pojawiły, należy je ręcznie zadeklarować w następujący sposób:


[root@hp-gen9 ~]# vbmc add control-1 --port 7001 --username admin --password admin
[root@hp-gen9 ~]# vbmc add storage-1 --port 7002 --username admin --password admin
[root@hp-gen9 ~]# vbmc add storage-2 --port 7003 --username admin --password admin
[root@hp-gen9 ~]# vbmc add compute-1 --port 7004 --username admin --password admin
[root@hp-gen9 ~]# vbmc add compute-2 --port 7005 --username admin --password admin
[root@hp-gen9 ~]#
[root@hp-gen9 ~]# vbmc list
+-------------+--------+---------+------+
| Domain name | Status | Address | Port |
+-------------+--------+---------+------+
| compute-1   | down   | ::      | 7004 |
| compute-2   | down   | ::      | 7005 |
| control-1   | down   | ::      | 7001 |
| storage-1   | down   | ::      | 7002 |
| storage-2   | down   | ::      | 7003 |
+-------------+--------+---------+------+
[root@hp-gen9 ~]#

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ć):


firewall-cmd --zone=public --add-port=7001/udp --permanent
firewall-cmd --zone=public --add-port=7002/udp --permanent
firewall-cmd --zone=public --add-port=7003/udp --permanent
firewall-cmd --zone=public --add-port=7004/udp --permanent
firewall-cmd --zone=public --add-port=7005/udp --permanent
firewall-cmd --reload

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:


{
    "nodes":[
        {
            "mac":[
                "52:54:00:20:a2:2f"
            ],
            "cpu":"8",
            "memory":"32768",
            "disk":"60",
            "arch":"x86_64",
            "name":"control-1",
            "pm_type":"pxe_ipmitool",
            "pm_user":"admin",
            "pm_password":"admin",
            "pm_addr":"192.168.255.200",
            "pm_port":"7001"
        },
        {
            "mac":[
                "52:54:00:79:0b:cb"
            ],
            "cpu":"4",
            "memory":"16384",
            "disk":"160",
            "arch":"x86_64",
            "name":"storage-1",
            "pm_type":"pxe_ipmitool",
            "pm_user":"admin",
            "pm_password":"admin",
            "pm_addr":"192.168.255.200",
            "pm_port":"7002"
        },
        {
            "mac":[
                "52:54:00:a7:fe:27"
            ],
            "cpu":"4",
            "memory":"16384",
            "disk":"160",
            "arch":"x86_64",
            "name":"storage-2",
            "pm_type":"pxe_ipmitool",
            "pm_user":"admin",
            "pm_password":"admin",
            "pm_addr":"192.168.255.200",
            "pm_port":"7003"
        },
        {
            "mac":[
                "52:54:00:98:e9:d6"
            ],
            "cpu":"12",
            "memory":"32768",
            "disk":"60",
            "arch":"x86_64",
            "name":"compute-1",
            "pm_type":"pxe_ipmitool",
            "pm_user":"admin",
            "pm_password":"admin",
            "pm_addr":"192.168.255.200",
            "pm_port":"7004"
        },
        {
            "mac":[
                "52:54:00:6a:ea:be"
            ],
            "cpu":"12",
            "memory":"32768",
            "disk":"60",
            "arch":"x86_64",
            "name":"compute-2",
            "pm_type":"pxe_ipmitool",
            "pm_user":"admin",
            "pm_password":"admin",
            "pm_addr":"192.168.255.200",
            "pm_port":"7005"
        }
    ]
}

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 ~]$

Jeszcze jedno - musisz dodać serwer DNS:


(undercloud) [stack@undercloud ~]$ openstack subnet list
+--------------------------------------+-----------------+--------------------------------------+------------------+
| ID                                   | Name            | Network                              | Subnet           |
+--------------------------------------+-----------------+--------------------------------------+------------------+
| f45dea46-4066-42aa-a3c4-6f84b8120cab | ctlplane-subnet | 6ca013dc-41c2-42d8-9d69-542afad53392 | 192.168.255.0/24 |
+--------------------------------------+-----------------+--------------------------------------+------------------+
(undercloud) [stack@undercloud ~]$ openstack subnet show f45dea46-4066-42aa-a3c4-6f84b8120cab
+-------------------+-----------------------------------------------------------+
| Field             | Value                                                     |
+-------------------+-----------------------------------------------------------+
| allocation_pools  | 192.168.255.11-192.168.255.50                             |
| cidr              | 192.168.255.0/24                                          |
| created_at        | 2020-08-13T20:10:37Z                                      |
| description       |                                                           |
| dns_nameservers   |                                                           |
| enable_dhcp       | True                                                      |
| gateway_ip        | 192.168.255.1                                             |
| host_routes       | destination='169.254.169.254/32', gateway='192.168.255.1' |
| id                | f45dea46-4066-42aa-a3c4-6f84b8120cab                      |
| ip_version        | 4                                                         |
| ipv6_address_mode | None                                                      |
| ipv6_ra_mode      | None                                                      |
| name              | ctlplane-subnet                                           |
| network_id        | 6ca013dc-41c2-42d8-9d69-542afad53392                      |
| prefix_length     | None                                                      |
| project_id        | a844ccfcdb2745b198dde3e1b28c40a3                          |
| revision_number   | 0                                                         |
| segment_id        | None                                                      |
| service_types     |                                                           |
| subnetpool_id     | None                                                      |
| tags              |                                                           |
| updated_at        | 2020-08-13T20:10:37Z                                      |
+-------------------+-----------------------------------------------------------+
(undercloud) [stack@undercloud ~]$ 
(undercloud) [stack@undercloud ~]$ neutron subnet-update f45dea46-4066-42aa-a3c4-6f84b8120cab --dns-nameserver 192.168.255.253                                    
neutron CLI is deprecated and will be removed in the future. Use openstack CLI instead.
Updated subnet: f45dea46-4066-42aa-a3c4-6f84b8120cab
(undercloud) [stack@undercloud ~]$

Teraz możemy wydać polecenie introspekcji:

(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:


(undercloud) [stack@undercloud ~]$ openstack overcloud profiles list
+--------------------------------------+-----------+-----------------+-----------------+-------------------+
| Node UUID                            | Node Name | Provision State | Current Profile | Possible Profiles |
+--------------------------------------+-----------+-----------------+-----------------+-------------------+
| b4b2cf4a-b7ca-4095-af13-cc83be21c4f5 | control-1 | available       | None            |                   |
| b89a72a3-6bb7-429a-93bc-48393d225838 | storage-1 | available       | None            |                   |
| 20a16cc0-e0ce-4d88-8f17-eb0ce7b4d69e | storage-2 | available       | None            |                   |
| bfc1eb98-a17a-4a70-b0b6-6c0db0eac8e8 | compute-1 | available       | None            |                   |
| 766ab623-464c-423d-a529-d9afb69d1167 | compute-2 | available       | None            |                   |
+--------------------------------------+-----------+-----------------+-----------------+-------------------+
(undercloud) [stack@undercloud ~]$ openstack flavor list
+--------------------------------------+---------------+------+------+-----------+-------+-----------+
| ID                                   | Name          |  RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------------------------------------+---------------+------+------+-----------+-------+-----------+
| 168af640-7f40-42c7-91b2-989abc5c5d8f | swift-storage | 4096 |   40 |         0 |     1 | True      |
| 52148d1b-492e-48b4-b5fc-772849dd1b78 | baremetal     | 4096 |   40 |         0 |     1 | True      |
| 56e66542-ae60-416d-863e-0cb192d01b09 | control       | 4096 |   40 |         0 |     1 | True      |
| af6796e1-d0c4-4bfe-898c-532be194f7ac | block-storage | 4096 |   40 |         0 |     1 | True      |
| e4d50fdd-0034-446b-b72c-9da19b16c2df | compute       | 4096 |   40 |         0 |     1 | True      |
| fc2e3acf-7fca-4901-9eee-4a4d6ef0265d | ceph-storage  | 4096 |   40 |         0 |     1 | True      |
+--------------------------------------+---------------+------+------+-----------+-------+-----------+
(undercloud) [stack@undercloud ~]$

Określ profil dla każdego węzła:


openstack baremetal node set --property capabilities='profile:control,boot_option:local' b4b2cf4a-b7ca-4095-af13-cc83be21c4f5
openstack baremetal node set --property capabilities='profile:ceph-storage,boot_option:local' b89a72a3-6bb7-429a-93bc-48393d225838
openstack baremetal node set --property capabilities='profile:ceph-storage,boot_option:local' 20a16cc0-e0ce-4d88-8f17-eb0ce7b4d69e
openstack baremetal node set --property capabilities='profile:compute,boot_option:local' bfc1eb98-a17a-4a70-b0b6-6c0db0eac8e8
openstack baremetal node set --property capabilities='profile:compute,boot_option:local' 766ab623-464c-423d-a529-d9afb69d1167

Sprawdźmy, czy zrobiliśmy wszystko poprawnie:


(undercloud) [stack@undercloud ~]$ openstack overcloud profiles list
+--------------------------------------+-----------+-----------------+-----------------+-------------------+
| Node UUID                            | Node Name | Provision State | Current Profile | Possible Profiles |
+--------------------------------------+-----------+-----------------+-----------------+-------------------+
| b4b2cf4a-b7ca-4095-af13-cc83be21c4f5 | control-1 | available       | control         |                   |
| b89a72a3-6bb7-429a-93bc-48393d225838 | storage-1 | available       | ceph-storage    |                   |
| 20a16cc0-e0ce-4d88-8f17-eb0ce7b4d69e | storage-2 | available       | ceph-storage    |                   |
| bfc1eb98-a17a-4a70-b0b6-6c0db0eac8e8 | compute-1 | available       | compute         |                   |
| 766ab623-464c-423d-a529-d9afb69d1167 | compute-2 | available       | compute         |                   |
+--------------------------------------+-----------+-----------------+-----------------+-------------------+
(undercloud) [stack@undercloud ~]$

Jeśli wszystko się zgadza, wydajemy polecenie wdrożenia overcloud:

openstack overcloud deploy --templates --control-scale 1 --compute-scale 2  --ceph-storage-scale 2 --control-flavor control --compute-flavor compute  --ceph-storage-flavor ceph-storage --libvirt-type qemu

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:


2020-08-14 08:39:21Z [overcloud]: CREATE_COMPLETE  Stack CREATE completed successfully

 Stack overcloud CREATE_COMPLETE 

Host 192.168.255.21 not found in /home/stack/.ssh/known_hosts
Started Mistral Workflow tripleo.deployment.v1.get_horizon_url. Execution ID: fcb996cd-6a19-482b-b755-2ca0c08069a9
Overcloud Endpoint: http://192.168.255.21:5000/
Overcloud Horizon Dashboard URL: http://192.168.255.21:80/dashboard
Overcloud rc file: /home/stack/overcloudrc
Overcloud Deployed
(undercloud) [stack@undercloud ~]$

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

(overcloud) [stack@undercloud ~]$ nova show f53b37b5-2204-46cc-aef0-dba84bf970c0 | egrep "hypervisor_hostname|instance_name|hostname"
| OS-EXT-SRV-ATTR:hostname             | vm-1                                                     |
| OS-EXT-SRV-ATTR:hypervisor_hostname  | overcloud-novacompute-0.localdomain                      |
| OS-EXT-SRV-ATTR:instance_name        | instance-00000001                                        |
(overcloud) [stack@undercloud ~]$ nova show fc8b6722-0231-49b0-b2fa-041115bef34a | egrep "hypervisor_hostname|instance_name|hostname"
| OS-EXT-SRV-ATTR:hostname             | vm-2                                                     |
| OS-EXT-SRV-ATTR:hypervisor_hostname  | overcloud-novacompute-1.localdomain                      |
| OS-EXT-SRV-ATTR:instance_name        | instance-00000002                                        |
(overcloud) [stack@undercloud ~]$ nova show 3cd74455-b9b7-467a-abe3-bd6ff765c83c | egrep "hypervisor_hostname|instance_name|hostname"
| OS-EXT-SRV-ATTR:hostname             | vm-3                                                     |
| OS-EXT-SRV-ATTR:hypervisor_hostname  | overcloud-novacompute-0.localdomain                      |
| OS-EXT-SRV-ATTR:instance_name        | instance-00000003                                        |
(overcloud) [stack@undercloud ~]$ nova show 7e836338-6772-46b0-9950-f7f06dbe91a8 | egrep "hypervisor_hostname|instance_name|hostname"
| OS-EXT-SRV-ATTR:hostname             | vm-4                                                     |
| OS-EXT-SRV-ATTR:hypervisor_hostname  | overcloud-novacompute-1.localdomain                      |
| OS-EXT-SRV-ATTR:instance_name        | instance-00000004                                        |

(overcloud) [stack@undercloud ~]$
Maszyny vm-1 i vm-3 znajdują się w węźle obliczeniowym-0, maszyny vm-2 i vm-4 znajdują się w węźle obliczeniowym-1.

Dodatkowo utworzono router wirtualny umożliwiający routing pomiędzy określonymi sieciami:

(overcloud) [stack@undercloud ~]$ openstack router list  --project 5e18ce8ec9594e00b155485f19895e6c
+--------------------------------------+----------+--------+-------+-------------+-------+----------------------------------+
| ID                                   | Name     | Status | State | Distributed | HA    | Project                          |
+--------------------------------------+----------+--------+-------+-------------+-------+----------------------------------+
| 0a4d2420-4b9c-46bd-aec1-86a1ef299abe | router-1 | ACTIVE | UP    | False       | False | 5e18ce8ec9594e00b155485f19895e6c |
+--------------------------------------+----------+--------+-------+-------------+-------+----------------------------------+
(overcloud) [stack@undercloud ~]$ 

Router posiada dwa porty wirtualne, które pełnią rolę bram dla sieci:

(overcloud) [stack@undercloud ~]$ openstack router show 0a4d2420-4b9c-46bd-aec1-86a1ef299abe | grep interface
| interfaces_info         | [{"subnet_id": "2529ad1a-6b97-49cd-8515-cbdcbe5e3daa", "ip_address": "10.0.1.254", "port_id": "0c52b15f-8fcc-4801-bf52-7dacc72a5201"}, {"subnet_id": "335552dd-b35b-456b-9df0-5aac36a3ca13", "ip_address": "10.0.2.254", "port_id": "92fa49b5-5406-499f-ab8d-ddf28cc1a76c"}] |
(overcloud) [stack@undercloud ~]$ 

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.


[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-vsctl show
[heat-admin@overcloud-novacompute-0 ~]$ sudo sudo ovs-appctl dpif/show
system@ovs-system: hit:3 missed:3
  br-ex:
    br-ex 65534/1: (internal)
    phy-br-ex 1/none: (patch: peer=int-br-ex)
  br-int:
    br-int 65534/2: (internal)
    int-br-ex 1/none: (patch: peer=phy-br-ex)
    patch-tun 2/none: (patch: peer=patch-int)
  br-tun:
    br-tun 65534/3: (internal)
    patch-int 1/none: (patch: peer=patch-tun)
    vxlan-c0a8ff0f 3/4: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.19, remote_ip=192.168.255.15)
    vxlan-c0a8ff1a 2/4: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.19, remote_ip=192.168.255.26)
[heat-admin@overcloud-novacompute-0 ~]$

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.

Wprowadzenie do sieciowej części infrastruktury chmurowej

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.


[heat-admin@overcloud-novacompute-0 ~]$ ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 192.168.255.19  netmask 255.255.255.0  broadcast 192.168.255.255
        inet6 fe80::5054:ff:fe6a:eabe  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:6a:ea:be  txqueuelen 1000  (Ethernet)
        RX packets 2909669  bytes 4608201000 (4.2 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1821057  bytes 349198520 (333.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[heat-admin@overcloud-novacompute-0 ~]$ 

Jak widać na wyjściu, adres jest przykręcony bezpośrednio do portu fizycznego, a nie do interfejsu mostu wirtualnego.


[heat-admin@overcloud-novacompute-0 ~]$  sudo ovs-appctl fdb/show br-ex
 port  VLAN  MAC                Age
[heat-admin@overcloud-novacompute-0 ~]$  sudo ovs-ofctl dump-flows br-ex
 cookie=0x9169eae8f7fe5bb2, duration=216686.864s, table=0, n_packets=303, n_bytes=26035, priority=2,in_port="phy-br-ex" actions=drop
 cookie=0x9169eae8f7fe5bb2, duration=216686.887s, table=0, n_packets=0, n_bytes=0, priority=0 actions=NORMAL
[heat-admin@overcloud-novacompute-0 ~]$ 

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.


[heat-admin@overcloud-controller-0 ~]$ sudo ovs-appctl dpif/show
system@ovs-system: hit:930491 missed:825
  br-ex:
    br-ex 65534/1: (internal)
    eth0 1/2: (system)
    phy-br-ex 2/none: (patch: peer=int-br-ex)
  br-int:
    br-int 65534/3: (internal)
    int-br-ex 1/none: (patch: peer=phy-br-ex)
    patch-tun 2/none: (patch: peer=patch-int)
  br-tun:
    br-tun 65534/4: (internal)
    patch-int 1/none: (patch: peer=patch-tun)
    vxlan-c0a8ff13 3/5: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.15, remote_ip=192.168.255.19)
    vxlan-c0a8ff1a 2/5: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.15, remote_ip=192.168.255.26)
[heat-admin@overcloud-controller-0 ~]$

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.


[heat-admin@overcloud-controller-0 ~]$ ifconfig br-ex
br-ex: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 192.168.255.15  netmask 255.255.255.0  broadcast 192.168.255.255
        inet6 fe80::5054:ff:fe20:a22f  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:20:a2:2f  txqueuelen 1000  (Ethernet)
        RX packets 803859  bytes 1732616116 (1.6 GiB)
        RX errors 0  dropped 63  overruns 0  frame 0
        TX packets 808475  bytes 121652156 (116.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[heat-admin@overcloud-controller-0 ~]$ 
[heat-admin@overcloud-controller-0 ~]$ sudo ovs-appctl fdb/show br-ex
 port  VLAN  MAC                Age
    3   100  28:c0:da:00:4d:d3   35
    1     0  28:c0:da:00:4d:d3   35
    1     0  52:54:00:98:e9:d6    0
LOCAL     0  52:54:00:20:a2:2f    0
    1     0  52:54:00:2c:08:9e    0
    3   100  52:54:00:20:a2:2f    0
    1     0  52:54:00:6a:ea:be    0
[heat-admin@overcloud-controller-0 ~]$ 

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.

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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.


[heat-admin@overcloud-novacompute-0 ~]$ sudo sudo ovs-appctl dpif/show
system@ovs-system: hit:526 missed:91
  br-ex:
    br-ex 65534/1: (internal)
    phy-br-ex 1/none: (patch: peer=int-br-ex)
  br-int:
    br-int 65534/2: (internal)
    int-br-ex 1/none: (patch: peer=phy-br-ex)
    patch-tun 2/none: (patch: peer=patch-int)
    qvo5bd37136-47 6/6: (system)
    qvo95d96a75-a0 3/5: (system)
  br-tun:
    br-tun 65534/3: (internal)
    patch-int 1/none: (patch: peer=patch-tun)
    vxlan-c0a8ff0f 3/4: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.19, remote_ip=192.168.255.15)
    vxlan-c0a8ff1a 2/4: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.19, remote_ip=192.168.255.26)
[heat-admin@overcloud-novacompute-0 ~]$ 

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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:

[heat-admin@overcloud-novacompute-0 ~]$  sudo ovs-appctl fdb/show br-int | grep fa:16:3e:72:ad:53
    2     1  fa:16:3e:72:ad:53    1
[heat-admin@overcloud-novacompute-0 ~]

Ruch powinien iść do portu 2 - zobaczmy, jaki to port:

[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-ofctl show br-int | grep addr
 1(int-br-ex): addr:7e:7f:28:1f:bd:54
 2(patch-tun): addr:0a:bd:07:69:58:d9
 3(qvo95d96a75-a0): addr:ea:50:9a:3d:69:58
 6(qvo5bd37136-47): addr:9a:d1:03:50:3d:96
 LOCAL(br-int): addr:1a:0f:53:97:b1:49
[heat-admin@overcloud-novacompute-0 ~]$

To jest patch-tun - czyli interfejs w br-tun. Zobaczmy, co stanie się z pakietem na br-tun:

[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-ofctl dump-flows br-tun | grep fa:16:3e:72:ad:53
 cookie=0x8759a56536b67a8e, duration=1387.959s, table=20, n_packets=1460, n_bytes=138880, hard_timeout=300, idle_age=0, hard_age=0, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:72:ad:53 actions=load:0->NXM_OF_VLAN_TCI[],load:0x16->NXM_NX_TUN_ID[],output:2
[heat-admin@overcloud-novacompute-0 ~]$ 

Pakiet jest pakowany w VxLAN i wysyłany do portu 2. Zobaczmy dokąd prowadzi port 2:

[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-ofctl show br-tun | grep addr   
 1(patch-int): addr:b2:d1:f8:21:96:66
 2(vxlan-c0a8ff1a): addr:be:64:1f:75:78:a7
 3(vxlan-c0a8ff0f): addr:76:6f:b9:3c:3f:1c
 LOCAL(br-tun): addr:a2:5b:6d:4f:94:47
[heat-admin@overcloud-novacompute-0 ~]$

To jest tunel vxlan na komputerze-1:

[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-appctl dpif/show | egrep vxlan-c0a8ff1a
    vxlan-c0a8ff1a 2/4: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.19, remote_ip=192.168.255.26)
[heat-admin@overcloud-novacompute-0 ~]$

Przejdźmy do compute-1 i zobaczmy, co stanie się dalej z pakietem:

[heat-admin@overcloud-novacompute-1 ~]$ sudo ovs-appctl fdb/show br-int | egrep fa:16:3e:44:98:20
    2     1  fa:16:3e:44:98:20    1
[heat-admin@overcloud-novacompute-1 ~]$ 

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:

[heat-admin@overcloud-novacompute-1 ~]$ sudo ovs-ofctl show br-int | grep addr   
 1(int-br-ex): addr:8a:d7:f9:ad:8c:1d
 2(patch-tun): addr:46:cc:40:bd:20:da
 3(qvoe7e23f1b-07): addr:12:78:2e:34:6a:c7
 4(qvo3210e8ec-c0): addr:7a:5f:59:75:40:85
 LOCAL(br-int): addr:e2:27:b2:ed:14:46

Cóż, wtedy widzimy, że w br-int na compute-1 znajduje się mak docelowy:

[heat-admin@overcloud-novacompute-1 ~]$ sudo ovs-appctl fdb/show br-int | egrep fa:16:3e:72:ad:53
    3     1  fa:16:3e:72:ad:53    0
[heat-admin@overcloud-novacompute-1 ~]$ 

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:

[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-appctl fdb/show br-int | egrep fa:16:3e:c4:64:70
    2     1  fa:16:3e:c4:64:70    0
[heat-admin@overcloud-novacompute-0 ~]$ 

Spójrzmy, dokąd prowadzi port 2:

[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-ofctl show br-int | grep addr
 1(int-br-ex): addr:7e:7f:28:1f:bd:54
 2(patch-tun): addr:0a:bd:07:69:58:d9
 3(qvo95d96a75-a0): addr:ea:50:9a:3d:69:58
 6(qvo5bd37136-47): addr:9a:d1:03:50:3d:96
 LOCAL(br-int): addr:1a:0f:53:97:b1:49
[heat-admin@overcloud-novacompute-0 ~]$ 

Wszystko jest logiczne, ruch idzie do br-tun. Zobaczmy, w który tunel vxlan zostanie owinięty:

[heat-admin@overcloud-novacompute-0 ~]$ sudo ovs-ofctl dump-flows br-tun | grep fa:16:3e:c4:64:70
 cookie=0x8759a56536b67a8e, duration=3514.566s, table=20, n_packets=3368, n_bytes=317072, hard_timeout=300, idle_age=0, hard_age=0, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:c4:64:70 actions=load:0->NXM_OF_VLAN_TCI[],load:0x16->NXM_NX_TUN_ID[],output:3
[heat-admin@overcloud-novacompute-0 ~]$ 

Trzeci port to tunel vxlan:

[heat-admin@overcloud-controller-0 ~]$ sudo ovs-ofctl show br-tun | grep addr
 1(patch-int): addr:a2:69:00:c5:fa:ba
 2(vxlan-c0a8ff1a): addr:86:f0:ce:d0:e8:ea
 3(vxlan-c0a8ff13): addr:72:aa:73:2c:2e:5b
 LOCAL(br-tun): addr:a6:cb:cd:72:1c:45
[heat-admin@overcloud-controller-0 ~]$ 

Który patrzy na węzeł kontrolny:

[heat-admin@overcloud-controller-0 ~]$ sudo sudo ovs-appctl dpif/show | grep vxlan-c0a8ff1a
    vxlan-c0a8ff1a 2/5: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.15, remote_ip=192.168.255.26)
[heat-admin@overcloud-controller-0 ~]$ 

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:

[heat-admin@overcloud-controller-0 ~]$ sudo ovs-appctl fdb/show br-int | grep fa:16:3e:c4:64:70
    5     1  fa:16:3e:c4:64:70    1
[heat-admin@overcloud-controller-0 ~]$ 
[heat-admin@overcloud-controller-0 ~]$  sudo ovs-ofctl show br-int | grep addr
 1(int-br-ex): addr:2e:58:b6:db:d5:de
 2(patch-tun): addr:06:41:90:f0:9e:56
 3(tapca25a97e-64): addr:fa:16:3e:e6:2c:5c
 4(tap22015e46-0b): addr:fa:16:3e:76:c2:11
 5(qr-0c52b15f-8f): addr:fa:16:3e:c4:64:70
 6(qr-92fa49b5-54): addr:fa:16:3e:80:13:72
 LOCAL(br-int): addr:06:de:5d:ed:44:44
[heat-admin@overcloud-controller-0 ~]$ 

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:

[heat-admin@overcloud-controller-0 ~]$ sudo  ip netns
qrouter-0a4d2420-4b9c-46bd-aec1-86a1ef299abe (id: 2)
qdhcp-7d541e74-1c36-4e1d-a7c4-0968c8dbc638 (id: 1)
qdhcp-67a3798c-32c0-4c18-8502-2531247e3cc2 (id: 0)
[heat-admin@overcloud-controller-0 ~]$ 

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.

[heat-admin@overcloud-controller-0 ~]$ sudo  ip netns exec qrouter-0a4d2420-4b9c-46bd-aec1-86a1ef299abe ifconfig qr-0c52b15f-8f
qr-0c52b15f-8f: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.0.1.254  netmask 255.255.255.0  broadcast 10.0.1.255
        inet6 fe80::f816:3eff:fec4:6470  prefixlen 64  scopeid 0x20<link>
        ether fa:16:3e:c4:64:70  txqueuelen 1000  (Ethernet)
        RX packets 5356  bytes 427305 (417.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5195  bytes 490603 (479.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[heat-admin@overcloud-controller-0 ~]$ 

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:

[heat-admin@overcloud-controller-0 ~]$ sudo ovs-appctl fdb/show br-int | grep fa:16:3e:6c:ad:9c
    2     2  fa:16:3e:6c:ad:9c    1
[heat-admin@overcloud-controller-0 ~]$ 
[heat-admin@overcloud-controller-0 ~]$ sudo ovs-ofctl show br-int | grep addr
 1(int-br-ex): addr:2e:58:b6:db:d5:de
 2(patch-tun): addr:06:41:90:f0:9e:56
 3(tapca25a97e-64): addr:fa:16:3e:e6:2c:5c
 4(tap22015e46-0b): addr:fa:16:3e:76:c2:11
 5(qr-0c52b15f-8f): addr:fa:16:3e:c4:64:70
 6(qr-92fa49b5-54): addr:fa:16:3e:80:13:72
 LOCAL(br-int): addr:06:de:5d:ed:44:44
[heat-admin@overcloud-controller-0 ~]$ 

Zgodnie z oczekiwaniami ruch idzie do br-tun, zobaczmy, do którego tunelu trafi dalej:

[heat-admin@overcloud-controller-0 ~]$ sudo ovs-ofctl dump-flows br-tun | grep fa:16:3e:6c:ad:9c
 cookie=0x2ab04bf27114410e, duration=5346.829s, table=20, n_packets=5248, n_bytes=498512, hard_timeout=300, idle_age=0, hard_age=0, priority=1,vlan_tci=0x0002/0x0fff,dl_dst=fa:16:3e:6c:ad:9c actions=load:0->NXM_OF_VLAN_TCI[],load:0x63->NXM_NX_TUN_ID[],output:2
[heat-admin@overcloud-controller-0 ~]$
[heat-admin@overcloud-controller-0 ~]$ sudo ovs-ofctl show br-tun | grep addr
 1(patch-int): addr:a2:69:00:c5:fa:ba
 2(vxlan-c0a8ff1a): addr:86:f0:ce:d0:e8:ea
 3(vxlan-c0a8ff13): addr:72:aa:73:2c:2e:5b
 LOCAL(br-tun): addr:a6:cb:cd:72:1c:45
[heat-admin@overcloud-controller-0 ~]$ 
[heat-admin@overcloud-controller-0 ~]$ sudo sudo ovs-appctl dpif/show | grep vxlan-c0a8ff1a
    vxlan-c0a8ff1a 2/5: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.15, remote_ip=192.168.255.26)
[heat-admin@overcloud-controller-0 ~]$ 

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:

[heat-admin@overcloud-controller-0 ~]$ sudo sudo ovs-appctl dpif/show | grep vxlan-c0a8ff1a
    vxlan-c0a8ff1a 2/5: (vxlan: egress_pkt_mark=0, key=flow, local_ip=192.168.255.15, remote_ip=192.168.255.26)
[heat-admin@overcloud-controller-0 ~]$ 
[heat-admin@overcloud-novacompute-1 ~]$ sudo ovs-appctl fdb/show br-int | grep fa:16:3e:6c:ad:9c
    4     2  fa:16:3e:6c:ad:9c    1
[heat-admin@overcloud-novacompute-1 ~]$ sudo ovs-ofctl show br-int | grep addr                  
 1(int-br-ex): addr:8a:d7:f9:ad:8c:1d
 2(patch-tun): addr:46:cc:40:bd:20:da
 3(qvoe7e23f1b-07): addr:12:78:2e:34:6a:c7
 4(qvo3210e8ec-c0): addr:7a:5f:59:75:40:85
 LOCAL(br-int): addr:e2:27:b2:ed:14:46
[heat-admin@overcloud-novacompute-1 ~]$ 

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:

Wprowadzenie do sieciowej części infrastruktury chmurowej

Wygląda na to, że to wszystko? Zapomnieliśmy o dwóch przestrzeniach nazw:

[heat-admin@overcloud-controller-0 ~]$ sudo  ip netns
qrouter-0a4d2420-4b9c-46bd-aec1-86a1ef299abe (id: 2)
qdhcp-7d541e74-1c36-4e1d-a7c4-0968c8dbc638 (id: 1)
qdhcp-67a3798c-32c0-4c18-8502-2531247e3cc2 (id: 0)
[heat-admin@overcloud-controller-0 ~]$ 

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:

[heat-admin@overcloud-controller-0 ~]$ sudo ip netns exec qdhcp-67a3798c-32c0-4c18-8502-2531247e3cc2 ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1  bytes 28 (28.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1  bytes 28 (28.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tapca25a97e-64: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.0.1.1  netmask 255.255.255.0  broadcast 10.0.1.255
        inet6 fe80::f816:3eff:fee6:2c5c  prefixlen 64  scopeid 0x20<link>
        ether fa:16:3e:e6:2c:5c  txqueuelen 1000  (Ethernet)
        RX packets 129  bytes 9372 (9.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 49  bytes 6154 (6.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Zobaczmy, czy procesy zawierające w węźle kontrolnym qdhcp-67a3798c-32c0-4c18-8502-2531247e3cc2:


[heat-admin@overcloud-controller-0 ~]$ ps -aux | egrep qdhcp-7d541e74-1c36-4e1d-a7c4-0968c8dbc638 
root      640420  0.0  0.0   4220   348 ?        Ss   11:31   0:00 dumb-init --single-child -- ip netns exec qdhcp-7d541e74-1c36-4e1d-a7c4-0968c8dbc638 /usr/sbin/dnsmasq -k --no-hosts --no-resolv --pid-file=/var/lib/neutron/dhcp/7d541e74-1c36-4e1d-a7c4-0968c8dbc638/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/7d541e74-1c36-4e1d-a7c4-0968c8dbc638/host --addn-hosts=/var/lib/neutron/dhcp/7d541e74-1c36-4e1d-a7c4-0968c8dbc638/addn_hosts --dhcp-optsfile=/var/lib/neutron/dhcp/7d541e74-1c36-4e1d-a7c4-0968c8dbc638/opts --dhcp-leasefile=/var/lib/neutron/dhcp/7d541e74-1c36-4e1d-a7c4-0968c8dbc638/leases --dhcp-match=set:ipxe,175 --local-service --bind-dynamic --dhcp-range=set:subnet-335552dd-b35b-456b-9df0-5aac36a3ca13,10.0.2.0,static,255.255.255.0,86400s --dhcp-option-force=option:mtu,1450 --dhcp-lease-max=256 --conf-file= --domain=openstacklocal
heat-ad+  951620  0.0  0.0 112944   980 pts/0    S+   18:50   0:00 grep -E --color=auto qdhcp-7d541e74-1c36-4e1d-a7c4-0968c8dbc638
[heat-admin@overcloud-controller-0 ~]$ 

Jest taki proces i na podstawie informacji przedstawionych w powyższym wyjściu możemy np. zobaczyć co aktualnie mamy do wynajęcia:

[heat-admin@overcloud-controller-0 ~]$ cat /var/lib/neutron/dhcp/7d541e74-1c36-4e1d-a7c4-0968c8dbc638/leases
1597492111 fa:16:3e:6c:ad:9c 10.0.2.8 host-10-0-2-8 01:fa:16:3e:6c:ad:9c
1597491115 fa:16:3e:76:c2:11 10.0.2.1 host-10-0-2-1 *
[heat-admin@overcloud-controller-0 ~]$

W rezultacie otrzymujemy następujący zestaw usług w węźle sterującym:

Wprowadzenie do sieciowej części infrastruktury chmurowej

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ć.

Źródło: www.habr.com

Dodaj komentarz