
Nedavno sem se srečal s precej nenavadno nalogo nastavitve usmerjanja za MetalLB. Nič hudega, ker običajno ni potrebnih dodatnih ukrepov za MetalLB, vendar imamo v našem primeru precej velik grozdi s dokaj preprosto omrežno konfiguracijo.
V tem članku bom opisal, kako nastaviti usmerjanje na podlagi virov in usmerjanje na podlagi pravil za zunanje omrežje vašega grozda.
Ne bom se podrobno ustavljal pri namestitvi in nastavitvi MetalLB, ker predvidevam, da imate že nekaj izkušenj. Predlagam, da se takoj lotimo dela, torej nastavitve usmerjanja. Imamo štiri primere:
Primer 1: Ko nastavitev ni potrebna
Razmislimo o preprostem primeru.

Dodatna nastavitev usmerjanja ni potrebna, ko so naslovi, ki jih dodeljuje MetalLB, v isti podmreži kot naslovi vaših vozlišč.
Na primer, imate podmrežo 192.168.1.0/24, v njej je usmerjevalnik 192.168.1.1, in vaša vozlišča prejemajo naslove: 192.168.1.10-30, zato lahko za MetalLB nastavite obseg 192.168.1.100-120 in biti prepričani, da bodo delovali brez kakršnekoli dodatne nastavitve.
Zakaj tako? Ker imajo vaša vozlišča že nastavljene poti:
# 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.10In naslovi iz istega obsega jih bodo ponovno uporabili brez kakršnih koli dodatnih ukrepov.
Primer 2: Ko je potrebna dodatna nastavitev

Dodatne poti je treba nastaviti vedno, ko vaša vozlišča nimajo nastavljene IP-naslove ali poti v podmrežo, za katero MetalLB dodeljuje naslove.
Pojasnim malo podrobneje. Vedno, ko MetalLB dodeli naslov, to lahko primerjate s preprostim dodeljevanjem, ki izgleda takole:
ip addr add 10.9.8.7/32 dev loPozor, na:
- a) Naslov se dodeli s predpono
/32, kar pomeni, da pot v podmrežo zanj samodejno ne bo dodana (to je samo naslov) - b) Naslov se dodeli kateremu koli vmesniku vozlišča (na primer loopback). Tukaj je treba omeniti značilnost omrežnega steka Linuxa. Ni važno, na kateri vmesnik dodelite naslov, jedro bo vedno obdelalo arp poizvedbe in poslalo arp odgovore na katerokoli od njih, takšno obnašanje velja za pravilno in se poleg tega precej široko uporablja v tako dinamičnem okolju, kot je Kubernetes.
To obnašanje je mogoče nastaviti, na primer, z aktiviranjem strogega ARP:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announceV tem primeru bodo arp-odgovori poslani le, če ima vmesnik jasno določen določen IP naslov. Ta nastavitev je obvezna, če nameravate uporabljati MetalLB in vaš kube-proxy deluje v načinu IPVS.
Kljub temu MetalLB za obdelavo arp-poizvedb ne uporablja jedra, ampak to počne samostojno v uporabniškem prostoru, zato ta možnost ne bo vplivala na delovanje MetalLB.
Vrnimo se k našemu nalogu. Če za dodeljene naslove na vaših vozliščih ne obstaja pot, jo dodajte vnaprej na vsa vozlišča:
ip route add 10.9.8.0/24 dev eth1Primera 3: Ko bo potrebno usmerjanje na osnovi vira
Usmerjanje na osnovi vira boste morali nastaviti, ko prejemate pakete prek ločenega prehod, ne tistega, ki je nastavljen privzeto, zato mora tudi povratni paket oditi skozi ta isti prehod.
Na primer, imate isto podomrežje 192.168.1.0/24 dodeljeno vašim vozliščem, vendar želite dodeliti zunanje naslove z uporabo MetalLB. Recimo, da imate več naslovov iz podomrežja 1.2.3.0/24 ki so v VLAN 100, in jih želite uporabiti za dostop do Kubernetes storitev od zunaj.

Ko se obrnete na 1.2.3.4 boste pošiljali poizvedbe iz drugega podomrežja kot 1.2.3.0/24 in pričakovali odgovor. Vozlišče, ki je trenutni glavni za dodeljeni MetalLB naslov 1.2.3.4, bo prejelo paket od usmerjevalnika 1.2.3.1, toda odgovor mu mora nujno oditi po isti poti, preko 1.2.3.1.
Ker naše vozlišče že ima nastavljen privzeti prehod 192.168.1.1, bo privzeto odgovor šel k njemu, in ne k 1.2.3.1, preko katerega smo prejeli paket.
Kako se spoprijeti s to situacijo?
V tem primeru morate pripraviti vsa vaša vozlišča tako, da bodo pripravljena obravnavati zunanje naslove brez dodatne nastavitve. To pomeni, da morate za zgornji primer vnaprej ustvariti VLAN-vmesnik na vozlišču:
ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 upNato dodajte poti:
ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100Upoštevajte, da poti dodajamo v ločeno tabelo usmerjanja, 100 ki bo vsebovala le dve poti, potrebni za pošiljanje povratnega paketa prek prehoda 1.2.3.1, ki se nahaja za vmesnikom eth0.100.
Zdaj moramo dodati preprosto pravilo:
ip rule add from 1.2.3.0/24 lookup 100ki jasno pove: če je naslov izvora paketa v 1.2.3.0/24, se mora uporabiti tabela usmerjanja 100. V njej je že opisana pot, ki bo poslala prek 1.2.3.1
Primer 4: Ko potrebujete usmerjanje na podlagi pravil
Topologija omrežja, kot v prejšnjem primeru, vendar recimo, da želite imeti tudi možnost dostopa do zunanjih naslovov bazena 1.2.3.0/24 iz vaših kontejnerjev:

Posebnost je v tem, da ob dostopu do kateregakoli naslova v 1.2.3.0/24, se povratni paket, ki pride na vozlišče in ima izvorni naslov v razponu 1.2.3.0/24 , tako pripravljen poslan v eth0.100, vendar želimo, da Kubernetes preusmeri ta paket v naš prvi kontejner, ki je izvorni zahtevek generiral.
Reševanje tega problema se je izkazalo za zahtevno, vendar je bilo možno zahvaljujoč usmerjanju na podlagi pravil:
Za boljše razumevanje procesa bom priložil shemo netfilter:

Najprej, kot v prejšnjem primeru, ustvarimo dodatno usmerjevalno tabelo:
ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100Zdaj dodajmo nekaj pravil v 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-markTa pravila bodo označila prihajajoče povezave na vmesniku eth0.100, pri čemer bodo vsi paketi označeni s tagom 0x100, s tem istim tagom bodo označeni tudi odgovori v okviru iste povezave.
Zdaj lahko dodamo pravilo za usmerjanje:
ip rule add from 1.2.3.0/24 fwmark 0x100 lookup 100Torej, vsi paketi z izvorno naslovom 1.2.3.0/24 in tagom 0x100 morajo biti usmerjeni z uporabo tabele 100.
Tako drugi paketi, prejeti na drugem vmesniku, pod to pravilo ne spadajo, kar jim omogoča, da jih usmerimo z običajnimi sredstvi Kubernetes.
Obstaja pa še ena zadeva, v Linuxu obstaja tako imenovani filter obratne poti, ki pokvari vse, saj izvaja preprosto preverjanje: za vse prihajajoče pakete spremeni izvorni naslov paketa na naslov pošiljatelja in preveri, ali lahko paket zapusti preko istega vmesnika, na katerega je bil prejet, če ne, ga filtrira.
Težava je v tem, da bo v našem primeru deloval nepravilno, lahko pa ga izklopimo:
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0.100/rp_filterUpoštevajte, prvi ukaz nadzoruje globalno obnašanje rp_filter, če ga ne izklopite, drugi ukaz ne bo imel nobenega učinka. Kljub temu bodo ostali vmesniki ostali z vključenim rp_filter.
Da ne omejimo delovanje filtra popolnoma, lahko uporabimo implementacijo rp_filter za netfilter. Z uporabo rpfilter kot modula iptables lahko nastavimo dovolj prilagodljive pravilnike, na primer:
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 DROPvklopi rp_filter na vmesniku eth0.100 za vse naslove razen 1.2.3.0/24.
Izvor: habr.com
