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.
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.1
ve 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
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.
İ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.1
ancak 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:
Özelliği, herhangi bir adrese erişirken 1.2.3.0/24
yanıt paketi düğüme ulaşır ve aralıkta bir kaynak adresine sahiptir. 1.2.3.0/24
itaatkar bir şekilde gönderilecek eth0.100
ancak 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:
Ö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