تنظیم دقیق مسیریابی برای 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) آدرس به هر رابط گره ای (به عنوان مثال حلقه بک) متصل می شود. شایان ذکر است که در اینجا به ویژگی های پشته شبکه لینوکس اشاره می شود. مهم نیست که آدرس را به کدام رابط اضافه کنید، هسته همیشه درخواست‌های 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 آن را به اولین پاد ما هدایت کند، که درخواست اصلی را ایجاد کرد.

حل این مشکل دشوار بود، اما به لطف مسیریابی مبتنی بر سیاست ممکن شد:

برای درک بهتر فرآیند، در اینجا یک بلوک دیاگرام netfilter آورده شده است:
تنظیم دقیق مسیریابی برای 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 مسیریابی شوند.

یک چیز دیگر وجود دارد، در لینوکس یک فیلتر به اصطلاح مسیر معکوس وجود دارد که کل چیز را خراب می کند؛ یک بررسی ساده انجام می دهد: برای همه بسته های ورودی، آدرس منبع بسته را با آدرس فرستنده تغییر می دهد و بررسی می کند که آیا بسته می تواند از طریق همان رابطی که در آن دریافت شده است خارج شود، در غیر این صورت، آن را فیلتر می کند.

مشکل این است که در مورد ما به درستی کار نمی کند، اما می توانیم آن را غیرفعال کنیم:

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

اضافه کردن نظر