Detailní nastavení směrování pro MetalLB v režimu L2

Detailní nastavení směrování pro MetalLB v režimu L2
Nedávno jsem se setkal s poněkud nestandardním úkolem nastavení routování pro MetalLB. Nic by to nebylo, protože obvykle pro MetalLB není potřeba žádných dalších akcí, ale v našem případě máme dost velký klastr s poměrně jednoduchou konfigurací sítě.

V tomto článku vám ukážu, jak nastavit routování na základě zdroje a zásady pro externí síť vašeho klastru.

Nebudu se detailně zabývat instalací a nastavením MetalLB, protože předpokládám, že již máte nějaké zkušenosti. Navrhuji přejít rovnou k věci, a to k nastavení routování. Máme čtyři případy:

Případ 1: Když nastavení není potřeba

Podíváme se na jednoduchý případ.

Detailní nastavení směrování pro MetalLB v režimu L2

Další nastavení routování není potřeba, když adresy vydávané MetalLB jsou ve stejné podsíti jako adresy vašich uzlů.

Například máte podsíť 192.168.1.0/24, v níž je směrovač 192.168.1.1, a vaše uzly získávají adresy: 192.168.1.10-30, pak pro MetalLB můžete nastavit rozsah 192.168.1.100-120 a být si jisti, že budou fungovat bez jakéhokoli dalšího nastavení.

Proč tomu tak je? Protože vaše uzly již mají nastavené trasy:

# ip route
default via 192.168.1.1 dev eth0 onlink 
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10

A adresy ze stejného rozsahu je budou znovu používat bez jakýchkoli dalších kroků.

Případ 2: Když je potřeba další nastavení

Detailní nastavení směrování pro MetalLB v režimu L2

Měli byste nastavit další trasy vždy, když vaše uzly nemají nastaveno IP adres nebo trasu do podsítě, pro kterou MetalLB vydává adresy.

Vysvětlím to podrobněji. Kdykoli MetalLB vydá adresu, dá se to přirovnat k jednoduchému přiřazení typu:

ip addr add 10.9.8.7/32 dev lo

Všimněte si:

  • a) Adresa je přiřazena s prefixem /32 to znamená, že do ní nebude automaticky přidán žádný routovací záznam (to je prostě adresa)
  • b) Adresa je nastavena na jakékoli rozhraní uzlu (například na loopback). Je třeba zmínit zvláštnosti síťového zásobníku Linuxu. Nezáleží na tom, na které rozhraní adresu přidáte, jádro vždy zpracovává arp dotazy a odesílá arp odpovědi na jakékoli z nich, toto chování je považováno za správné a navíc se v dynamickém prostředí, jakým je Kubernetes, používá dost široce.

Toto chování lze nastavit, například povolením strict arp:

echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

V tomto případě budou arp-odpovědi odesílány pouze v případě, že rozhraní výslovně obsahuje konkrétní IP adresu. Toto nastavení je povinné, pokud plánujete používat MetalLB a váš kube-proxy pracuje v režimu IPVS.

MetalLB však pro zpracování arp-dotazů nepoužívá jádro, ale dělá to samostatně v uživatelském prostoru, takže tato volba nebude mít vliv na práci MetalLB.

Vraťme se k našemu úkolu. Pokud neexistuje trasa pro přidělované adresy na vašich uzlech, přidejte ji předem na všechny uzly:

ip route add 10.9.8.0/24 dev eth1

Případ 3: Kdy bude potřeba routování založené na zdroji

Routování založené na zdroji budete potřebovat nastavit tehdy, když přijímáte pakety přes samostatnou bránu, která není ta, která je nastavena jako výchozí, a podle toho musí odpovědní pakety také jít přes tuto bránu.

Například máte stále tu samou podsíť 192.168.1.0/24 vyčleněnou pro vaše uzly, ale chcete přidělovat externí adresy pomocí MetalLB. Předpokládejme, že máte několik adres z podsítě 1.2.3.0/24 umístěných ve VLAN 100 a chcete je používat pro přístup ke Kubernetes službám zvenčí.

Detailní nastavení směrování pro MetalLB v režimu L2

Při přístupu na 1.2.3.4 budete provádět dotazy z jiné podsítě než 1.2.3.0/24 a očekávat odpověď. Uzlu, který je v tuto chvíli mistrem pro přidělenou adresu MetalLB 1.2.3.4, obdrží paket od směrovače 1.2.3.1, ale odpověď na něj musí nutně odejít stejnou cestou, přes 1.2.3.1.

Jelikož náš uzel již má nastavený default gateway 192.168.1.1, pak odpověď půjde výchozím směrem, tedy k němu, a ne k 1.2.3.1, přes který jsme obdrželi paket.

Jak se s touto situací vyrovnat?

V tomto případě je třeba připravit všechny vaše uzly tak, aby byly schopny obsluhovat externí adresy bez dalšího nastavení. To znamená, že pro výše uvedený příklad potřebujete předem vytvořit VLAN rozhraní na uzlu:

ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 up

A pak přidat trasy:

ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100

Všimněte si, že trasy přidáváme do samostatné tabulky routování 100 bude obsahovat pouze dvě trasy potřebné pro odesílání odpovědního paketu přes bránu 1.2.3.1, která se nachází za rozhraním eth0.100.

Nyní je potřeba přidat jednoduché pravidlo:

ip rule add from 1.2.3.0/24 lookup 100

které výslovně říká: pokud je zdrojová adresa paketu v 1.2.3.0/24, pak je třeba použít tabulku routování 100. V ní už máme popsánu trasu, která jej odešle přes 1.2.3.1

Příklad 4: Kdy bude potřeba směrování na základě politiky

Topologie sítě jako v předchozím příkladu, ale předpokládejme, že chcete mít také možnost přistupovat k externím adresám poolu 1.2.3.0/24 z vašich podů:

Detailní nastavení směrování pro MetalLB v režimu L2

Specifikum spočívá v tom, že při přístupu k jakékoli adrese v 1.2.3.0/24, odpovědní paket, dostávající se na uzel a mající adresu zdroje v rozsahu 1.2.3.0/24 bude poslušně odeslán do eth0.100, ale my chceme, aby Kubernetes přesměroval jej do našeho prvního podu, který původně vytvořil dotaz.

Vyřešení této problémy se ukázalo být obtížné, ale stalo se to možné díky směrování na základě politiky:

Pro lepší porozumění procesu uvedu blokovou schéma netfilter:
Detailní nastavení směrování pro MetalLB v režimu L2

Nejprve, jako v předchozím příkladu, vytvoříme další směrovací tabulku:

ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100

Teď přidáme několik pravidel do iptables:

iptables -t mangle -A PREROUTING -i eth0.100 -j CONNMARK --set-mark 0x100
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j RETURN
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

Tato pravidla budou označovat příchozí připojení na rozhraní eth0.100, označujíc všechny pakety tagem 0x100, tímto tagem budou označeny i odpovědi v rámci jednoho připojení.

Teď můžeme přidat směrovací pravidlo:

ip rule add from 1.2.3.0/24 fwmark 0x100 lookup 100

To znamená, že všechny pakety se zdrojovou adresou 1.2.3.0/24 a tagem 0x100 by měly být směrovány pomocí tabulky 100.

Tímto způsobem jiné pakety, získané na jiném rozhraní, do tohoto pravidla nepatří, což jim umožní být směrovány standardními prostředky Kubernetes.

Existuje ještě jedno, ale, v Linuxu existuje takzvaný filtr zpětné cesty, který kazí celou legraci, provádí jednoduchou kontrolu: pro všechny příchozí pakety mění adresu zdroje paketu na adresu odesílatele a kontroluje, zda může paket projít stejným rozhraním, na které byl přijat, pokud ne, pak jej filtruje.

Problém je v tom, že v našem případě bude fungovat nesprávně, ale můžeme jej vypnout:

echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0.100/rp_filter

Všimněte si, že první příkaz ovládá globální chování rp_filter, pokud jej nevypnete, pak druhý příkaz nebude mít žádný efekt. Nicméně ostatní rozhraní zůstanou se zapnutým rp_filter.

Abychom neomezovali činnost filtru úplně, můžeme využít implementaci rp_filter pro netfilter. Použitím rp_filter jako modulu iptables můžeme nastavit dostatečně flexibilní pravidla, například:

iptables -t raw -A PREROUTING -i eth0.100 -d 1.2.3.0/24 -j RETURN
iptables -t raw -A PREROUTING -i eth0.100 -m rpfilter --invert -j DROP

povolí rp_filter na rozhraní eth0.100 pro všechny adresy kromě 1.2.3.0/24.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster