Tôi sẽ giải thích thiết lập của mình và cách tôi giải quyết các tải lại duyên dáng:
Tôi có một thiết lập điển hình với 2 nút chạy HAproxy và được giữ nguyên. Giao diện theo dõi được giữ nguyên dummy0, vì vậy tôi có thể thực hiện "ifconfig dummy0 down" để buộc chuyển đổi.
Vấn đề thực sự là, tôi không biết tại sao, "tải lại haproxy" vẫn làm giảm tất cả các kết nối THÀNH LẬP :( Tôi đã thử "lật iptables" do gertas đề xuất, nhưng tôi thấy một số vấn đề vì nó thực hiện NAT ở đích Địa chỉ IP, không phải là một giải pháp phù hợp trong một số tình huống.
Thay vào đó, tôi quyết định sử dụng hack bẩn CONNophone để đánh dấu các gói thuộc các kết nối MỚI và sau đó chuyển hướng các gói được đánh dấu sang nút khác.
Đây là quy tắc iptables:
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
Hai quy tắc đầu tiên đánh dấu các gói thuộc các luồng mới (123.123.123.123 là VIP được giữ lại được sử dụng trên haproxy để liên kết các giao diện trên).
Quy tắc thứ ba và thứ tư đánh dấu các gói FIN / RST. (Tôi không biết tại sao, mục tiêu TEE "bỏ qua" các gói FIN / RST).
Quy tắc thứ năm gửi một bản sao của tất cả các gói được đánh dấu đến HAproxy khác (192.168.0.2).
Quy tắc thứ sáu bỏ các gói thuộc các luồng mới để ngăn chặn đến đích ban đầu của chúng.
Hãy nhớ tắt rp_filter trên các giao diện hoặc kernel sẽ loại bỏ các gói martian đó.
Và cuối cùng nhưng không kém phần quan trọng, hãy nhớ các gói trả về! Trong trường hợp của tôi, có định tuyến không đối xứng (yêu cầu đến máy khách -> haproxy1 -> haproxy2 -> máy chủ web và trả lời đi từ máy chủ web -> haproxy1 -> máy khách), nhưng nó không ảnh hưởng. Nó hoạt động tốt.
Tôi biết giải pháp tao nhã nhất là sử dụng iproute2 để thực hiện chuyển hướng, nhưng nó chỉ hoạt động cho gói SYN đầu tiên. Khi nhận được ACK (gói thứ 3 của bắt tay 3 chiều), nó đã không đánh dấu nó :( Tôi không thể dành nhiều thời gian để điều tra, ngay khi tôi thấy nó hoạt động với mục tiêu TEE, nó đã để nó ở đó. Tất nhiên, hãy thử dùng nó với iproute2.
Về cơ bản, "tải lại duyên dáng" hoạt động như thế này:
- Tôi kích hoạt bộ quy tắc iptables và ngay lập tức thấy các kết nối mới sẽ đến HAproxy khác.
- Tôi để mắt đến "netstat -an | grep THÀNH LẬP | wc -l" để giám sát quá trình "rút cạn".
- Khi chỉ có một vài kết nối (hoặc không), "ifconfig dummy0 down" để buộc giữ lại chuyển đổi dự phòng, vì vậy tất cả lưu lượng truy cập sẽ chuyển sang HAproxy khác.
- Tôi loại bỏ các quy tắc iptables
- (Chỉ dành cho cấu hình keepalive "không ưu tiên") "ifconfig dummy0 up".
Bộ quy tắc IPtables có thể dễ dàng được tích hợp vào tập lệnh start / stop:
#!/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