Фино подесување на рутирање за MetalLB во режим L2

Фино подесување на рутирање за MetalLB во режим L2
Не така одамна се соочив со многу необична задача да поставам рутирање за MetalLB. Сè би било добро, бидејќи ... Обично MetalLB не бара никакви дополнителни дејства, но во нашиот случај имаме прилично голем кластер со многу едноставна мрежна конфигурација.

Во оваа статија ќе ви кажам како да конфигурирате рутирање базирано на извор и политика за надворешната мрежа на вашиот кластер.

Нема да навлегувам во детали за инсталирање и конфигурирање на MetalLB, бидејќи претпоставувам дека веќе имате одредено искуство. Предлагам да одиме директно на поентата, имено поставување на рутирање. Значи, имаме четири случаи:

Случај 1: Кога не е потребна конфигурација

Ајде да погледнеме во едноставен случај.

Фино подесување на рутирање за MetalLB во режим L2

Не е потребна дополнителна конфигурација за рутирање кога адресите издадени од MetalLB се во истата подмрежа како и адресите на вашите јазли.

На пример, имате подмрежа 192.168.1.0/24, има рутер 192.168.1.1, и вашите јазли добиваат адреси: 192.168.1.10-30, потоа за MetalLB можете да го прилагодите опсегот 192.168.1.100-120 и бидете сигурни дека ќе работат без дополнителна конфигурација.

Зошто е тоа? Бидејќи вашите јазли веќе имаат конфигурирани правци:

# 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

И адресите од истиот опсег ќе ги користат повторно без никакви дополнителни дејства.

Случај 2: Кога е потребно дополнително прилагодување

Фино подесување на рутирање за MetalLB во режим L2

Треба да конфигурирате дополнителни правци секогаш кога вашите јазли немаат конфигурирана IP адреса или маршрута до подмрежата за која адресира издавањето на MetalLB.

Ќе објаснам малку подетално. Секогаш кога MetalLB дава адреса, таа може да се спореди со едноставна задача како:

ip addr add 10.9.8.7/32 dev lo

Обрни внимание на:

  • a) Адресата е доделена со префикс /32 односно, рутата нема автоматски да се додаде во подмрежата за неа (тоа е само адреса)
  • b) Адресата е прикачена на кој било интерфејс на јазол (на пример, loopback). Овде вреди да се споменат карактеристиките на стекот на мрежата Линукс. Без разлика на кој интерфејс ќе ја додадете адресата, кернелот секогаш ќе обработува arp-барања и ќе испраќа одговори на arp на кое било од нив, ова однесување се смета за правилно и, згора на тоа, е доста широко користено во таква динамична средина како Kubernetes.

Ова однесување може да се приспособи, на пример, со овозможување строг arp:

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

Во овој случај, одговорите на arp ќе се испраќаат само ако интерфејсот експлицитно содржи одредена IP адреса. Оваа поставка е потребна ако планирате да користите MetalLB и вашиот kube-прокси работи во режим IPVS.

Меѓутоа, MetalLB не го користи кернелот за обработка на барањата arp, туку тоа го прави самиот во корисничкиот простор, така што оваа опција нема да влијае на работата на MetalLB.

Да се ​​вратиме на нашата задача. Ако рутата за издадените адреси не постои на вашите јазли, додајте ја однапред на сите јазли:

ip route add 10.9.8.0/24 dev eth1

Случај 3: Кога ви треба рутирање базирано на извор

Ќе треба да конфигурирате рутирање базирано на извор кога примате пакети преку посебна порта, а не онаа што е стандардно конфигурирана, затоа пакетите за одговор исто така треба да поминуваат низ истата порта.

На пример, ја имате истата подмрежа 192.168.1.0/24 посветен на вашите јазли, но сакате да издавате надворешни адреси користејќи MetalLB. Да претпоставиме дека имате повеќе адреси од подмрежа 1.2.3.0/24 се наоѓа во VLAN 100 и сакате да ги користите за надворешно пристап до услугите на Кубернетес.

Фино подесување на рутирање за MetalLB во режим L2

При контактирање 1.2.3.4 ќе поднесувате барања од друга подмрежа од 1.2.3.0/24 и чекај одговор. Јазолот кој моментално е главен за адресата издадена од MetalLB 1.2.3.4, ќе го прими пакетот од рутерот 1.2.3.1, но одговорот за него мора нужно да оди по истиот пат, низ 1.2.3.1.

Бидејќи нашиот јазол веќе има конфигуриран стандарден портал 192.168.1.1, тогаш стандардно одговорот ќе оди кај него, а не до 1.2.3.1, преку кој го добивме пакетот.

Како да се справите со оваа ситуација?

Во овој случај, треба да ги подготвите сите ваши јазли на таков начин што тие се подготвени да опслужуваат надворешни адреси без дополнителна конфигурација. Тоа е, за горенаведениот пример, треба однапред да креирате VLAN интерфејс на јазолот:

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

И потоа додадете маршрути:

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

Ве молиме имајте предвид дека додаваме маршрути во посебна рутирачка табела 100 ќе содржи само две рути неопходни за испраќање на пакет одговор преку портата 1.2.3.1, кој се наоѓа зад интерфејсот eth0.100.

Сега треба да додадеме едноставно правило:

ip rule add from 1.2.3.0/24 lookup 100

кој експлицитно вели: ако изворната адреса на пакетот е внатре 1.2.3.0/24, тогаш треба да ја користите рутирачката табела 100. Во него веќе ја опишавме рутата по која ќе го испрати 1.2.3.1

Случај 4: Кога ви треба рутирање засновано на политики

Топологијата на мрежата е иста како и во претходниот пример, но да речеме дека сакате да имате пристап до адресите на надворешниот базен 1.2.3.0/24 од вашите мешунки:

Фино подесување на рутирање за MetalLB во режим L2

Особеноста е во тоа што при пристапување кон која било адреса во 1.2.3.0/24, пакетот одговор го погодува јазолот и има изворна адреса во опсегот 1.2.3.0/24 ќе биде послушно испратен до eth0.100, но сакаме Kubernetes да го пренасочи кон нашиот прв pod, кој го генерира оригиналното барање.

Решавањето на овој проблем се покажа како тешко, но стана возможно благодарение на рутирањето засновано на политики:

За подобро разбирање на процесот, тука е блок дијаграм на нетфилтер:
Фино подесување на рутирање за MetalLB во режим L2

Прво, како и во претходниот пример, ајде да создадеме дополнителна рутирачка табела:

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

Сега да додадеме неколку правила на 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

Овие правила ќе ги означат дојдовните врски со интерфејсот eth0.100, означувајќи ги сите пакети со ознаката 0x100, одговорите во рамките на истата врска исто така ќе бидат означени со истата ознака.

Сега можеме да додадеме правило за рутирање:

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

Тоа е, сите пакети со изворна адреса 1.2.3.0/24 и означете 0x100 мора да се насочи со помош на табела 100.

Така, другите пакети добиени на друг интерфејс не подлежат на ова правило, што ќе им овозможи да се насочуваат со користење на стандардни алатки на Kubernetes.

Има уште една работа, во Linux постои таканаречен филтер за обратна патека, кој ја расипува целата работа, врши едноставна проверка: за сите дојдовни пакети, ја менува изворната адреса на пакетот со адресата на испраќачот и проверува дали пакетот може да замине преку истиот интерфејс на кој е примен, ако не, ќе го филтрира.

Проблемот е што во нашиот случај нема да работи правилно, но можеме да го оневозможиме:

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

Ве молиме имајте предвид дека првата команда го контролира глобалното однесување на rp_filter; ако не е оневозможено, втората команда нема да има ефект. Сепак, преостанатите интерфејси ќе останат со вклучен rp_filter.

За да не ја ограничиме целосно работата на филтерот, можеме да ја користиме имплементацијата rp_filter за netfilter. Користејќи rpfilter како модул iptables, можете да конфигурирате прилично флексибилни правила, на пример:

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

овозможете rp_filter на интерфејсот eth0.100 за сите адреси освен 1.2.3.0/24.

Извор: www.habr.com

Додадете коментар