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