Penalaan halus untuk MetalLB dalam mod L2

Penalaan halus untuk MetalLB dalam mod L2
Tidak lama dahulu saya berhadapan dengan tugas yang sangat luar biasa untuk menyediakan penghalaan untuk MetalLB. Semuanya akan baik-baik saja, kerana... Biasanya MetalLB tidak memerlukan sebarang tindakan tambahan, tetapi dalam kes kami, kami mempunyai kluster yang agak besar dengan konfigurasi rangkaian yang sangat mudah.

Dalam artikel ini saya akan memberitahu anda cara mengkonfigurasi penghalaan berasaskan sumber dan berasaskan dasar untuk rangkaian luaran kluster anda.

Saya tidak akan menerangkan secara terperinci tentang memasang dan mengkonfigurasi MetalLB, kerana saya menganggap anda sudah mempunyai pengalaman. Saya cadangkan pergi terus ke intinya, iaitu menyediakan penghalaan. Jadi kami mempunyai empat kes:

Kes 1: Apabila tiada konfigurasi diperlukan

Mari kita lihat kes mudah.

Penalaan halus untuk MetalLB dalam mod L2

Konfigurasi penghalaan tambahan tidak diperlukan apabila alamat yang dikeluarkan oleh MetalLB berada dalam subnet yang sama dengan alamat nod anda.

Sebagai contoh, anda mempunyai subnet 192.168.1.0/24, ia mempunyai penghala 192.168.1.1, dan nod anda menerima alamat: 192.168.1.10-30, kemudian untuk MetalLB anda boleh melaraskan julat 192.168.1.100-120 dan pastikan ia akan berfungsi tanpa sebarang konfigurasi tambahan.

Kenapa begitu? Kerana nod anda sudah mempunyai laluan yang dikonfigurasikan:

# 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

Dan alamat dari julat yang sama akan menggunakannya semula tanpa sebarang tindakan tambahan.

Kes 2: Apabila penyesuaian tambahan diperlukan

Penalaan halus untuk MetalLB dalam mod L2

Anda harus mengkonfigurasi laluan tambahan apabila nod anda tidak mempunyai alamat IP yang dikonfigurasikan atau laluan ke subnet yang mana MetalLB mengeluarkan alamat.

Saya akan menerangkan dengan lebih terperinci. Apabila MetalLB mengeluarkan alamat, ia boleh dibandingkan dengan tugasan mudah seperti:

ip addr add 10.9.8.7/32 dev lo

Beri perhatian kepada:

  • a) Alamat diberikan dengan awalan /32 iaitu, laluan tidak akan ditambahkan secara automatik ke subnet untuknya (ia hanya alamat)
  • b) Alamat dilampirkan pada mana-mana antara muka nod (contohnya loopback). Perlu disebutkan di sini ciri-ciri susunan rangkaian Linux. Tidak kira antara muka yang anda tambahkan alamat, kernel akan sentiasa memproses permintaan arp dan menghantar respons arp kepada mana-mana daripada mereka, tingkah laku ini dianggap betul dan, lebih-lebih lagi, digunakan secara meluas dalam persekitaran yang dinamik seperti Kubernetes.

Tingkah laku ini boleh disesuaikan, contohnya dengan mendayakan arp ketat:

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

Dalam kes ini, respons arp hanya akan dihantar jika antara muka secara eksplisit mengandungi alamat IP tertentu. Tetapan ini diperlukan jika anda merancang untuk menggunakan MetalLB dan kube-proxy anda berjalan dalam mod IPVS.

Walau bagaimanapun, MetalLB tidak menggunakan kernel untuk memproses permintaan arp, tetapi melakukannya sendiri dalam ruang pengguna, jadi pilihan ini tidak akan menjejaskan operasi MetalLB.

Mari kita kembali kepada tugas kita. Jika laluan untuk alamat yang dikeluarkan tidak wujud pada nod anda, tambahkannya terlebih dahulu pada semua nod:

ip route add 10.9.8.0/24 dev eth1

Kes 3: Apabila anda memerlukan penghalaan berasaskan sumber

Anda perlu mengkonfigurasi penghalaan berasaskan sumber apabila anda menerima paket melalui get laluan yang berasingan, bukan yang dikonfigurasikan secara lalai, oleh itu paket respons juga harus melalui get laluan yang sama.

Sebagai contoh, anda mempunyai subnet yang sama 192.168.1.0/24 khusus untuk nod anda, tetapi anda ingin mengeluarkan alamat luaran menggunakan MetalLB. Katakan anda mempunyai berbilang alamat daripada subnet 1.2.3.0/24 terletak dalam VLAN 100 dan anda mahu menggunakannya untuk mengakses perkhidmatan Kubernetes secara luaran.

Penalaan halus untuk MetalLB dalam mod L2

Apabila menghubungi 1.2.3.4 anda akan membuat permintaan daripada subnet yang berbeza daripada 1.2.3.0/24 dan tunggu jawapan. Nod yang kini menjadi induk untuk alamat yang dikeluarkan MetalLB 1.2.3.4, akan menerima paket daripada penghala 1.2.3.1, tetapi jawapan untuknya semestinya mesti melalui laluan yang sama, melalui 1.2.3.1.

Memandangkan nod kami sudah mempunyai gerbang lalai yang dikonfigurasikan 192.168.1.1, maka secara lalai respons akan pergi kepadanya, dan bukan kepada 1.2.3.1, yang melaluinya kami menerima pakej tersebut.

Bagaimana untuk menghadapi situasi ini?

Dalam kes ini, anda perlu menyediakan semua nod anda sedemikian rupa sehingga mereka bersedia untuk menyampaikan alamat luaran tanpa konfigurasi tambahan. Iaitu, untuk contoh di atas, anda perlu membuat antara muka VLAN pada nod terlebih dahulu:

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

Dan kemudian tambah laluan:

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

Sila ambil perhatian bahawa kami menambah laluan pada jadual penghalaan yang berasingan 100 ia akan mengandungi hanya dua laluan yang diperlukan untuk menghantar paket respons melalui get laluan 1.2.3.1, terletak di belakang antara muka eth0.100.

Sekarang kita perlu menambah peraturan mudah:

ip rule add from 1.2.3.0/24 lookup 100

yang secara eksplisit mengatakan: jika alamat sumber paket ada 1.2.3.0/24, maka anda perlu menggunakan jadual penghalaan 100. Di dalamnya kami telah menerangkan laluan yang akan menghantarnya melaluinya 1.2.3.1

Kes 4: Apabila anda memerlukan penghalaan berasaskan dasar

Topologi rangkaian adalah sama seperti dalam contoh sebelumnya, tetapi katakan anda juga mahu boleh mengakses alamat kumpulan luaran 1.2.3.0/24 daripada pod anda:

Penalaan halus untuk MetalLB dalam mod L2

Keanehannya ialah apabila mengakses mana-mana alamat dalam 1.2.3.0/24, paket tindak balas mencecah nod dan mempunyai alamat sumber dalam julat 1.2.3.0/24 akan dihantar dengan patuh kepada eth0.100, tetapi kami mahu Kubernetes mengubah halanya ke pod pertama kami, yang menghasilkan permintaan asal.

Menyelesaikan masalah ini ternyata sukar, tetapi ia menjadi mungkin berkat penghalaan berasaskan dasar:

Untuk pemahaman yang lebih baik tentang proses tersebut, berikut ialah gambarajah blok netfilter:
Penalaan halus untuk MetalLB dalam mod L2

Pertama, seperti dalam contoh sebelumnya, mari kita buat jadual penghalaan tambahan:

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

Sekarang mari tambahkan beberapa peraturan pada 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

Peraturan ini akan menandakan sambungan masuk ke antara muka eth0.100, menandakan semua paket dengan tag 0x100, respons dalam sambungan yang sama juga akan ditandakan dengan teg yang sama.

Sekarang kita boleh menambah peraturan penghalaan:

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

Iaitu, semua paket dengan alamat sumber 1.2.3.0/24 dan tag 0x100 mesti dihalakan menggunakan jadual 100.

Oleh itu, paket lain yang diterima pada antara muka lain tidak tertakluk kepada peraturan ini, yang akan membolehkan mereka dihalakan menggunakan alat Kubernetes standard.

Terdapat satu perkara lagi, di Linux terdapat penapis laluan terbalik yang dipanggil, yang merosakkan keseluruhannya; ia melakukan pemeriksaan mudah: untuk semua paket masuk, ia menukar alamat sumber paket dengan alamat pengirim dan memeriksa sama ada paket boleh keluar melalui antara muka yang sama di mana ia diterima, jika tidak, ia akan menapisnya.

Masalahnya ialah dalam kes kami ia tidak akan berfungsi dengan betul, tetapi kami boleh melumpuhkannya:

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

Sila ambil perhatian bahawa arahan pertama mengawal tingkah laku global rp_filter; jika ia tidak dilumpuhkan, arahan kedua tidak akan memberi kesan. Walau bagaimanapun, antara muka yang selebihnya akan kekal dengan rp_filter didayakan.

Untuk tidak mengehadkan sepenuhnya operasi penapis, kita boleh menggunakan pelaksanaan rp_filter untuk netfilter. Menggunakan rpfilter sebagai modul iptables, anda boleh mengkonfigurasi peraturan yang agak fleksibel, contohnya:

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

dayakan rp_filter pada antara muka eth0.100 untuk semua alamat kecuali 1.2.3.0/24.

Sumber: www.habr.com

Tambah komen