Jemné doladění směrování pro MetalLB v režimu L2

Jemné doladění směrování pro MetalLB v režimu L2
Nedávno jsem stál před velmi neobvyklým úkolem nastavit směrování pro MetalLB. Všechno by bylo v pořádku, protože... MetalLB obvykle nevyžaduje žádné další akce, ale v našem případě máme poměrně velký cluster s velmi jednoduchou konfigurací sítě.

V tomto článku vám řeknu, jak nakonfigurovat směrování založené na zdroji a na zásadách pro externí síť vašeho clusteru.

Nebudu zabíhat do podrobností o instalaci a konfiguraci MetalLB, protože předpokládám, že již máte nějaké zkušenosti. Navrhuji jít přímo k věci, konkrétně k nastavení směrování. Máme tedy čtyři případy:

Případ 1: Když není vyžadována žádná konfigurace

Podívejme se na jednoduchý případ.

Jemné doladění směrování pro MetalLB v režimu L2

Další konfigurace směrování není vyžadována, pokud jsou adresy vydané MetalLB ve stejné podsíti jako adresy vašich uzlů.

Máte například podsíť 192.168.1.0/24, má router 192.168.1.1a vaše uzly obdrží adresy: 192.168.1.10-30, pak pro MetalLB můžete upravit rozsah 192.168.1.100-120 a ujistěte se, že budou fungovat bez jakékoli další konfigurace.

proč tomu tak je? Protože vaše uzly již 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 ze stejného rozsahu je znovu použijí bez dalších akcí.

Případ 2: Když je vyžadováno další přizpůsobení

Jemné doladění směrování pro MetalLB v režimu L2

Měli byste nakonfigurovat další cesty, kdykoli vaše uzly nemají nakonfigurovanou IP adresu nebo směrování do podsítě, pro kterou MetalLB vydává adresy.

Vysvětlím to trochu podrobněji. Kdykoli MetalLB vydá adresu, lze ji přirovnat k jednoduchému zadání, jako je:

ip addr add 10.9.8.7/32 dev lo

Dávejte pozor na:

  • a) Adresa je přiřazena s předponou /32 to znamená, že trasa pro ni nebude automaticky přidána do podsítě (je to pouze adresa)
  • b) Adresa je připojena k libovolnému rozhraní uzlu (například zpětné smyčce). Zde stojí za zmínku vlastnosti linuxového síťového zásobníku. Bez ohledu na to, do kterého rozhraní přidáte adresu, jádro vždy zpracuje požadavky arp a odešle odpovědi arp na kterýkoli z nich, toto chování je považováno za správné a navíc je v tak dynamickém prostředí, jako je Kubernetes, poměrně široce používáno.

Toto chování lze přizpůsobit, například povolením přísného 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 odpovědi arp odeslány pouze v případě, že rozhraní explicitně obsahuje konkrétní IP adresu. Toto nastavení je vyžadováno, pokud plánujete používat MetalLB a vaše kube-proxy běží v režimu IPVS.

MetalLB však nepoužívá jádro ke zpracování požadavků arp, ale dělá to samo v uživatelském prostoru, takže tato možnost neovlivní provoz MetalLB.

Vraťme se k našemu úkolu. Pokud trasa pro vydané adresy ve vašich uzlech neexistuje, přidejte ji předem do všech uzlů:

ip route add 10.9.8.0/24 dev eth1

Případ 3: Když potřebujete směrování založené na zdroji

Budete muset nakonfigurovat směrování založené na zdroji, když přijímáte pakety prostřednictvím samostatné brány, nikoli brány nakonfigurované ve výchozím nastavení, proto by pakety s odpovědí měly také procházet stejnou bránou.

Máte například stejnou podsíť 192.168.1.0/24 vyhrazené pro vaše uzly, ale chcete vydávat externí adresy pomocí MetalLB. Předpokládejme, že máte více adres z podsítě 1.2.3.0/24 umístěné ve VLAN 100 a chcete je používat pro externí přístup ke službám Kubernetes.

Jemné doladění směrování pro MetalLB v režimu L2

Při kontaktu 1.2.3.4 budete zadávat požadavky z jiné podsítě než 1.2.3.0/24 a čekat na odpověď. Uzel, který je aktuálně hlavním pro adresu vydanou MetalLB 1.2.3.4, přijme paket z routeru 1.2.3.1, ale odpověď pro něj musí nutně jít stejnou cestou, skrz 1.2.3.1.

Protože náš uzel již má nakonfigurovanou výchozí bránu 192.168.1.1, pak ve výchozím nastavení odešle odpověď jemu a ne 1.2.3.1, prostřednictvím kterého jsme balíček obdrželi.

Jak se s touto situací vyrovnat?

V tomto případě musíte připravit všechny vaše uzly tak, aby byly připraveny obsluhovat externí adresy bez další konfigurace. To znamená, že pro výše uvedený příklad musíte předem vytvořit rozhraní VLAN na uzlu:

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

A pak přidejte 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 přidáváme trasy do samostatné směrovací tabulky 100 bude obsahovat pouze dvě cesty nutné k odeslání paketu odpovědi přes bránu 1.2.3.1, umístěný za rozhraním eth0.100.

Nyní musíme 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 musíte použít směrovací tabulku 100. V něm jsme již popsali cestu, která ho pošle 1.2.3.1

Případ 4: Když potřebujete směrování založené na zásadách

Topologie sítě je stejná jako v předchozím příkladu, ale řekněme, že chcete mít také přístup k externím adresám fondu 1.2.3.0/24 z vašich podů:

Jemné doladění směrování pro MetalLB v režimu L2

Zvláštností je, že při přístupu na jakoukoli adresu v 1.2.3.0/24, paket odpovědi zasáhne uzel a má zdrojovou adresu v rozsahu 1.2.3.0/24 bude poslušně poslán do eth0.100, ale chceme, aby jej Kubernetes přesměroval na náš první modul, který vygeneroval původní požadavek.

Řešení tohoto problému se ukázalo být obtížné, ale bylo to možné díky směrování založenému na zásadách:

Pro lepší pochopení procesu je zde blokové schéma netfilter:
Jemné doladění směrování pro MetalLB v režimu L2

Nejprve, stejně jako v předchozím příkladu, vytvořte 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

Nyní přidáme do iptables několik pravidel:

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 označí příchozí připojení k rozhraní eth0.100, označující všechny pakety značkou 0x100, budou také odpovědi v rámci stejného spojení označeny stejným tagem.

Nyní můžeme přidat pravidlo směrování:

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

Tedy všechny pakety se zdrojovou adresou 1.2.3.0/24 a tag 0x100 musí být směrován pomocí tabulky 100.

Ostatní pakety přijaté na jiném rozhraní tedy tomuto pravidlu nepodléhají, což umožní jejich směrování pomocí standardních nástrojů Kubernetes.

Je tu ještě jedna věc, v Linuxu je tzv. filtr zpětné cesty, který to celé kazí, provede jednoduchou kontrolu: u všech příchozích paketů změní zdrojovou adresu paketu s adresou odesílatele a zkontroluje, zda paket může odejít přes stejné rozhraní, na kterém byl přijat, pokud ne, odfiltruje ho.

Problém je v tom, že v našem případě to nebude fungovat správně, ale můžeme to zakázat:

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

Vezměte prosím na vědomí, že první příkaz řídí globální chování rp_filter; pokud není zakázán, druhý příkaz nebude mít žádný účinek. Zbývající rozhraní však zůstanou s povoleným rp_filter.

Aby nedošlo k úplnému omezení provozu filtru, můžeme použít implementaci rp_filter pro netfilter. Pomocí rpfilter jako modulu iptables můžete nakonfigurovat poměrně 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

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

Zdroj: www.habr.com

Přidat komentář