L2 modunda MetalLB için yönlendirmenin ince ayarı

L2 modunda MetalLB için yönlendirmenin ince ayarı
Kısa bir süre önce MetalLB için yönlendirme ayarlama gibi alışılmadık bir görevle karşı karşıya kaldım. Her şey güzel olacak çünkü... Genellikle MetalLB herhangi bir ek eylem gerektirmez, ancak bizim durumumuzda çok basit bir ağ konfigürasyonuna sahip oldukça büyük bir kümeye sahibiz.

Bu yazımda kümenizin dış ağı için kaynak tabanlı ve politika tabanlı yönlendirmeyi nasıl yapılandıracağınızı anlatacağım.

Zaten bir miktar deneyiminiz olduğunu varsaydığım için MetalLB'nin kurulumu ve yapılandırılmasıyla ilgili ayrıntılara girmeyeceğim. Doğrudan konuya geçmenizi, yani yönlendirmeyi ayarlamanızı öneririm. Yani elimizde dört durum var:

Durum 1: Yapılandırma gerekmediğinde

Basit bir duruma bakalım.

L2 modunda MetalLB için yönlendirmenin ince ayarı

MetalLB tarafından yayınlanan adresler düğümlerinizin adresleriyle aynı alt ağda olduğunda ek yönlendirme yapılandırmasına gerek yoktur.

Örneğin, bir alt ağınız var 192.168.1.0/24, bir yönlendiricisi var 192.168.1.1ve düğümleriniz adresleri alır: 192.168.1.10-30, ardından MetalLB için aralığı ayarlayabilirsiniz 192.168.1.100-120 ve hiçbir ek konfigürasyona ihtiyaç duymadan çalışacaklarından emin olun.

Nedenmiş? Düğümlerinizde zaten yapılandırılmış yollar olduğundan:

# 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

Aynı aralıktaki adresler, herhangi bir ek eyleme gerek kalmadan bunları yeniden kullanır.

Durum 2: Ek özelleştirme gerektiğinde

L2 modunda MetalLB için yönlendirmenin ince ayarı

Düğümlerinizin yapılandırılmış bir IP adresi olmadığında veya MetalLB'nin adres yayınladığı alt ağa giden rotaya sahip olmadığında ek yollar yapılandırmanız gerekir.

Biraz daha detaylı anlatacağım. MetalLB bir adresin çıktısını verdiğinde, bu aşağıdaki gibi basit bir atamayla karşılaştırılabilir:

ip addr add 10.9.8.7/32 dev lo

Dikkat et:

  • a) Adres bir önekle atanır /32 yani alt ağa otomatik olarak bir rota eklenmez (bu yalnızca bir adrestir)
  • b) Adres herhangi bir düğüm arayüzüne eklenir (örneğin geridöngü). Burada Linux ağ yığınının özelliklerinden bahsetmeye değer. Adresi hangi arayüze eklerseniz ekleyin, çekirdek her zaman arp isteklerini işleyecek ve bunlardan herhangi birine arp yanıtları gönderecektir, bu davranış doğru kabul edilir ve üstelik Kubernetes gibi dinamik bir ortamda oldukça yaygın olarak kullanılır.

Bu davranış, örneğin katı arp etkinleştirilerek özelleştirilebilir:

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

Bu durumda, arp yanıtları yalnızca arayüzün açıkça belirli bir IP adresi içermesi durumunda gönderilecektir. MetalLB kullanmayı planlıyorsanız ve kube-proxy'niz IPVS modunda çalışıyorsa bu ayar gereklidir.

Ancak MetalLB, arp isteklerini işlemek için çekirdeği kullanmaz, ancak bunu kullanıcı alanında kendisi yapar, dolayısıyla bu seçenek MetalLB'nin çalışmasını etkilemeyecektir.

Görevimize dönelim. Verilen adreslerin rotası düğümlerinizde mevcut değilse, bunu önceden tüm düğümlere ekleyin:

ip route add 10.9.8.0/24 dev eth1

Durum 3: Kaynak tabanlı yönlendirmeye ihtiyaç duyduğunuzda

Paketleri varsayılan olarak yapılandırılan ağ geçidi yerine ayrı bir ağ geçidi üzerinden aldığınızda, kaynak tabanlı yönlendirmeyi yapılandırmanız gerekecektir; bu nedenle yanıt paketlerinin de aynı ağ geçidinden geçmesi gerekir.

Örneğin, aynı alt ağa sahipsiniz 192.168.1.0/24 düğümlerinize ayrılmış ancak MetalLB kullanarak harici adresler vermek istiyorsunuz. Bir alt ağdan birden fazla adresiniz olduğunu varsayalım 1.2.3.0/24 VLAN 100'de bulunur ve bunları Kubernetes hizmetlerine harici olarak erişmek için kullanmak istiyorsunuz.

L2 modunda MetalLB için yönlendirmenin ince ayarı

İletişim kurarken 1.2.3.4 farklı bir alt ağdan istekte bulunacaksınız 1.2.3.0/24 ve bir cevap bekleyin. Şu anda MetalLB tarafından verilen adresin ana düğümü olan düğüm 1.2.3.4, paketi yönlendiriciden alacak 1.2.3.1ancak onun için yanıt mutlaka aynı yoldan gitmelidir. 1.2.3.1.

Düğümümüzün zaten yapılandırılmış bir varsayılan ağ geçidi olduğundan 192.168.1.1, o zaman varsayılan olarak yanıt ona gidecektir, ona gitmeyecektir. 1.2.3.1, bu sayede paketi aldık.

Bu durumla nasıl başa çıkılır?

Bu durumda tüm düğümlerinizi, ek yapılandırmaya gerek kalmadan harici adreslere hizmet vermeye hazır olacak şekilde hazırlamanız gerekir. Yani yukarıdaki örnek için düğümde önceden bir VLAN arayüzü oluşturmanız gerekir:

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

Ve sonra rotaları ekleyin:

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

Rotaları ayrı bir yönlendirme tablosuna eklediğimizi lütfen unutmayın. 100 ağ geçidi üzerinden bir yanıt paketi göndermek için gereken yalnızca iki yolu içerecektir 1.2.3.1, arayüzün arkasında bulunur eth0.100.

Şimdi basit bir kural eklememiz gerekiyor:

ip rule add from 1.2.3.0/24 lookup 100

ki bu açıkça şunu söylüyor: eğer paketin kaynak adresi 1.2.3.0/24, o zaman yönlendirme tablosunu kullanmanız gerekir 100. İçinde onu gönderecek rotayı zaten tanımladık. 1.2.3.1

Durum 4: İlke tabanlı yönlendirmeye ihtiyaç duyduğunuzda

Ağ topolojisi önceki örnektekiyle aynıdır ancak diyelim ki harici havuz adreslerine de erişmek istiyorsunuz 1.2.3.0/24 bölmelerinizden:

L2 modunda MetalLB için yönlendirmenin ince ayarı

Özelliği, herhangi bir adrese erişirken 1.2.3.0/24yanıt paketi düğüme ulaşır ve aralıkta bir kaynak adresine sahiptir. 1.2.3.0/24 itaatkar bir şekilde gönderilecek eth0.100ancak Kubernetes'in bunu orijinal isteği oluşturan ilk bölmemize yönlendirmesini istiyoruz.

Bu sorunu çözmenin zor olduğu ortaya çıktı ancak politikaya dayalı yönlendirme sayesinde bu mümkün oldu:

Sürecin daha iyi anlaşılması için burada bir netfilter blok şeması verilmiştir:
L2 modunda MetalLB için yönlendirmenin ince ayarı

Öncelikle önceki örnekte olduğu gibi ek bir yönlendirme tablosu oluşturalım:

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

Şimdi iptables'a birkaç kural ekleyelim:

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

Bu kurallar arayüze gelen bağlantıları işaretleyecektir eth0.100, tüm paketleri etiketiyle işaretleyerek 0x100, aynı bağlantı içindeki yanıtlar da aynı etiketle işaretlenecektir.

Artık bir yönlendirme kuralı ekleyebiliriz:

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

Yani kaynak adresi olan tüm paketler 1.2.3.0/24 ve etiket 0x100 bir tablo kullanılarak yönlendirilmelidir 100.

Dolayısıyla başka bir arayüz üzerinden alınan diğer paketler bu kurala tabi değildir ve bu da onların standart Kubernetes araçları kullanılarak yönlendirilmelerine olanak tanıyacaktır.

Bir şey daha var, Linux'ta her şeyi bozan sözde ters yol filtresi var; basit bir kontrol yapıyor: gelen tüm paketler için paketin kaynak adresini gönderen adresiyle değiştiriyor ve olup olmadığını kontrol ediyor. Paket alındığı arayüzden ayrılabilir, aksi takdirde filtrelenecektir.

Sorun şu ki bizim durumumuzda düzgün çalışmayacak, ancak onu devre dışı bırakabiliriz:

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

Lütfen ilk komutun rp_filter'ın genel davranışını kontrol ettiğini unutmayın; devre dışı bırakılmazsa ikinci komutun hiçbir etkisi olmayacaktır. Ancak geri kalan arayüzler rp_filter etkin durumda kalacak.

Filtrenin çalışmasını tamamen sınırlamamak adına netfilter için rp_filter uygulamasını kullanabiliriz. Rpfilter'ı iptables modülü olarak kullanarak oldukça esnek kurallar yapılandırabilirsiniz, örneğin:

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

arayüzde rp_filter'ı etkinleştirin eth0.100 hariç tüm adresler için 1.2.3.0/24.

Kaynak: habr.com

Yorum ekle