Dziś bierzemy na tapetę przestrzenie nazw w kernelu Linux. To feature jądra Linux, który pozwala na izolację i wirtualizację zasobów systemowych. Namespaces pozwalają tworzyć wiele swoich instancji, które koegzystują na jednej maszynie linuxowej nie konfliktując się wzajemnie. Przestrzenie nazw sprawiają, że możliwa jest całkowita separacja sieci – routingu, iptables i interfejsów sieciowych. Zobaczcie jak wygląda to w naszym ulubionym systemie.
Te specjalne właściwości namespaces są wykorzystywane między innymi w OpenStack’u. Dzięki nim użytkownicy chmury, są w stanie tworzyć swoje własne sieci, nie bojąc się, że będą one w konflikcie (nazwa, zakres, maska) z inną siecią utworzoną przez innego użytkownika tego samego OpenStakck’a w innym tenancie. OpenStack wykorzystuje przestrzenie nazw dzięki projektowi Neutron i jego agentom. To one dostarczają wiele niezależnych wirtualnych routerów na każdym z nodów, które nie konfliktują się ze sobą nawzajem, dzięki wykorzystaniu przestrzeni nazw. OpenStack Neutron agent L2 i L3 dzięki namespaces tworzą przestrzenie dla serwera DHCP i przestrzeń dla routera. Bardzo dobrze pokazuje to rysunek poniżej:
Na tym rusunku widać cztery przestrzenie nazw, dwie dla DHCP o nazwach zaczynających się na qdhcp i dwie dla routera, o nazwach zaczynających się na qrouter. Każdy z procesów DHCP dostarcza adresację IP dla swojej podsieci wirtualnej, a każdy z routerów dokonuje przesyłania pakietów z tych sieci do sieci zewnętrznej. Rysunek poniżej pokazuje takie rozwiązanie w widoku sieci z OpenStack Horizon. Mamy tu dwa routery (qrouter w rysunku powyżej) i dwie sieci wewnętrzne z DHCP (qdhcp w rysunku powyżej).
W tym miejscu warto zaznaczyć również, że namespaces są kreowane tylko wtedy kiedy pojawia się jakaś aktywność w sieci. Otóż, przestrzeń dla DHCP jest kreowana tylko kiedy pojawi się maszyna wirtualna, która będzie potrzebowała pobrać adres IP z przydzielonego dla jej sieci serwera DHCP. Podobnie jest z przestrzenią dla routera. Ta też pojawi się tylko wówczas, gdy zostanie ustawiona brama z danej podsieci do innej sieci. Jeśli nasz tenant nie posiada bramy, to przestrzeń dla routera nie jest tworzona.
Pobawmy się teraz sami przestrzeniami nazw. Zrobimy małe ćwiczenie, które zademonstruje nam w jaki sposób OpenStack korzysta z tego rozwiązania, by odizolować od siebie różne sieci. Zaczynamy…
Naszym celem będzie utworzenie architektury jak na poniższym rysunku.
W naszym małym labie utworzymy zatem:
a) dwie przestrzenie nazw
[local-ns1 i local-ns2]
b) linuxowy bridge, którym będziemy łączyć nasze namespaces
[br-ns]
c) dwie pary wirtualnych kabli sieciowych Veth, które posłużą nam do połączeń instancji namespaces z bridge’m
[tap1br-tap1 i tap2br-tap2]
Wirtualny kabel ethernet składa się z dwóch wirtualnych wtyczek. Jedną wepniemy do naszego namespace, a druga do bridge’a. By ułatwić zrozumienie co gdzie wpinamy posłuzyłem się nazwami, które sugerują, która strona „kabla” będzie wpięta do bridge, a która do namespace.
Zaglądamy w możliwości instrukcji ip. Szczególnie w opcję ip netns exec 😉 ip netns help
Tworzymy dwie przestrzenie nazw:
ip netns add local-ns1
ip netns add local-ns2
Dodajemy bridge:
brctl addbr br-ns
ip link set up dev br-ns
Tworzymy wirtualne kable ethernet:
ip link add tap1 type veth peer name br-tap1
ip link add tap2 type veth peer name br-tap2
Podłączamy końcówki o nazwie br-tapX do bridge’a:
brctl addif br-ns br-tap1
brctl addif br-ns br-tap2
Podłączamy końcówki o nazwie tapX do namespaces:
ip link set tap1 netns local-ns1
ip link set tap2 netns local-ns2
Podnosimy wszystkie wpięte interfejsy:
ip link set up dev br-tap1
ip link set up dev br-tap2
ip netns exec local-ns1 ip link set dev tap1 up
ip netns exec local-ns2 ip link set dev tap2 up
Nadajemy adresy IP dla wpiętych w namespaces interfejsów TAP:
ip netns exec local-ns1 ip addr add 192.168.10.5/24 dev tap1
ip netns exec local-ns2 ip addr add 192.168.10.15/24 dev tap2
Test naszego rozwiązania. Zobaczmy czy przestrzenie widza się między sobą:
ip netns exec local-ns1 ip route sh
ip netns exec local-ns1 ping -c 3 192.168.10.15
ip netns exec local-ns2 iptables -I INPUT 1 -p ICMP -j DROP
ip netns exec local-ns2 iptables -L
ip netns exec local-ns1 ping -w 3 192.168.10.15
Możecie również „wejść” do przestrzeni nazw i wykonać te same instrukcje z wnętrza, już bez ip netns… np.:
ip netns exec local-ns1 bash
ip a
ping -c 3 192.168.10.15
Po więcej informacji zapraszamy na szkolenie CL310, gdzie porusza się dogłębnie problematykę sieci w OpenStack i omawia integrację z Ceph Storage.