Jemné doladenie smerovania pre MetalLB v režime L2

Jemné doladenie smerovania pre MetalLB v režime L2
Nie je to tak dávno, čo som stál pred veľmi nezvyčajnou úlohou nastaviť smerovanie pre MetalLB. Všetko by bolo v poriadku, pretože... MetalLB zvyčajne nevyžaduje žiadne ďalšie akcie, ale v našom prípade máme pomerne veľký klaster s veľmi jednoduchou konfiguráciou siete.

V tomto článku vám poviem, ako nakonfigurovať smerovanie založené na zdroji a politike pre externú sieť vášho klastra.

Nebudem zachádzať do detailov o inštalácii a konfigurácii MetalLB, keďže predpokladám, že už máte nejaké skúsenosti. Navrhujem ísť priamo k veci, konkrétne k nastaveniu smerovania. Takže máme štyri prípady:

Prípad 1: Keď nie je potrebná žiadna konfigurácia

Pozrime sa na jednoduchý prípad.

Jemné doladenie smerovania pre MetalLB v režime L2

Dodatočná konfigurácia smerovania nie je potrebná, keď sú adresy vydané MetalLB v rovnakej podsieti ako adresy vašich uzlov.

Napríklad máte podsieť 192.168.1.0/24, má router 192.168.1.1a vaše uzly dostanú adresy: 192.168.1.10-30, potom pre MetalLB môžete upraviť rozsah 192.168.1.100-120 a uistite sa, že budú fungovať bez akejkoľvek ďalšej konfigurácie.

prečo je to tak? Pretože vaše uzly už majú nakonfigurované 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 z rovnakého rozsahu ich znova použijú bez akýchkoľvek ďalších akcií.

Prípad 2: Keď je potrebné ďalšie prispôsobenie

Jemné doladenie smerovania pre MetalLB v režime L2

Mali by ste nakonfigurovať ďalšie trasy vždy, keď vaše uzly nemajú nakonfigurovanú IP adresu alebo smerovanie do podsiete, pre ktorú MetalLB vydáva adresy.

Vysvetlím trochu podrobnejšie. Kedykoľvek MetalLB odošle adresu, dá sa to prirovnať k jednoduchému priradeniu ako:

ip addr add 10.9.8.7/32 dev lo

Dávaj pozor na:

  • a) Adresa je priradená s predponou /32 to znamená, že trasa nebude automaticky pridaná do podsiete (je to len adresa)
  • b) Adresa je pripojená k ľubovoľnému rozhraniu uzla (napríklad spätnej slučke). Tu stojí za zmienku vlastnosti sieťového zásobníka Linuxu. Bez ohľadu na to, do akého rozhrania pridáte adresu, jadro vždy spracuje požiadavky arp a odošle odpovede arp na ktorúkoľvek z nich, toto správanie sa považuje za správne a navyše je pomerne široko používané v dynamickom prostredí, akým je Kubernetes.

Toto správanie je možné prispôsobiť, napríklad povolením striktného arp:

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

V tomto prípade budú odpovede arp odoslané iba vtedy, ak rozhranie explicitne obsahuje konkrétnu IP adresu. Toto nastavenie je potrebné, ak plánujete používať MetalLB a váš kube-proxy beží v režime IPVS.

MetalLB však nepoužíva jadro na spracovanie požiadaviek arp, ale robí to samo v užívateľskom priestore, takže táto možnosť neovplyvní fungovanie MetalLB.

Vráťme sa k našej úlohe. Ak trasa pre vydané adresy vo vašich uzloch neexistuje, pridajte ju vopred do všetkých uzlov:

ip route add 10.9.8.0/24 dev eth1

Prípad 3: Keď potrebujete smerovanie založené na zdroji

Budete musieť nakonfigurovať smerovanie založené na zdroji, keď prijímate pakety cez samostatnú bránu, nie cez tú, ktorá je nakonfigurovaná predvolene, takže pakety odpovedí by tiež mali prechádzať cez rovnakú bránu.

Napríklad máte rovnakú podsieť 192.168.1.0/24 venované vašim uzlom, ale chcete vydávať externé adresy pomocou MetalLB. Predpokladajme, že máte viacero adries z podsiete 1.2.3.0/24 umiestnené vo VLAN 100 a chcete ich použiť na externý prístup k službám Kubernetes.

Jemné doladenie smerovania pre MetalLB v režime L2

Pri kontaktovaní 1.2.3.4 budete zadávať požiadavky z inej podsiete ako 1.2.3.0/24 a čakať na odpoveď. Uzol, ktorý je momentálne master pre adresu vydanú MetalLB 1.2.3.4, prijme paket zo smerovača 1.2.3.1, ale odpoveď pre neho musí nevyhnutne ísť rovnakou cestou, cez 1.2.3.1.

Keďže náš uzol už má nakonfigurovanú predvolenú bránu 192.168.1.1, potom bude odpoveď štandardne pridelená jemu a nie 1.2.3.1, prostredníctvom ktorej sme balík dostali.

Ako sa s touto situáciou vyrovnať?

V tomto prípade musíte pripraviť všetky svoje uzly tak, aby boli pripravené obsluhovať externé adresy bez ďalšej konfigurácie. To znamená, že pre vyššie uvedený príklad musíte vopred vytvoriť rozhranie VLAN na uzle:

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

A potom pridajte 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

Upozorňujeme, že trasy pridávame do samostatnej smerovacej tabuľky 100 bude obsahovať iba dve cesty potrebné na odoslanie paketu odpovede cez bránu 1.2.3.1, ktorý sa nachádza za rozhraním eth0.100.

Teraz musíme pridať jednoduché pravidlo:

ip rule add from 1.2.3.0/24 lookup 100

ktorý výslovne hovorí: ak je zdrojová adresa paketu v 1.2.3.0/24, potom musíte použiť smerovaciu tabuľku 100. V ňom sme už opísali cestu, ktorou sa dostane 1.2.3.1

Prípad 4: Keď potrebujete smerovanie založené na zásadách

Topológia siete je rovnaká ako v predchádzajúcom príklade, ale povedzme, že chcete mať prístup aj k externým adresám fondu 1.2.3.0/24 z vašich modulov:

Jemné doladenie smerovania pre MetalLB v režime L2

Zvláštnosťou je, že pri prístupe na akúkoľvek adresu v 1.2.3.0/24, paket odpovede zasiahne uzol a má zdrojovú adresu v rozsahu 1.2.3.0/24 bude poslušne poslaný do eth0.100, ale chceme, aby ho Kubernetes presmeroval na náš prvý modul, ktorý vygeneroval pôvodnú požiadavku.

Riešenie tohto problému sa ukázalo ako ťažké, ale bolo to možné vďaka smerovaniu založenému na politike:

Pre lepšie pochopenie procesu uvádzame blokovú schému sieťového filtra:
Jemné doladenie smerovania pre MetalLB v režime L2

Najprv, ako v predchádzajúcom príklade, vytvorte ďalšiu smerovaciu tabuľku:

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

Teraz do iptables pridáme niekoľko pravidiel:

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

Tieto pravidlá označia prichádzajúce pripojenia k rozhraniu eth0.100, pričom označíte všetky pakety značkou 0x100, odpovede v rámci toho istého spojenia budú tiež označené rovnakou značkou.

Teraz môžeme pridať pravidlo smerovania:

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

Teda všetky pakety so zdrojovou adresou 1.2.3.0/24 a tag 0x100 musia byť smerované pomocou tabuľky 100.

Na ostatné pakety prijaté na inom rozhraní sa teda toto pravidlo nevzťahuje, čo umožní ich smerovanie pomocou štandardných nástrojov Kubernetes.

Je tu ešte jedna vec, v Linuxe existuje takzvaný filter spätnej cesty, ktorý pokazí celú malinu, vykoná jednoduchú kontrolu: pre všetky prichádzajúce pakety zmení zdrojovú adresu paketu s adresou odosielateľa a skontroluje, či paket môže odísť cez rovnaké rozhranie, na ktorom bol prijatý, ak nie, odfiltruje ho.

Problém je v tom, že v našom prípade to nebude fungovať správne, ale môžeme to vypnúť:

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

Upozorňujeme, že prvý príkaz riadi globálne správanie rp_filter; ak nie je zakázaný, druhý príkaz nebude mať žiadny účinok. Zostávajúce rozhrania však zostanú s povoleným rp_filter.

Aby sme úplne neobmedzili činnosť filtra, môžeme použiť implementáciu rp_filter pre netfilter. Pomocou rpfilter ako modulu iptables môžete nakonfigurovať pomerne flexibilné pravidlá, naprí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

povoliť rp_filter na rozhraní eth0.100 pre všetky adresy okrem 1.2.3.0/24.

Zdroj: hab.com

Pridať komentár