
Koha e fundit përballa me një detyrë të pazakonshme për konfigurimin e rutimit për MetalLB. Nuk do të ishte ndonjë problem, pasi zakonisht për MetalLB nuk kërkohen veprime shtesë, por në rastin tonë ka një klaster të madh me një konfigurim të thjeshtë rrjeti.
Në këtë artikull do të tregoj se si të konfiguroni rutimin e bazuar në burim dhe rutimin e bazuar në politika për rrjetin tuaj të jashtëm.
Nuk do të ndalem në instalimin dhe konfigurimin e MetalLB, pasi supozoj se keni ndonjë përvojë. Propozoj të kalojmë drejtpërsëdrejti në punë, domethënë në konfigurimin e rutimit. Kështu kemi katër raste:
Rasti 1: Kur rregullimi nuk kërkohet
Të shqyrtojmë një rast të thjeshtë.

Rregullimi shtesë i rutimit nuk kërkohet kur adresat e dhëna nga MetalLB janë në të njëjtën nënrrjetë me adresat e nodave tuaj.
Për shembull, keni një nënrrjetë 192.168.1.0/24, aty ka një rutues 192.168.1.1, dhe nodet tuaja marrin adresat: 192.168.1.10-30, atëherë për MetalLB mund të konfiguroni një rang 192.168.1.100-120 dhe të jeni të sigurt se ato do të funksionojnë pa ndonjë konfigurim shtesë.
Pse kështu? Sepse nodet tuaja tashmë kanë të konfigurura rrugë:
# 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.10Dhe adresat nga i njëjti rang do të ripërdorin ato pa ndonjë përpjekje shtesë.
Rasti 2: Kur kërkohet rregullim shtesë

Ju duhet të konfiguroni rrugë shtesë çdo herë kur nodet tuaja nuk kanë të konfiguruar IP-адреса apo një rrugë në nënrrjeten për të cilën MetalLB ka dhënë adresat.
Të shpjegoj pak më në detaje. Çdo herë që MetalLB jep një adresë, kjo mund të krahasohet me një emërim të thjeshtë të këtij lloji:
ip addr add 10.9.8.7/32 dev loVini re, se:
- a) Adresa jepet me prefiks
/32pra rruga në nënrrjetë për të nuk do të shtohet automatikisht (është thjesht një adresë) - b) Adresa lidhet me çdo ndërfaqe të nodës (p.sh. loopback). Këtu është e rëndësishme të përmendet veçoria e shtresës rrjetore të Linux. Nuk ka rëndësi në cilën ndërfaqe e shtoni adresën, bërthama gjithmonë do të trajtojë kërkesat arp dhe do të dërgojë përgjigjet arp në cilëndo prej tyre; ky qëndrim konsiderohet i saktë dhe, për më tepër, përdoret gjerësisht në një mjedis dinamik si Kubernetes.
Ky qëndrim mund të konfigurohet, për shembull duke aktivizuar arp strikt:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announceNë këtë rast, përgjigjet ARP do të dërgohen vetëm nëse interfaci përmban një adresë IP specifike. Ky cilësim është i detyrueshëm në rast se planifikoni të përdorni MetalLB dhe kube-proxy juaj punon në modalitetin IPVS.
Megjithatë, MetalLB nuk përdor bërthamën për të përpunuar kërkesat ARP, por e bën këtë vetë në hapësirën e përdoruesit, kështu që kjo mundësi nuk do të ndikojë në funksionimin e MetalLB.
Le të kthehemi në detyrën tonë. Nëse nuk ekziston një rrugë për adresat e shpërndara në nodet tuaja, shtoni atë paraprakisht në të gjitha nodet:
ip route add 10.9.8.0/24 dev eth1Rasti 3: Kur do të jetë e nevojshme routing bazuar në burim
Ju nevojitet të konfiguroni routing bazuar në burim kur merrni paketa përmes një gateway të veçantë, ndryshe nga ai që keni konfiguruar si të parazgjedhur, prandaj, paketat e përgjigjes gjithashtu duhet të shkojnë përmes këtij gateway.
Për shembull, ju keni të njëjtin subnet 192.168.1.0/24 të dedikuar për nodet tuaja, por dëshironi të jepni adresat e jashtme me MetalLB. Supozoni se keni disa adresa nga subneti 1.2.3.0/24 në VLAN 100, dhe dëshironi t'i përdorni ato për të aksesuar shërbimet e Kubernetes nga jashtë.

Kur të drejtoheni në 1.2.3.4 do të bëni kërkesa nga një subnet tjetër nga 1.2.3.0/24 dhe do të prisni një përgjigje. Noda, e cila për momentin është masteri për adresën e dhënë nga MetalLB 1.2.3.4, do të marrë paketën nga routeri 1.2.3.1, por përgjigja për të duhet patjetër të shkojë në të njëjtin rrugë, përmes 1.2.3.1.
Duke qenë se noda jonë tashmë ka një gateway të parazgjedhur 192.168.1.1, përgjigja automatikisht do të shkojë aty, dhe jo për 1.2.3.1, përmes të cilit morëm paketën.
Si mund ta zgjidhim këtë situatë?
Në këtë rast, ju nevojitet të përgatitni të gjitha nodet tuaja në mënyrë që ato të jenë të gatshme të mundësojnë adresat e jashtme pa konfigurime shtesë. Kështu, për shembullin e lartpërmendur, ju duhet të krijoni paraprakisht një ndërfaqe VLAN në nodë:
ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 upDhe pastaj të shtoni rrugët:
ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100Vini re se rrugët i shtojmë në një tabelë të veçantë rrugëtimi 100 ajo do të përmbajë vetëm dy rrugë të nevojshme për dërgimin e paketës përmes gateway 1.2.3.1, që ndodhet pas ndërfaqes eth0.100.
Tani na nevojitet të shtojmë një rregull të thjeshtë:
ip rule add from 1.2.3.0/24 lookup 100e cila thotë qartë: nëse adresa burimore e paketës ndodhet në 1.2.3.0/24, atëherë duhet të përdorni tabelën e rrugëtimit 100. Në të kemi përshkruar tashmë itinerarin që do ta dërgojë atë përmes 1.2.3.1
Rasti 4: Kur do të nevojitet routing i bazuar në politika
Topologjia e rrjetit është si në shembullin e mëparshëm, por supozojmë se dëshironi gjithashtu të keni mundësinë që të aksesoni adresat e jashtme të pool-it 1.2.3.0/24 nga pods tuaj:

Veçoria qëndron në faktin se kur i drejtohen çdo adrese në 1.2.3.0/24, paketi përgjigjës, duke arritur në nod dhe duke pasur adresën e burimit në gamën 1.2.3.0/24 , do të dërgohet nënshtruar në eth0.100, por ne duam që Kubernetes ta redirektojë atë në pod-in tonë të parë, i cili e gjeneroi kërkesën origjinale.
Zgjidhja e këtij problemi u tregua e vështirë, por kjo u mundësua falë routing-ut të bazuar në politika:
Për një kuptim më të thellë të procesit, do të jap një diagram kuadrim netfilter:

Për fillim, si në shembullin e mëparshëm, do të krijojmë një tabelë të re rrugëzimi:
ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100Tani do të shtojmë disa rregulla në 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-markKëto rregulla do të markojnë lidhjet hyrëse në ndërfaqen eth0.100, duke e markuar të gjitha paketat me etiketën 0x100, kjo etiketë do të përdoret gjithashtu për përgjigjet brenda të njëjtës lidhje.
Tani mund të shtojmë një rregull rrugëzimi:
ip rule add from 1.2.3.0/24 fwmark 0x100Pra, të gjitha paketat me adresën e burimit 1.2.3.0/24 dhe etiketën 0x100 duhet të rrugëzohen duke përdorur tabelën 100.
Kështu, paketat e tjera që priten në një ndërfaqe tjetër, nuk bien nën këtë rregull, duke i lejuar ato të rrugëzohen me mjetet standarde të Kubernetes.
Ka një por, në Linux ekziston një filtri i njohur si reverse path filter, i cili prishet situatën duke kryer një kontroll të thjeshtë: për të gjitha paketat hyrëse ai ndryshon adresën e burimit të paketës me adresën e dërguesit dhe kontrollon nëse paketa mund të dalë përmes të njëjtës ndërfaqe nga e cila është marrë, nëse jo, atëherë e filtroi atë.
Problemi është se në rastin tonë do të funksionojë në mënyrë të papërshtatshme, por ne mund ta çaktivizojmë atë:
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0.100/rp_filterVini re, komanda e parë kontrollon sjelljen globale të rp_filter, nëse nuk e çaktivizoni, atëherë komanda e dytë nuk do të ketë asnjë efekt. Megjithatë, gjithë ndërfaqet e tjera do të mbeten me rp_filter të aktivizuar.
Për të mos e kufizuar plotësisht funksionimin e filtrit, ne mund të shfrytëzojmë implementimin e rp_filter për netfilter. Duke përdorur rpfilter si një modul iptables, mund të configurem rregulla mjaft fleksibël, për shembull:
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 DROPaktivizoni rp_filter në interface eth0.100 për të gjitha adresat përveç 1.2.3.0/24.
Burimi: habr.com
