Kurulumumu ve zarif yüklemeleri nasıl çözdüğümü açıklayacağım:
HAproxy çalışan ve keepalived 2 düğüm ile tipik bir kurulum var. Keepalived izler arayüzü dummy0, bu yüzden geçişi zorlamak için "ifconfig down down" yapabilirim.
Asıl sorun, neden bilmiyorum, bir "haproxy yeniden yükleme" hala KURULAN tüm bağlantıları bırakıyor :( Gertalar tarafından önerilen "iptables flipping" denedim, ancak hedefte bir NAT gerçekleştirdiği için bazı sorunlar buldum Bazı senaryolarda uygun bir çözüm olmayan IP adresi.
Bunun yerine, YENİ bağlantılara ait paketleri işaretlemek için bir CONNMARK kirli hack kullanmaya karar verdim ve ardından işaretli paketleri diğer düğüme yönlendirdim.
İşte iptables kural kümesi:
iptables -t mangle -A PREROUTING -i eth1 -d 123.123.123.123/32 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -i eth1 -p tcp --tcp-flags FIN FIN -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i eth1 -p tcp --tcp-flags RST RST -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i eth1 -m mark ! --mark 0 -j TEE --gateway 192.168.0.2
iptables -t mangle -A PREROUTING -i eth1 -m mark --mark 1 -j DROP
İlk iki kural, yeni akışlara ait paketleri işaretler (123.123.123.123, ön uçları bağlamak için haroside kullanılan sürekli VIP.
Üçüncü ve dördüncü kurallar paketleri FIN / RST paketlerini işaretler. (Nedenini bilmiyorum, TEE hedefi FIN / RST paketlerini "görmezden geliyor").
Beşinci kural, işaretli tüm paketlerin bir kopyasını diğer HAproxy'ye (192.168.0.2) gönderir.
Altıncı kural, orijinal hedeflerine ulaşılmasını önlemek için yeni akışlara ait paketleri bırakır.
Arabirimlerde rp_filter'i devre dışı bırakmayı unutmayın, yoksa çekirdek bu Mars paketlerini düşürür.
Ve son fakat en az değil, geri dönen paketleri dikkate alın! Benim durumumda asimetrik yönlendirme var (istekler istemciye geliyor -> haproxy1 -> haproxy2 -> web sunucusu ve cevaplar web sunucusu -> haproxy1 -> istemcisinden geliyor), ancak etkilenmiyor. İyi çalışıyor.
En şık çözümün, yönlendirme yapmak için iproute2 kullanmak olacağını biliyorum, ancak yalnızca ilk SYN paketi için işe yaradı. ACK (3 yollu el sıkışmasının 3. paketi) alındığında işaretlemedi :( Araştırmak için fazla zaman harcadım, TEE hedefiyle çalıştığını görür görmez orada bıraktı. Elbette, iproute2 ile denemek için çekinmeyin.
Temel olarak, "zarif yeniden yükleme" şu şekilde çalışır:
- İptables kural kümesini etkinleştiriyorum ve derhal diğer HAproxy'ye giden yeni bağlantıları görüyorum.
- "Boşaltma" işlemini denetlemek için "netstat -an | grep ESTABLISHED | wc -l" konusuna göz kulak oluyorum.
- Sadece birkaç (veya sıfır) bağlantı oluştuktan sonra, "ifconfig dummy0 down" işlevini yerine getirmeyi yerine devretmeye zorlamak için tüm trafik diğer HAproxy'ye gider.
- İptables kural kümesini kaldırıyorum
- (Sadece "önlenmeyen" keepalive config için) "ifconfig dummy0 up".
IPtables kuralları, bir start / stop betiğine kolayca entegre edilebilir:
#!/bin/sh
case $1 in
start)
echo Redirection for new sessions is enabled
# echo 0 > /proc/sys/net/ipv4/tcp_fwmark_accept
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
iptables -t mangle -A PREROUTING -i eth1 ! -d 123.123.123.123 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -i eth1 -p tcp --tcp-flags FIN FIN -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i eth1 -p tcp --tcp-flags RST RST -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i eth1 -m mark ! --mark 0 -j TEE --gateway 192.168.0.2
iptables -t mangle -A PREROUTING -i eth1 -m mark --mark 1 -j DROP
;;
stop)
iptables -t mangle -D PREROUTING -i eth1 -m mark --mark 1 -j DROP
iptables -t mangle -D PREROUTING -i eth1 -m mark ! --mark 0 -j TEE --gateway 192.168.0.2
iptables -t mangle -D PREROUTING -i eth1 -p tcp --tcp-flags RST RST -j MARK --set-mark 2
iptables -t mangle -D PREROUTING -i eth1 -p tcp --tcp-flags FIN FIN -j MARK --set-mark 2
iptables -t mangle -D PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -D PREROUTING -i eth1 ! -d 123.123.123.123 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1
echo Redirection for new sessions is disabled
;;
esac