1. 程式人生 > >linux 實現lvs-dr在不同網段的負載均衡排程

linux 實現lvs-dr在不同網段的負載均衡排程

一、前言:

當一組伺服器在高速的區域網或廣域網中相互連線,其前端部署了一個負責負載排程的排程器(director)的服務系統,排程器能將網路請求無縫銜接排程到真實的伺服器上(real server)上,客戶訪問集群系統提供的網路服務就像訪問一臺高效能,高可用的伺服器一樣,集群系統支援透明的增加或刪除伺服器節點,以此來靈活應對客戶機的不同的訪問量需求,從而靈活排程,來實現收益最大化的效果,而客戶對此是毫無感知的,而且,集群系統能夠透過檢測節點或服務程序的故障來正確進行節點的切換,從而達到系統的高可用性。通過此類技術實現的負載均衡。因為是在Linux核心上實現的,因此被稱為Linux vitural server(lvs)。

Lvs叢集的型別包括:nat、dr、tun和fullnat四種類型,這四種類型的Lvs叢集分別有著不同的特點及應用場景,下面我們就來一起看看它們的區別。

因為四種類型在現實生活中的需求以及功能要求不同,所以主要研究最常用的dr型別。

lvs常用術語:

VS:Virtual Server,排程器,負責排程 RS: Real Server,負責真正提供服務,後端伺服器 VIP: LVS伺服器上的公網IP,即Virtual IP DIP: LVS伺服器上的內網IP,即Director IP RIP: Real Server上的內網IP CIP:客戶端的IP

二:詳解dr:

lvs-dr叢集是lvs的預設模式,又稱為Direct Routing,直接路由模式,通過請求報文重新封裝一個MAC首部進行轉發,源MAC是DIP所在介面的MAC,目標MAC是某挑選出的RS所在的介面的MAC地址,源IP/PORT,以及目標IP/PORT均保持不變。 在DR 模式下需要在 Director 和 RS 叢集繫結同一個 VIP(RS 通過將 VIP 繫結在 loopback 實現)。由於在VIP在同一個網路中的多臺伺服器上都需要配置,因此必須對RS的ARP響應報文規則進行修改,其方式有三種:

(a) 在前端閘道器做靜態繫結;
(b) 在RS上使用arptables工具;
  # arptables -A IN -d $VIP -j DROP
  # arptables -A OUT -s $VIP -j mangle --mangle-ip-s $RIP
(c) 在RS上修改核心引數以限制arp通告及應答級別;
  echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
  echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
  echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
  echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

配置dr模式注意以下幾點:

1、確保前端路由器將目標Ip為VIP的請求報文發往director,而不是RS; 2、RS的RIP可以使用私網地址,也可以是公網地址;RIP與DIP在同一IP網路;RIP的閘道器不能指向DIP,以確保響應報文不會經由Director; 3、RS跟Director要在同一個物理網路(關鍵點,這樣才能實現請求通過director,響應時不經過director); 4、請求報文要經由Director,但響應不能經由Director,而是由RS直接發往Client; 5、dr模式不支援埠對映;

lvs-dr模式的優點在於:Director只是分發請求,應答包通過單獨的路由方法返回給客戶端。與Lvs-tun相比,Lvs-dr這種實現方式不需要隧道結構,因此可以使用大多數作業系統做為物理伺服器。缺點在於要求負載均衡器的網絡卡必須與物理網絡卡在一個物理段上。 設計圖:

上圖為lvs-dr的常見的使用場景,其工作流程如下: 1、客戶端的請求會發往Director,此時,客戶端請求報文的源Ip為CIP,目標Ip為Director的VIP。 2、當Director接受到客戶端的請求報文後,Director會在請求報文外封裝一個MAC首部,其源MAC為Director介面的MAC地址,目標MAC為選定RS的MAC地址; 3、當RS收到Director轉發過來的請求報文後,檢查發現請求報文的目標Ip為本地環回介面上配置的VIP,因此會接受報文進行響應處理。另外由於對ARP響應規則做了修改,因此RS不會把響應報文響應給director ,而是響應給GW; 4、客戶端接收響應報文,完成通訊。

實驗:

開啟五臺虛擬機器,編輯虛擬網路介面卡,新加兩個網絡卡vmnet2,vmnet4,因為和ip相似便於區分

關閉所有機器的firewalld,和selinux.

配置client,新加網絡卡自定義為vmnet4,必須對照MAC,給新加網絡卡設定IP。

[[email protected] ~]# nmcli connection add type ethernet ifname ens33 con-name ens33
Connection 'ens33' (f85db8da-ca5b-4f39-a09a-8a9d2759f5e7) successfully added.
[[email protected] ~]# nmcli connection modify ens33 connection.autoconnect yes ipv4.method manual ipv4.addresses 40.40.40.10/24 ipv4.gateway 40.40.40.254
[[email protected] ~]# nmcli connection up ens33
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/18)

配置route,route需要兩個網絡卡,分別對應20.20.20.254和40...網段,另外由於rs回來時直接指向route,所以還有在配置個30的網段,所以在vmnet2上配置兩個ip,在vmnet4上配置一個ip根據MAC地址仔細配對,別搞錯了網絡卡配置。

[[email protected] ~]# nmcli connection add type ethernet ifname ens38 con-name ens38
[[email protected] ~]# nmcli connection modify ens38 connection.autoconnect yes ipv4.method manual ipv4.addresses 40.40.40.254/24 
[[email protected] ~]# nmcli connection up ens38
[[email protected] ~]# nmcli connection add type ethernet ifname ens33 con-name ens33
Connection 'ens33' (e05443aa-b3b1-4801-bb40-a04f435f7f27) successfully added.
[[email protected] ~]# nmcli connection modify ens33 connection.autoconnect yes ipv4.method manual ipv4.addresses 30.30.30.254/24
[[email protected] ~]# nmcli connection modify ens33 +ipv4.addresses 20.20.20.254/24
[[email protected] ~]#  nmcli connection modify ens33 +ipv4.addresses 20.20.20.254/24

配置Director

director僅需一個網絡卡,但要在vmnet2一個網絡卡上配置兩個ip,分別為20.20.20.20和30.30.30.20

[[email protected] ~]# nmcli connection add type ethernet ifname ens33 con-name ens33
Connection 'ens33' (a327fefb-b395-4744-9ab7-b0bc1a26da22) successfully added.
[[email protected] ~]# nmcli connection modify ens33 connection.autoconnect yes ipv4.method manual ipv4.addresses 30.30.30.20/24
[[email protected] ~]# nmcli connection modify ens33 +ipv4.addresses 20.20.20.20/32 ipv4.gateway 20.20.20.254
[[email protected] ~]# nmcli connection up ens33

配置rs1

rs1僅需一塊網絡卡vmnet2,但也要配置兩個ip,分別為20.20.20.20和30.30.30.30,另外,還要在client發請訪問20.20.20.20ip時候,rs不予響應,所以需要加策略。

[[email protected] ~]# nmcli connection add type ethernet ifname ens34 con-name ens34
Connection 'ens34' (61568fb8-0f0d-437c-8a31-556e7c9a7ec9) successfully added.
[[email protected] ~]# nmcli connection modify ens34 connection.autoconnect yes ipv4.method manual ipv4.addresses 30.30.30.30/24 ipv4.gateway 30.30.30.254
[[email protected] ~]# nmcli connection up ens34

[[email protected] ~]# vim setpara.sh
#!/bin/bash
#
vip=20.20.20.20
mask='255.255.255.255'
iface="lo:0"

case $1 in
start)
        echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
        echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
        echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
        echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
        ifconfig $iface $vip netmask $mask broadcast $vip up
        route add -host $vip dev $iface
        ;;
stop)
        ifconfig $iface down

        echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
        echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
        echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
        echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
        ;;
*)
        echo "Usage $(basename $0) start|stop"
        exit 1
        ;;
esac 

[[email protected] ~]# chmod +x setpara.sh 
[[email protected] ~]# ./setpara.sh start
[[email protected] ~]# ifconfig lo:0
lo:0: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 20.20.20.20  netmask 255.255.255.255
        loop  txqueuelen 1000  (Local Loopback)

配置rs2

rs1僅需一塊網絡卡vmnet2,但也要配置兩個ip,分別為20.20.20.20和30.30.30.40,另外,還要在client發請訪問20.20.20.20ip時候,rs不予響應,所以需要加策略。

[[email protected] ~]# nmcli connection add type ethernet ifname ens34 con-name ens34
Connection 'ens34' (61568fb8-0f0d-437c-8a31-556e7c9a7ec9) successfully added.
[[email protected] ~]# nmcli connection modify ens34 connection.autoconnect yes ipv4.method manual ipv4.addresses 30.30.30.40/24 ipv4.gateway 30.30.30.254
[[email protected] ~]# nmcli connection up ens34

[[email protected] ~]# vim setpara.sh
#!/bin/bash
#
vip=20.20.20.20
mask='255.255.255.255'
iface="lo:0"

case $1 in
start)
        echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
        echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
        echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
        echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
        ifconfig $iface $vip netmask $mask broadcast $vip up
        route add -host $vip dev $iface
        ;;
stop)
        ifconfig $iface down

        echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
        echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
        echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
        echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
        ;;
*)
        echo "Usage $(basename $0) start|stop"
        exit 1
        ;;
esac 

[[email protected] ~]# chmod +x setpara.sh 
[[email protected] ~]# ./setpara.sh start
[[email protected] ~]# ifconfig lo:0
lo:0: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 20.20.20.20  netmask 255.255.255.255
        loop  txqueuelen 1000  (Local Loopback)

在兩個rs上安裝httpd

[[email protected] ~]# yum -y install httpd
[[email protected] ~]# yum -y install httpd
[[email protected] ~]# echo rs1.kobe > /var/www/html/index.html
[[email protected] ~]# echo rs2.curry > /var/www/html/index.html
[[email protected] ~]# systemctl restart httpd
[[email protected] ~]# systemctl restart httpd

在director上驗證

[[email protected] ~]# curl 30.30.30.30
rs1.kobe
[[email protected] ~]# curl 30.30.30.40
rs2.curry

在director上配置策略

[[email protected] ~]# yum -y install ipvsadm
[[email protected] ~]# systemctl start ipvsadm
[[email protected] ~]# ipvsadm -A -t 20.20.20.20:80 -s wrr
[[email protected] ~]# ipvsadm -a -t 20.20.20.20:80 -r 30.30.30.30 -g -w 1
[[email protected] ~]# ipvsadm -a -t 20.20.20.20:80 -r 30.30.30.40 -g -w 3

ipvsadm功能類似於firewalld,新增策略後,不用重啟ipvsadm,如果,systemctl restart ipvsadm ,之前寫的策略會清空,這是因為ipvsadm 有個配置檔案/etc/sysconfig/ipvsadm_config

# Unload modules on restart and stop
#   Value: yes|no,  default: yes
# This option has to be 'yes' to get to a sane state for a ipvs
# restart or stop. Only set to 'no' if there are problems unloading ipvs
# modules.
IPVS_MODULES_UNLOAD="yes"

# Save current ipvs rules on stop.
#   Value: yes|no,  default: no
# Saves all ipvs rules to /etc/sysconfig/ipvsadm if ipvsadm gets stopped
# (e.g. on system shutdown).
IPVS_SAVE_ON_STOP="no"

# Save current ipvs rules on restart.
#   Value: yes|no,  default: no
# Saves all ipvs rules to /etc/sysconfig/ipvsadm if ipvsadm gets
# restarted.
IPVS_SAVE_ON_RESTART="no"

# Numeric status output
#   Value: yes|no,  default: yes
# Print IP addresses and port numbers in numeric format in the status output.
IPVS_STATUS_NUMERIC="yes"

第三項有個重啟自動清空規則。我們把no改為yes就可以了。

在route,director上開啟路由轉發,

client進行測試

[[email protected] nginx]# while true;do curl 20.20.20.20;sleep 1s;done
rs2.curry
rs1.kobe
rs2.curry
rs2.curry
rs2.curry
rs1.kobe
rs2.curry
rs2.curry
rs2.curry
rs1.kobe
rs2.curry
rs2.curry
rs2.curry
rs1.kobe
rs2.curry

完畢