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): Այստեղ հարկ է նշել Linux ցանցային փաթեթի առանձնահատկությունները։ Անկախ նրանից, թե որ միջերեսին եք ավելացնում հասցեն, միջուկը միշտ կմշակի 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-proxy-ն աշխատում է 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-ում, և դուք ցանկանում եք դրանք օգտագործել Kubernetes-ի ծառայություններից արտաքին մուտք գործելու համար:

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, որը ստեղծեց սկզբնական հարցումը:

Այս խնդրի լուծումը դժվար էր, բայց դա հնարավոր դարձավ քաղաքականության վրա հիմնված երթուղիների շնորհիվ.

Գործընթացը ավելի լավ հասկանալու համար ահա netֆիլտրի բլոկային դիագրամ.
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.

Source: www.habr.com

Добавить комментарий