A MetalLB útválasztás finomhangolása L2 módban

A MetalLB útválasztás finomhangolása L2 módban
Nem sokkal ezelőtt egy nagyon szokatlan feladattal kellett szembenéznem: útválasztást kell beállítani a MetalLB számára. Minden rendben lenne, mert... Általában a MetalLB nem igényel további műveleteket, de esetünkben egy meglehetősen nagy klaszterrel rendelkezünk, nagyon egyszerű hálózati konfigurációval.

Ebben a cikkben elmondom, hogyan konfigurálhat forrás- és házirend-alapú útválasztást a fürt külső hálózatához.

Nem részletezem a MetalLB telepítését és konfigurálását, mivel feltételezem, hogy már van némi tapasztalata. Azt javaslom, hogy menjen közvetlenül a lényegre, nevezetesen az útválasztás beállítására. Tehát négy esetünk van:

1. eset: Amikor nincs szükség konfigurációra

Nézzünk egy egyszerű esetet.

A MetalLB útválasztás finomhangolása L2 módban

Nincs szükség további útválasztási konfigurációra, ha a MetalLB által kiadott címek ugyanabban az alhálózatban vannak, mint a csomópontok címei.

Például van egy alhálózata 192.168.1.0/24, router van benne 192.168.1.1, és a csomópontok címeket kapnak: 192.168.1.10-30, akkor a MetalLB esetében beállíthatja a tartományt 192.168.1.100-120 és győződjön meg arról, hogy minden további konfiguráció nélkül működni fognak.

Miert van az? Mivel a csomópontokon már vannak konfigurálva az útvonalak:

# 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

Az azonos tartományba tartozó címek pedig további műveletek nélkül újra felhasználják őket.

2. eset: Ha további testreszabásra van szükség

A MetalLB útválasztás finomhangolása L2 módban

További útvonalakat kell konfigurálnia, ha a csomópontok nem rendelkeznek konfigurált IP-címmel vagy útvonallal arra az alhálózatra, amelyhez a MetalLB címeket bocsát ki.

Kicsit részletesebben kifejtem. Amikor a MetalLB egy címet ad ki, az összehasonlítható egy egyszerű hozzárendeléssel, például:

ip addr add 10.9.8.7/32 dev lo

Figyelni:

  • a) A címhez egy előtag tartozik /32 vagyis egy útvonal nem kerül automatikusan hozzá az alhálózathoz (ez csak egy cím)
  • b) A cím bármely csomóponti interfészhez csatolva van (például loopback). Itt érdemes megemlíteni a Linux hálózati verem tulajdonságait. Függetlenül attól, hogy melyik interfészhez adja hozzá a címet, a kernel mindig feldolgozza az arp kéréseket, és bármelyikre küldi az arp válaszokat, ez a viselkedés helyesnek tekinthető, és ráadásul meglehetősen széles körben használják olyan dinamikus környezetben, mint a Kubernetes.

Ez a viselkedés testreszabható, például a szigorú arp engedélyezésével:

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

Ebben az esetben az arp válaszokat csak akkor küldi el, ha az interfész kifejezetten tartalmaz egy adott IP-címet. Ez a beállítás akkor szükséges, ha MetalLB-t kíván használni, és a kube-proxy IPVS módban fut.

A MetalLB azonban nem használja a kernelt az arp kérések feldolgozására, hanem saját maga végzi el a felhasználói térben, így ez az opció nem befolyásolja a MetalLB működését.

Térjünk vissza a feladatunkhoz. Ha a kiadott címekhez tartozó útvonal nem létezik a csomópontokon, előzetesen adja hozzá az összes csomóponthoz:

ip route add 10.9.8.0/24 dev eth1

3. eset: Ha forrásalapú útválasztásra van szüksége

Be kell állítania a forrás alapú útválasztást, ha külön átjárón keresztül kap csomagokat, nem az alapértelmezés szerint beállítotton, ezért a válaszcsomagoknak is ugyanazon az átjárón kell keresztülmenniük.

Például ugyanaz az alhálózata van 192.168.1.0/24 dedikált a csomópontjaihoz, de külső címeket szeretne kiadni a MetalLB használatával. Tegyük fel, hogy több címe van egy alhálózatból 1.2.3.0/24 a VLAN 100-ban található, és a Kubernetes-szolgáltatásokhoz külsőleg szeretne hozzáférni.

A MetalLB útválasztás finomhangolása L2 módban

Kapcsolatfelvételkor 1.2.3.4 más alhálózatról fog kérni, mint 1.2.3.0/24 és várja a választ. Az a csomópont, amely jelenleg a MetalLB által kiadott cím mestere 1.2.3.4, megkapja a csomagot a routertől 1.2.3.1, de a válasznak feltétlenül ugyanazon az úton kell haladnia, keresztül 1.2.3.1.

Mivel a csomópontunknak már van beállított alapértelmezett átjárója 192.168.1.1, akkor alapértelmezés szerint a válasz neki fog menni, és nem 1.2.3.1, amelyen keresztül megkaptuk a csomagot.

Hogyan lehet megbirkózni ezzel a helyzettel?

Ebben az esetben az összes csomópontot úgy kell előkészítenie, hogy készen álljanak a külső címek további konfiguráció nélküli kiszolgálására. Vagyis a fenti példában előzetesen létre kell hoznia egy VLAN interfészt a csomóponton:

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

Ezután adjon hozzá útvonalakat:

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

Felhívjuk figyelmét, hogy az útvonalakat külön útválasztási táblázatba adjuk 100 csak két olyan útvonalat fog tartalmazni, amelyek a válaszcsomag átjárón keresztül történő elküldéséhez szükségesek 1.2.3.1, amely az interfész mögött található eth0.100.

Most hozzá kell adnunk egy egyszerű szabályt:

ip rule add from 1.2.3.0/24 lookup 100

amely kifejezetten azt mondja: ha a csomag forráscíme benne van 1.2.3.0/24, akkor az útválasztási táblát kell használnia 100. Ebben már leírtuk az útvonalat, amelyen keresztül eljut 1.2.3.1

4. eset: Ha házirend-alapú útválasztásra van szüksége

A hálózati topológia ugyanaz, mint az előző példában, de tegyük fel, hogy külső készletcímeket is szeretne elérni 1.2.3.0/24 a hüvelyeidből:

A MetalLB útválasztás finomhangolása L2 módban

A sajátosság az, hogy bármely cím elérésekor 1.2.3.0/24, a válaszcsomag eléri a csomópontot, és a tartományban van egy forráscíme 1.2.3.0/24 engedelmesen elküldik majd eth0.100, de azt szeretnénk, hogy a Kubernetes átirányítsa az első podba, amely az eredeti kérést generálta.

A probléma megoldása nehéznek bizonyult, de a házirend-alapú útválasztásnak köszönhetően lehetségessé vált:

A folyamat jobb megértése érdekében itt van egy netfilter blokkdiagram:
A MetalLB útválasztás finomhangolása L2 módban

Először is, az előző példához hasonlóan, hozzunk létre egy további útválasztó táblát:

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

Most adjunk hozzá néhány szabályt az iptables-hoz:

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

Ezek a szabályok megjelölik az interfészhez bejövő kapcsolatokat eth0.100, minden csomagot megjelölve a címkével 0x100, az ugyanazon a kapcsolaton belüli válaszok is ugyanazzal a címkével lesznek megjelölve.

Most hozzáadhatunk egy útválasztási szabályt:

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

Vagyis minden csomag forráscímmel 1.2.3.0/24 és tag 0x100 táblázat segítségével kell irányítani 100.

Így a másik interfészen kapott más csomagokra nem vonatkozik ez a szabály, amely lehetővé teszi, hogy szabványos Kubernetes-eszközökkel irányítsák őket.

Van még valami, a Linuxban van egy úgynevezett reverse path filter, ami elrontja az egészet, egy egyszerű ellenőrzést végez: minden bejövő csomagnál megváltoztatja a csomag forráscímét a küldő címével, és ellenőrzi, hogy a csomag ugyanazon az interfészen keresztül távozhat, amelyen érkezett, ha nem, akkor kiszűri.

A probléma az, hogy esetünkben nem fog megfelelően működni, de letilthatjuk:

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

Kérjük, vegye figyelembe, hogy az első parancs az rp_filter globális viselkedését szabályozza; ha nincs letiltva, a második parancsnak nincs hatása. A többi interfészen azonban az rp_filter engedélyezve marad.

Annak érdekében, hogy ne korlátozzuk teljesen a szűrő működését, használhatjuk az rp_filter implementációt a netfilterhez. Az rpfilter iptables modulként való használatával meglehetősen rugalmas szabályokat állíthat be, például:

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

engedélyezze az rp_filtert az interfészen eth0.100 minden címre, kivéve 1.2.3.0/24.

Forrás: will.com

Hozzászólás