
Nedávno som sa stretol s pomerne netradičnou úlohou nastavenia smerovania pre MetalLB. Nič by na tom nebolo, pretože zvyčajne pre MetalLB nie sú potrebné žiadne ďalšie akcie, ale v našom prípade máme dostatočne veľký klaster s pomerne jednoduchou konfiguráciou siete.
V tomto článku sa podelím o to, ako nastaviť smerovanie založené na zdroji a smerovanie založené na politike pre vonkajšiu sieť vášho klastru.
Nebudem sa podrobne zaoberať inštaláciou a nastavením MetalLB, pretože predpokladám, že už máte určité skúsenosti. Navrhoval by som ihneď prejsť k veci, to znamená k nastaveniu smerovania. Takže máme štyri prípady:
Prípad 1: Keď nastavenie nie je potrebné
Rozoberieme jednoduchý prípad.

Dodatočné nastavenie smerovania nie je potrebné, keď adresy vydávané MetalLB sú v tej istej podsieti ako adresy vašich uzlov.
Napríklad máte podsieť 192.168.1.0/24, v nej je smerovač 192.168.1.1, a vaše uzly získavajú adresy: 192.168.1.10-30, potom pre MetalLB môžete nastaviť rozsah 192.168.1.100-120 a byť si istý, že budú fungovať bez akéhokoľvek ďalšieho nastavenia.
Prečo je to tak? Pretože vaše uzly už 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.10A adresy z toho istého rozsahu si ich znovu použijú bez akýchkoľvek ďalších pohybov.
Prípad 2: Keď je potrebné dodatočné nastavenie

Mali by ste nastaviť dodatočné trasy vždy, keď vaše uzly nemajú nastavený IP adresy alebo trasu do podsiete, pre ktorú MetalLB vydáva adresy.
Vysvetlím trochu podrobnejšie. Vždy, keď MetalLB vydá adresu, to sa dá porovnať s jednoduchým priradením typu:
ip addr add 10.9.8.7/32 dev loVšimnite si, že:
- a) Adresa sa priraďuje s prefixom
/32to znamená, že trasa do podsiete pre ňu sa automaticky nepridá (to je len adresa) - b) Adresa sa priraďuje na akékoľvek rozhranie uzla (napríklad loopback). Tu je potrebné spomenúť zvláštnosť sieťového zásobníka Linuxu. Nie je dôležité, na ktoré rozhranie pridáte adresu, jadro vždy spracováva arp-žiadosti a odosiela arp-odpovede na ktorékoľvek z nich, toto správanie sa považuje za správne a navyše sa dosť široko používa v takej dynamickej prostredí ako Kubernetes.
Toto správanie je možné nastaviť, napríklad, zapnutím strict arp:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announceV tomto prípade budú arp-odpovede zasielané iba vtedy, ak rozhranie obsahuje konkrétnu IP adresu. Toto nastavenie je povinné, ak plánujete používať MetalLB a váš kube-proxy beží v režime IPVS.
MetalLB však nepoužíva jadro na spracovanie arp-žiadostí, ale vykonáva to samostatne v užívateľskom priestore, takže táto možnosť nebude mať vplyv na fungovanie MetalLB.
Vráťme sa k našej úlohe. Ak neexistuje cesta pre pridelené adresy na vašich uzloch, pridajte ju vopred na všetky uzly:
ip route add 10.9.8.0/24 dev eth1Prípad 3: Keď bude potrebné smerovanie založené na zdroji
Smerovanie založené na zdroji budete musieť nastaviť vtedy, keď prijímate pakety cez samostatný gateway, nie ten, ktorý máte nastavený ako predvolený, a teda aj spätné pakety musia odchádzať cez tento istý gateway.
Napríklad, máte tú istú podsieť 192.168.1.0/24 vyčlenenú pre vaše uzly, ale chcete pridelovať externé adresy pomocou MetalLB. Predpokladajme, že máte niekoľko adries z podsiete 1.2.3.0/24 nachádzajúce sa vo VLAN 100 a chcete ich použiť na prístup k službám Kubernetes zvonka.

Pri prístupe na 1.2.3.4 budete posielať žiadosti z inej podsiete ako 1.2.3.0/24 a očakávať odpoveď. Uzol, ktorý je v súčasnosti hlavným pre pridelenú adresu MetalLB 1.2.3.4, prijme paket od smerovača 1.2.3.1, ale odpoveď naň musí ísť tou istou trasou, cez 1.2.3.1.
Keďže náš uzol už má nastavený predvolený gateway 192.168.1.1, odpoveď pôjde predvolene k nemu a nie k 1.2.3.1, cez ktorý sme dostali paket.
Ako sa vysporiadať s touto situáciou?
V tomto prípade musíte pripraviť všetky svoje uzly tak, aby boli schopné obsluhovať externé adresy bez dodatočného nastavenia. To znamená, že pre vyššie uvedený príklad je potrebné vopred vytvoriť VLAN-rozhranie na uzle:
ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 upA potom pridať smerovanie:
ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100Všimnite si, že trasy pridávame do samostatnej tabuľky smerovania 100 bude obsahovať iba dve trasy potrebné na zasielanie odpovedajúceho paketu cez gateway 1.2.3.1, nachádzajúceho sa za rozhraním eth0.100.
Teraz musíme pridať jednoduché pravidlo:
ip rule add from 1.2.3.0/24 lookup 100ktoré jasne hovorí: ak je adresa zdroja paketu v 1.2.3.0/24, je potrebné použiť tabuľku smerovania 100. V nej už máme opísanú trasu, ktorá ho pošle cez 1.2.3.1
Prípad 4: Keď bude potrebné smerovanie založené na politike
Topológia siete je rovnaká ako v predchádzajúcom príklade, ale predpokladajme, že chcete mať tiež možnosť pristupovať k vonkajším adresám z poolu 1.2.3.0/24 z vašich podov:

Rys sa nachádza v tom, že pri prístupe k akejkoľvek adrese v 1.2.3.0/24, odpovedajúci paket prichádzajúci na uzol s adresou zdroja v rozsahu 1.2.3.0/24 bude poslušne odoslaný do eth0.100, ale my chceme, aby Kubernetes preposlal ho do nášho prvého podu, ktorý pôvodne vygeneroval požiadavku.
Riešenie tejto otázky sa ukázalo ako náročné, ale stalo sa to možné vďaka smerovaniu na základe politiky:
Pre lepšie pochopenie procesu uvediem blokovú schému netfilter:

Najprv, ako v predchádzajúcom príklade, vytvoríme ďalšiu routingovú 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 100Teraz pridáme niekoľko pravidiel 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-markTieto pravidlá budú označovať prichádzajúce pripojenia na rozhraní eth0.100, označujúc všetky pakety značkou 0x100, touto istou značkou budú označené aj odpovede v rámci jedného pripojenia.
Teraz môžeme pridať pravidlo smerovania:
ip rule add from 1.2.3.0/24 fwmark 0x100 lookup 100To znamená, že všetky pakety s adresou zdroja 1.2.3.0/24 a značkou 0x100 by mali byť smerované pomocou tabuľky 100.
Takže iné pakety prijaté na inom rozhraní sa pod toto pravidlo nedostanú, čo im umožní byť smerované štandardnými prostriedkami Kubernetes.
Existuje však ešte jedno ale, v Linuxe existuje takzvaný filter reverznej cesty, ktorý kazí všetko – vykonáva jednoduchú kontrolu: pre všetky prichádzajúce pakety mení adresu zdroja paketu na adresu odosielateľa a kontroluje, či môže paket odísť cez to isté rozhranie, cez ktoré bol prijatý, ak nie, tak ho filtrove.
Problém je v tom, že v našom prípade nebude fungovať správne, ale môžeme ho vypnúť:
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0.100/rp_filterVšimnite si, že prvý príkaz ovláda globálne správanie rp_filter, ak ho nevypnete, druhý príkaz nebude mať žiadny efekt. Napriek tomu ostatné rozhrania zostanú so zapnutým rp_filter.
Aby sme úplne neobmedzili prácu filtra, môžeme využiť realizáciu rp_filter pre netfilter. Použitím rpfilter ako modulu iptables je možné nastaviť dostatočne 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 DROPaktivovať rp_filter na rozhraní eth0.100 pre všetky adresy okrem 1.2.3.0/24.
Zdroj: habr.com
