MetalLB:n reitityksen hienosäätö L2-tilassa

MetalLB:n reitityksen hienosäätö L2-tilassa
Jokin aika sitten kohtasin hyvin epätavallisen tehtävän MetalLB:n reitityksen määrittämisessä. Kaikki olisi hyvin, koska... Yleensä MetalLB ei vaadi lisätoimenpiteitä, mutta meidän tapauksessamme meillä on melko suuri klusteri hyvin yksinkertaisella verkkokokoonpanolla.

Tässä artikkelissa kerron sinulle, kuinka voit määrittää lähdepohjaisen ja käytäntöön perustuvan reitityksen klusterin ulkoiseen verkkoon.

En mene yksityiskohtiin MetalLB:n asentamisesta ja konfiguroinnista, koska oletan, että sinulla on jo kokemusta. Suosittelen siirtymistä suoraan asiaan, nimittäin reitityksen määrittämiseen. Meillä on siis neljä tapausta:

Tapaus 1: Kun määritystä ei tarvita

Katsotaanpa yksinkertaista tapausta.

MetalLB:n reitityksen hienosäätö L2-tilassa

Ylimääräisiä reititysmäärityksiä ei tarvita, kun MetalLB:n antamat osoitteet ovat samassa aliverkossa kuin solmujesi osoitteet.

Sinulla on esimerkiksi aliverkko 192.168.1.0/24, siinä on reititin 192.168.1.1, ja solmusi vastaanottavat osoitteet: 192.168.1.10-30, sitten MetalLB:lle voit säätää aluetta 192.168.1.100-120 ja varmista, että ne toimivat ilman lisämäärityksiä.

Miksi niin? Koska solmuissasi on jo määritettyjä reitit:

# 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

Ja saman alueen osoitteet käyttävät niitä uudelleen ilman lisätoimia.

Tapaus 2: Kun lisämuokkausta tarvitaan

MetalLB:n reitityksen hienosäätö L2-tilassa

Sinun tulee määrittää lisäreittejä aina, kun solmuillasi ei ole määritettyä IP-osoitetta tai reittiä aliverkkoon, jolle MetalLB myöntää osoitteita.

Selitän hieman tarkemmin. Aina kun MetalLB lähettää osoitteen, sitä voidaan verrata yksinkertaiseen tehtävään, kuten:

ip addr add 10.9.8.7/32 dev lo

Kiinnitä huomiota:

  • a) Osoite määritetään etuliitteen kanssa /32 eli reittiä ei lisätä automaattisesti sen aliverkkoon (se on vain osoite)
  • b) Osoite liitetään mihin tahansa solmuliitäntään (esimerkiksi silmukan takaisinkytkentä). Tässä kannattaa mainita Linux-verkkopinon ominaisuudet. Riippumatta siitä, mihin käyttöliittymään lisäät osoitteen, ydin käsittelee aina arp-pyynnöt ja lähettää arp-vastaukset mihin tahansa niistä, tätä käyttäytymistä pidetään oikeana ja lisäksi sitä käytetään melko laajalti sellaisessa dynaamisessa ympäristössä kuin Kubernetes.

Tätä toimintaa voidaan mukauttaa esimerkiksi ottamalla käyttöön tiukka arp:

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

Tässä tapauksessa arp-vastaukset lähetetään vain, jos käyttöliittymä sisältää nimenomaisesti tietyn IP-osoitteen. Tämä asetus on pakollinen, jos aiot käyttää MetalLB:tä ja kube-välityspalvelin toimii IPVS-tilassa.

MetalLB ei kuitenkaan käytä ydintä ARP-pyyntöjen käsittelyyn, vaan tekee sen itse käyttäjätilassa, joten tämä vaihtoehto ei vaikuta MetalLB:n toimintaan.

Palataan tehtäväämme. Jos annettujen osoitteiden reittiä ei ole solmuissasi, lisää se etukäteen kaikkiin solmuihin:

ip route add 10.9.8.0/24 dev eth1

Tapaus 3: Kun tarvitset lähdepohjaista reititystä

Sinun on määritettävä lähdepohjainen reititys, kun vastaanotat paketteja erillisen yhdyskäytävän kautta, ei oletusarvoisesti määritetyn yhdyskäytävän kautta, joten myös vastauspakettien tulisi kulkea saman yhdyskäytävän kautta.

Sinulla on esimerkiksi sama aliverkko 192.168.1.0/24 omistettu solmullesi, mutta haluat antaa ulkoisia osoitteita MetalLB:n avulla. Oletetaan, että sinulla on useita osoitteita aliverkosta 1.2.3.0/24 sijaitsevat VLAN 100:ssa ja haluat käyttää niitä Kubernetes-palveluihin ulkoisesti.

MetalLB:n reitityksen hienosäätö L2-tilassa

Kun otat yhteyttä 1.2.3.4 teet pyyntöjä eri aliverkosta kuin 1.2.3.0/24 ja odottaa vastausta. Solmu, joka on tällä hetkellä MetalLB:n myöntämän osoitteen isäntä 1.2.3.4, vastaanottaa paketin reitittimeltä 1.2.3.1, mutta vastauksen hänelle on välttämättä mentävä samaa reittiä läpi 1.2.3.1.

Koska solmullamme on jo määritetty oletusyhdyskäytävä 192.168.1.1, oletuksena vastaus lähetetään hänelle, ei 1.2.3.1, jonka kautta saimme paketin.

Kuinka selviytyä tästä tilanteesta?

Tässä tapauksessa sinun on valmisteltava kaikki solmusi siten, että ne ovat valmiita palvelemaan ulkoisia osoitteita ilman lisämäärityksiä. Eli yllä olevaa esimerkkiä varten sinun on luotava VLAN-liitäntä solmuun etukäteen:

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

Ja sitten lisää reitit:

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

Huomaa, että lisäämme reitit erilliseen reititystaulukkoon 100 se sisältää vain kaksi reittiä, jotka tarvitaan vastauspaketin lähettämiseen yhdyskäytävän kautta 1.2.3.1, joka sijaitsee käyttöliittymän takana eth0.100.

Nyt meidän on lisättävä yksinkertainen sääntö:

ip rule add from 1.2.3.0/24 lookup 100

joka sanoo nimenomaisesti: jos paketin lähdeosoite on 1.2.3.0/24, sinun on käytettävä reititystaulukkoa 100. Siinä olemme jo kuvanneet reitin, joka lähettää hänet läpi 1.2.3.1

Tapaus 4: Kun tarvitset käytäntöön perustuvaa reititystä

Verkkotopologia on sama kuin edellisessä esimerkissä, mutta oletetaan, että haluat päästä käsiksi myös ulkoisiin poolin osoitteisiin 1.2.3.0/24 podistasi:

MetalLB:n reitityksen hienosäätö L2-tilassa

Erikoisuus on, että kun käytät mitä tahansa osoitetta 1.2.3.0/24, vastauspaketti osuu solmuun ja sen lähdeosoite on alueella 1.2.3.0/24 lähetetään kuuliaisesti eth0.100, mutta haluamme Kubernetesin ohjaavan sen ensimmäiseen podiimme, joka loi alkuperäisen pyynnön.

Tämän ongelman ratkaiseminen osoittautui vaikeaksi, mutta se tuli mahdolliseksi käytäntöihin perustuvan reitityksen ansiosta:

Prosessin ymmärtämiseksi paremmin, tässä on netfilterin lohkokaavio:
MetalLB:n reitityksen hienosäätö L2-tilassa

Ensin, kuten edellisessä esimerkissä, luodaan ylimääräinen reititystaulukko:

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

Lisätään nyt muutama sääntö iptablesiin:

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

Nämä säännöt merkitsevät liittymään saapuvat yhteydet eth0.100, merkitsee kaikki paketit tunnisteella 0x100, saman yhteyden vastaukset merkitään myös samalla tunnisteella.

Nyt voimme lisätä reitityssäännön:

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

Eli kaikki paketit, joilla on lähdeosoite 1.2.3.0/24 ja tagi 0x100 tulee reitittää taulukon avulla 100.

Näin ollen muut paketit, jotka on vastaanotettu toisella rajapinnalla, eivät ole tämän säännön alaisia, mikä mahdollistaa niiden reitittämisen tavallisilla Kubernetes-työkaluilla.

On vielä yksi asia, Linuxissa on niin sanottu käänteinen polkusuodatin, joka pilaa koko asian, se suorittaa yksinkertaisen tarkistuksen: kaikille saapuville paketeille se muuttaa paketin lähdeosoitteen lähettäjän osoitteella ja tarkistaa, onko paketti voi lähteä saman rajapinnan kautta, josta se vastaanotettiin, jos ei, se suodattaa sen pois.

Ongelmana on, että meidän tapauksessamme se ei toimi oikein, mutta voimme poistaa sen käytöstä:

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

Huomaa, että ensimmäinen komento ohjaa rp_filterin yleistä toimintaa; jos sitä ei ole poistettu käytöstä, toisella komennolla ei ole vaikutusta. Loput liitännät jäävät kuitenkin rp_filter käyttöön.

Jotta suodattimen toimintaa ei rajoiteta kokonaan, voimme käyttää netfilterin rp_filter-toteutusta. Käyttämällä rpfilteriä iptables-moduulina voit määrittää melko joustavia sääntöjä, esimerkiksi:

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

Ota rp_filter käyttöön käyttöliittymässä eth0.100 kaikille osoitteille paitsi 1.2.3.0/24.

Lähde: will.com

Lisää kommentti