Fajnagorda vojigo por MetalLB en L2-reĝimo

Fajnagorda vojigo por MetalLB en L2-reĝimo
Antaŭ nelonge mi estis alfrontita kun tre nekutima tasko agordi vojigon por MetalLB. Ĉio estus en ordo, ĉar... Kutime MetalLB ne postulas iujn ajn aldonajn agojn, sed en nia kazo ni havas sufiĉe grandan areton kun tre simpla reta agordo.

En ĉi tiu artikolo mi rakontos al vi kiel agordi font-bazitan kaj politik-bazitan vojigon por la ekstera reto de via areto.

Mi ne eniros en detalojn pri instalo kaj agordo de MetalLB, ĉar mi supozas, ke vi jam havas iom da sperto. Mi sugestas iri rekte al la punkto, nome agordi vojigon. Do ni havas kvar kazojn:

Kazo 1: Kiam neniu agordo estas bezonata

Ni rigardu simplan kazon.

Fajnagorda vojigo por MetalLB en L2-reĝimo

Plia envojiga agordo ne estas bezonata kiam la adresoj eldonitaj de MetalLB estas en la sama subreto kiel la adresoj de viaj nodoj.

Ekzemple, vi havas subreton 192.168.1.0/24, ĝi havas enkursigilon 192.168.1.1, kaj viaj nodoj ricevas adresojn: 192.168.1.10-30, tiam por MetalLB vi povas ĝustigi la intervalon 192.168.1.100-120 kaj estu certa, ke ili funkcios sen ia aldona agordo.

Kial estas tio? Ĉar viaj nodoj jam havas itinerojn agorditaj:

# 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

Kaj adresoj de la sama gamo reuzos ilin sen aldonaj agoj.

Kazo 2: Kiam aldona personigo estas postulata

Fajnagorda vojigo por MetalLB en L2-reĝimo

Vi devus agordi pliajn itinerojn kiam ajn viaj nodoj ne havas agordita IP-adreso aŭ itinero al la subreto por kiu MetalLB eldonas adresojn.

Mi klarigos iom pli detale. Kiam ajn MetalLB eligas adreson, ĝi povas esti komparita kun simpla tasko kiel:

ip addr add 10.9.8.7/32 dev lo

Atentu:

  • a) La adreso estas asignita kun prefikso /32 tio estas, itinero ne estos aŭtomate aldonita al la subreto por ĝi (ĝi estas nur adreso)
  • b) La adreso estas ligita al iu ajn noda interfaco (ekzemple loopback). Indas mencii ĉi tie la funkciojn de la Linukso-reta stako. Ne gravas al kiu interfaco vi aldonas la adreson, la kerno ĉiam prilaboros arp-petojn kaj sendos arp-respondojn al iu ajn el ili, ĉi tiu konduto estas konsiderata ĝusta kaj, krome, estas sufiĉe vaste uzata en tia dinamika medio kiel Kubernetes.

Ĉi tiu konduto povas esti personecigita, ekzemple ebligante striktan arp:

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

En ĉi tiu kazo, arp-respondoj nur estos senditaj se la interfaco eksplicite enhavas specifan IP-adreson. Ĉi tiu agordo estas postulata se vi planas uzi MetalLB kaj via kube-proxy funkcias en IPVS-reĝimo.

Tamen, MetalLB ne uzas la kernon por prilabori arp-petojn, sed faras ĝin mem en uzantspaco, do ĉi tiu opcio ne influos la funkciadon de MetalLB.

Ni revenu al nia tasko. Se la itinero por la eldonitaj adresoj ne ekzistas sur viaj nodoj, aldonu ĝin anticipe al ĉiuj nodoj:

ip route add 10.9.8.0/24 dev eth1

Kazo 3: Kiam vi bezonas font-bazitan vojigon

Vi devos agordi font-bazitan vojigon kiam vi ricevas pakaĵojn tra aparta enirejo, ne tiu agordita defaŭlte, tial respondpakoj ankaŭ devus iri tra la sama enirejo.

Ekzemple, vi havas la saman subreton 192.168.1.0/24 dediĉita al viaj nodoj, sed vi volas elsendi eksterajn adresojn uzante MetalLB. Ni supozu, ke vi havas plurajn adresojn de subreto 1.2.3.0/24 situas en VLAN 100 kaj vi volas uzi ilin por aliri Kubernetes-servojn ekstere.

Fajnagorda vojigo por MetalLB en L2-reĝimo

Kiam oni kontaktas 1.2.3.4 vi faros petojn de alia subreto ol 1.2.3.0/24 kaj atendu respondon. La nodo kiu estas nuntempe la majstro por la MetalLB-eldonita adreso 1.2.3.4, ricevos la pakaĵon de la enkursigilo 1.2.3.1, sed la respondo por li devas nepre iri la saman vojon, tra 1.2.3.1.

Ĉar nia nodo jam havas agordita defaŭlta enirejo 192.168.1.1, tiam defaŭlte la respondo iros al li, kaj ne al 1.2.3.1, per kiu ni ricevis la pakaĵon.

Kiel trakti ĉi tiun situacion?

En ĉi tiu kazo, vi devas prepari ĉiujn viajn nodojn tiel, ke ili pretas servi eksterajn adresojn sen plia agordo. Tio estas, por la supra ekzemplo, vi devas krei VLAN-interfacon sur la nodo anticipe:

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

Kaj poste aldonu itinerojn:

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

Bonvolu noti, ke ni aldonas itinerojn al aparta vojtabelo 100 ĝi enhavos nur du vojojn necesajn por sendi respondpakaĵon tra la enirejo 1.2.3.1, situanta malantaŭ la interfaco eth0.100.

Nun ni devas aldoni simplan regulon:

ip rule add from 1.2.3.0/24 lookup 100

kiu eksplicite diras: se la fontadreso de la pako estas en 1.2.3.0/24, tiam vi devas uzi la vojtablon 100. En ĝi ni jam priskribis la vojon, kiu sendos lin 1.2.3.1

Kazo 4: Kiam vi bezonas politiko-bazitan vojigon

La retotopologio estas la sama kiel en la antaŭa ekzemplo, sed ni diru, ke vi ankaŭ volas povi aliri eksterajn naĝejojn. 1.2.3.0/24 el viaj balgoj:

Fajnagorda vojigo por MetalLB en L2-reĝimo

La propreco estas, ke kiam oni aliras ajnan adreson en 1.2.3.0/24, la respondpakaĵo trafas la nodon kaj havas fontadreson en la intervalo 1.2.3.0/24 estos obeeme sendita al eth0.100, sed ni volas, ke Kubernetes redirektu ĝin al nia unua pod, kiu generis la originan peton.

Solvi ĉi tiun problemon montriĝis malfacila, sed ĝi fariĝis ebla danke al politiko-bazita vojigo:

Por pli bona kompreno de la procezo, jen netfilter-blokdiagramo:
Fajnagorda vojigo por MetalLB en L2-reĝimo

Unue, kiel en la antaŭa ekzemplo, ni kreu plian vojigtabelon:

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

Nun ni aldonu kelkajn regulojn al 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-mark

Ĉi tiuj reguloj markos venontajn konektojn al la interfaco eth0.100, markante ĉiujn pakaĵojn per la etikedo 0x100, respondoj ene de la sama konekto ankaŭ estos markitaj per la sama etikedo.

Nun ni povas aldoni vojregulon:

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

Tio estas, ĉiuj pakoj kun fontadreso 1.2.3.0/24 kaj etikedo 0x100 devas esti sendita per tabelo 100.

Tiel, aliaj pakaĵoj ricevitaj sur alia interfaco ne estas submetitaj al ĉi tiu regulo, kio permesos ilin esti direktitaj per normaj Kubernetes-iloj.

Estas ankoraŭ unu afero, en Linukso ekzistas tiel nomata inversa voja filtrilo, kiu difektas la tuton; ĝi faras simplan kontrolon: por ĉiuj envenantaj pakaĵoj, ĝi ŝanĝas la fontadreson de la pako kun la sendinta adreso kaj kontrolas ĉu la pako povas eliri tra la sama interfaco sur kiu ĝi estis ricevita, se ne, ĝi elfiltros ĝin.

La problemo estas, ke en nia kazo ĝi ne funkcios ĝuste, sed ni povas malŝalti ĝin:

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

Bonvolu noti, ke la unua komando kontrolas la tutmondan konduton de rp_filter; se ĝi ne estas malŝaltita, la dua komando ne havos efikon. Tamen, la ceteraj interfacoj restos kun rp_filter ebligita.

Por ne tute limigi la funkciadon de la filtrilo, ni povas uzi la efektivigon rp_filter por netfilter. Uzante rpfilter kiel iptables-modulon, vi povas agordi sufiĉe flekseblajn regulojn, ekzemple:

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

ebligu rp_filter sur la interfaco eth0.100 por ĉiuj adresoj krom 1.2.3.0/24.

fonto: www.habr.com

Aldoni komenton