LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。LVS 简单工作原理:用户请求LVS VIP,LVS根据转发方式和算法,将请求转发后端服务器,后端服务器接受到请求,返回给用户。对用户来说,看不到WEB后端具体的应用。LVS转发方式有三种,分别是NAT、DR、TUN模式,常用算法:RR、LC、WRR、WLC模式等(RR为轮询模式,LC为最少连接模式)LVS NAT原理:用户请求LVS到达director,director将请求的报文的目标地址改成后端的realserver地址,同时将报文的目标端口也改成后端选定的realserver相应端口,最后将报文发送到realserver,realserver将数据返给director,director再把数据发送给用户。(两次请求都经过director,所以访问大的话,director会成为瓶颈)LVS DR原理:用户请求LVS到达director,director将请求的报文的目标MAC地址改成后端的realserver MAC地址,目标IP为VIP(不变),源IP为用户IP地址(保持不变),然后Director将报文发送到realserver,realserver检测到目标为自己本地IP,如果在同一个网段,然后将请求直接返给用户。如果用户跟realserver不在一个网段,则通过网关返回用户。(此种转发效率最高)LVS TUN原理:跟LVS DR类似,也是改变封装MAC地址,多了一层隧道加密。实施环境复杂,比LVS DR模式效率略低。


实验环境:两台服务器部署,IP地址为:192.168.10.30、192.168.10.31 VIP:192.168.10.32 [root@server ~]# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core)

[root@lvs ~]# yum install ipvsadm keepalived -y [root@lvs ~]# ipvsadm -version //查看IPVS版本信息 [root@lvs ~]# ipvsadm -Ln //查看LVS转发列表 [root@lvs ~]# ipvsadm -Ln --timeout //查看LVS的超时时间 [root@lvs ~]# ipvsadm --set 5 10 10 //修改LVS对转发过的请求超时时间


LVS存在分设与合设,分设就是服务器单独安装LVS,合设就是跟业务网元一起安装在相同服务器上,合设时需要注意25%的几率会出现调度跟业务流出现死循环,需要在iptables里面对入流做标记过滤。 1. 分设主备配置示例: [root@lvs ~]# vim /etc/keepalived/keepalived.conf //主用

! Configuration File for keepalived

global_defs { router_id LVS_Master }

vrrp_instance VI_WEB { state MASTER interface bond0 virtual_router_id 110 priority 200 advert_int 3 authentication { auth_type PASS auth_pass 1212 } virtual_ipaddress { 192.168.10.32 } }

virtual_server 192.168.10.32 80 { delay_loop 6 lb_algo lc lb_kind DR persistence_timeout 60 protocol TCP real_server 192.168.10.23 80 { weight 100
TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.24 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.25 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.26 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }

[root@lvs ~]# vim /etc/keepalived/keepalived.conf //备用

! Configuration File for keepalived

global_defs { router_id LVS_Backup }

vrrp_instance VI_WEB { state BACKUP interface bond0 virtual_router_id 110 priority 120 advert_int 3 authentication { auth_type PASS auth_pass 1212 } virtual_ipaddress { 192.168.10.32 } }

virtual_server 192.168.10.32 80 { delay_loop 6 lb_algo lc lb_kind DR persistence_timeout 60 protocol TCP real_server 192.168.10.23 80 { weight 100
TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.24 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.25 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.26 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }

2. 合设主备配置示例:

[root@lvs~]# vim /etc/sysconfig/iptables //主用(写备用LVS的MAC)

*mangle :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A PREROUTING -d 192.168.10.32/32 -p tcp -m tcp --dport 80 -m mac ! --mac-source 0c:c4:7a:82:dc:ce -j MARK --set-xmark 0x3 -A INPUT -d 224.0.0.18 -i bond0 -j ACCEPT COMMIT

[root@lvs ~]# vim /etc/keepalived/keepalived.conf //主用

! Configuration File for keepalived

global_defs { router_id LVS_Master }

vrrp_instance VI_WEB { state MASTER interface bond0 virtual_router_id 110 priority 200 advert_int 3 authentication { auth_type PASS auth_pass 1212 } virtual_ipaddress { 192.168.10.32 } }

virtual_server fwmark 3 { delay_loop 6 lb_algo lc lb_kind DR persistence_timeout 60 protocol TCP real_server 192.168.10.23 80 { weight 100
TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.24 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.25 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.26 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }

[root@lvs~]# vim /etc/sysconfig/iptables //备用(写主用LVS的MAC)

*mangle :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A PREROUTING -d 192.168.10.32/32 -p tcp -m tcp --dport 80 -m mac ! --mac-source 0c:c4:7a:82:dc:cf -j MARK --set-xmark 0x4 -A INPUT -d 224.0.0.18 -i bond0 -j ACCEPT COMMIT

[root@lvs ~]# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs { router_id LVS_Backup }

vrrp_instance VI_WEB { state BACKUP interface bond0 virtual_router_id 110 priority 120 advert_int 3 authentication { auth_type PASS auth_pass 1212 } virtual_ipaddress { 192.168.10.32 } }

virtual_server fwmark 4 { delay_loop 6 lb_algo lc lb_kind DR persistence_timeout 60 protocol TCP real_server 192.168.10.23 80 { weight 100
TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.24 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.25 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.26 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }

[root@lvs ~]# systemctl enable keepalived && systemctl start keepalived [root@lvs ~]# systemctl list-unit-files | grep keepalived [root@lvs ~]# tail -f /var/log/messages


如上设置,LVS 主备配置完毕,接下来需要在realserver配置LVS VIP,为什么要在realserver绑定VIP呢?客户端访问director的VIP,director接收请求,将通过相应的算法将请求转发给相应的realserver。在转发的过程中,会修改请求包的目的mac地址,目的ip地址不变。Realserver接收请求,并直接响应客户端。这时便出现一个问题,director此时与realserver位于同一个网络中,当director直接将请求转发给realserver时,realserver检测到该请求包的目的ip是vip而并非自己,便会丢弃,而不会响应。为了解决这个问题,所以需要在所有Realserver上都配上VIP。为什么一定要配置在lo接口上呢?在realserver上的lo口配置VIP,这样限制了VIP不会在物理交换机上产生MAC地址表,从而避免IP冲突。 [root@realserver ~]# vim /usr/bin/realserver.sh

#! /bin/bash #description: Config realserver lo and apply noarp LVS_VIP=192.168.10.32 case "$1" in start) ifconfig lo:0 $LVS_VIP netmask 255.255.255.255 broadcast $LVS_VIP /sbin/route add -host $LVS_VIP dev lo:0 echo "1" >/proc/sys/net/ipv4/conf/bond0/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/bond0/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce sysctl -p >/dev/null 2>&1 echo "RealServer Start OK" exit 0 ;; stop) ifconfig lo:0 down route del $EPG_VIP >/dev/null 2>&1 echo "0" >/proc/sys/net/ipv4/conf/bond0/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/bond0/arp_announce echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce echo "RealServer Stoped" exit 1 ;; status) # Status of LVS-DR real server. islothere=/sbin/ifconfig lo:0 | grep $LVS_VIP isrothere=netstat -rn | grep "lo:0" | grep $LVS_VIP if [ ! "$islothere" -o ! "isrothere" ];then # Either the route or the lo:0 device echo "LVS-DR real server Stopped." else echo "LVS-DR Running." fi ;; *) # Invalid entry. echo "$0: Usage: $0 {start|status|stop}" exit 1 ;; esac

[root@realserver ~]# chmod +x /usr/bin/realserver.sh [root@realserver ~]# sh /usr/bin/realserver.sh start