Belum lama ini saya dihadapkan dengan tugas yang sangat tidak biasa dalam menyiapkan perutean untuk MetalLB. Semuanya akan baik-baik saja, karena... Biasanya MetalLB tidak memerlukan tindakan tambahan apa pun, tetapi dalam kasus kami, kami memiliki cluster yang cukup besar dengan konfigurasi jaringan yang sangat sederhana.
Pada artikel ini saya akan memberi tahu Anda cara mengonfigurasi perutean berbasis sumber dan berbasis kebijakan untuk jaringan eksternal cluster Anda.
Saya tidak akan menjelaskan secara detail tentang menginstal dan mengkonfigurasi MetalLB, karena saya berasumsi Anda sudah memiliki pengalaman. Saya sarankan langsung ke intinya yaitu mengatur routing. Jadi kita punya empat kasus:
Kasus 1: Ketika tidak diperlukan konfigurasi
Mari kita lihat kasus sederhana.
Konfigurasi perutean tambahan tidak diperlukan bila alamat yang dikeluarkan oleh MetalLB berada di subnet yang sama dengan alamat node Anda.
Misalnya, Anda memiliki subnet 192.168.1.0/24
, ia memiliki router 192.168.1.1
, dan node Anda menerima alamat: 192.168.1.10-30
, lalu untuk MetalLB Anda dapat menyesuaikan rentangnya 192.168.1.100-120
dan pastikan semuanya akan berfungsi tanpa konfigurasi tambahan apa pun.
Mengapa demikian? Karena node Anda sudah memiliki rute yang dikonfigurasi:
# 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 rentang yang sama akan menggunakannya kembali tanpa tindakan tambahan apa pun.
Kasus 2: Ketika penyesuaian tambahan diperlukan
Anda harus mengonfigurasi rute tambahan setiap kali node Anda tidak memiliki alamat IP yang dikonfigurasi atau rute ke subnet yang alamatnya dikeluarkan oleh MetalLB.
Saya akan menjelaskannya sedikit lebih detail. Setiap kali MetalLB mengeluarkan sebuah alamat, itu dapat dibandingkan dengan tugas sederhana seperti:
ip addr add 10.9.8.7/32 dev lo
Perhatikan:
- a) Alamat diberikan dengan awalan
/32
artinya, rute tidak akan secara otomatis ditambahkan ke subnet untuk itu (itu hanya sebuah alamat) - b) Alamat tersebut dilampirkan ke antarmuka node mana pun (misalnya loopback). Perlu disebutkan di sini fitur tumpukan jaringan Linux. Tidak peduli antarmuka mana yang Anda tambahkan alamatnya, kernel akan selalu memproses permintaan arp dan mengirimkan respons arp ke salah satu permintaan tersebut, perilaku ini dianggap benar dan, terlebih lagi, cukup banyak digunakan dalam lingkungan dinamis seperti Kubernetes.
Perilaku ini dapat disesuaikan, misalnya dengan mengaktifkan arp ketat:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
Dalam hal ini, tanggapan arp hanya akan dikirim jika antarmuka secara eksplisit berisi alamat IP tertentu. Pengaturan ini diperlukan jika Anda berencana menggunakan MetalLB dan kube-proxy Anda berjalan dalam mode IPVS.
Namun, MetalLB tidak menggunakan kernel untuk memproses permintaan arp, tetapi melakukannya sendiri di ruang pengguna, jadi opsi ini tidak akan memengaruhi pengoperasian MetalLB.
Mari kita kembali ke tugas kita. Jika rute untuk alamat yang dikeluarkan tidak ada di node Anda, tambahkan terlebih dahulu ke semua node:
ip route add 10.9.8.0/24 dev eth1
Kasus 3: Saat Anda memerlukan perutean berbasis sumber
Anda perlu mengonfigurasi perutean berbasis sumber ketika Anda menerima paket melalui gateway terpisah, bukan yang dikonfigurasi secara default, oleh karena itu paket respons juga harus melalui gateway yang sama.
Misalnya, Anda memiliki subnet yang sama 192.168.1.0/24
didedikasikan untuk node Anda, tetapi Anda ingin mengeluarkan alamat eksternal menggunakan MetalLB. Anggaplah Anda memiliki beberapa alamat dari satu subnet 1.2.3.0/24
terletak di VLAN 100 dan Anda ingin menggunakannya untuk mengakses layanan Kubernetes secara eksternal.
Saat menghubungi 1.2.3.4
Anda akan membuat permintaan dari subnet yang berbeda 1.2.3.0/24
dan menunggu jawabannya. Node yang saat ini menjadi master untuk alamat yang dikeluarkan MetalLB 1.2.3.4
, akan menerima paket dari router 1.2.3.1
, tapi jawabannya tentu harus melalui jalur yang sama, lewat 1.2.3.1
.
Karena node kita sudah memiliki gateway default yang dikonfigurasi 192.168.1.1
, maka secara default responsnya akan ditujukan kepadanya, bukan ke sana 1.2.3.1
, melalui mana kami menerima paket tersebut.
Bagaimana cara mengatasi situasi ini?
Dalam hal ini, Anda perlu mempersiapkan semua node Anda sedemikian rupa sehingga siap melayani alamat eksternal tanpa konfigurasi tambahan. Artinya, untuk contoh di atas, Anda perlu membuat antarmuka VLAN pada node terlebih dahulu:
ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 up
Dan kemudian tambahkan rute:
ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100
Harap dicatat bahwa kami menambahkan rute ke tabel perutean terpisah 100
itu hanya akan berisi dua rute yang diperlukan untuk mengirim paket respons melalui gateway 1.2.3.1
, terletak di belakang antarmuka eth0.100
.
Sekarang kita perlu menambahkan aturan sederhana:
ip rule add from 1.2.3.0/24 lookup 100
yang secara eksplisit mengatakan: jika alamat sumber paket ada di 1.2.3.0/24
, maka Anda perlu menggunakan tabel perutean 100
. Di dalamnya kami telah menjelaskan rute yang akan dilaluinya 1.2.3.1
Kasus 4: Saat Anda memerlukan perutean berbasis kebijakan
Topologi jaringannya sama seperti pada contoh sebelumnya, tetapi misalkan Anda juga ingin dapat mengakses alamat pool eksternal 1.2.3.0/24
dari pod Anda:
Keunikannya adalah ketika mengakses alamat apa pun di 1.2.3.0/24
, paket respons mencapai node dan memiliki alamat sumber dalam jangkauan 1.2.3.0/24
akan dengan patuh dikirim ke eth0.100
, tapi kami ingin Kubernetes mengalihkannya ke pod pertama kami, yang menghasilkan permintaan asli.
Menyelesaikan masalah ini ternyata sulit, namun menjadi mungkin berkat perutean berbasis kebijakan:
Untuk pemahaman yang lebih baik tentang prosesnya, berikut adalah diagram blok netfilter:
Pertama, seperti pada contoh sebelumnya, mari buat tabel routing 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 aturan ke 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
Aturan-aturan ini akan menandai koneksi masuk ke antarmuka eth0.100
, menandai semua paket dengan tag 0x100
, tanggapan dalam koneksi yang sama juga akan ditandai dengan tag yang sama.
Sekarang kita dapat menambahkan aturan perutean:
ip rule add from 1.2.3.0/24 fwmark 0x100 lookup 100
Artinya, semua paket dengan alamat sumber 1.2.3.0/24
dan menandai 0x100
harus dirutekan menggunakan tabel 100
.
Dengan demikian, paket lain yang diterima di antarmuka lain tidak tunduk pada aturan ini, yang memungkinkan paket tersebut dirutekan menggunakan alat standar Kubernetes.
Ada satu hal lagi, di Linux ada yang disebut filter jalur terbalik, yang merusak semuanya; ia melakukan pemeriksaan sederhana: untuk semua paket masuk, ia mengubah alamat sumber paket dengan alamat pengirim dan memeriksa apakah paket dapat keluar melalui antarmuka yang sama dengan tempat paket diterima, jika tidak, paket akan menyaringnya.
Masalahnya adalah dalam kasus kami ini tidak berfungsi dengan benar, tetapi kami dapat menonaktifkannya:
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0.100/rp_filter
Harap dicatat bahwa perintah pertama mengontrol perilaku global rp_filter; jika tidak dinonaktifkan, perintah kedua tidak akan berpengaruh. Namun, antarmuka lainnya akan tetap dengan rp_filter diaktifkan.
Agar tidak sepenuhnya membatasi pengoperasian filter, kita dapat menggunakan implementasi rp_filter untuk netfilter. Menggunakan rpfilter sebagai modul iptables, Anda dapat mengonfigurasi aturan yang cukup fleksibel, misalnya:
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
aktifkan rp_filter pada antarmuka eth0.100
untuk semua alamat kecuali 1.2.3.0/24
.
Sumber: www.habr.com