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.
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
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.
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:
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:
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