LVS集群采用IP负载均衡技术和基于内容请求分发技术。调度器具有很好的吞吐率,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的、高可用的虚拟服务器。整个服务器集群的结构对客户是透明的,而且无需修改客户端和服务器端的程序。为此,在设计时需要考虑系统的透明性、可伸缩性、高可用性和易管理性
原理:把客户端发来的数据包在负载均衡器上将目的地址封装成其中一台RS的IP地址,并发至该RS来处理,RS处理完成后把数据包发给负载均衡器,负载均衡器再把数据包的原IP地址封装成为自己的IP,将目的地址封装成客户端IP地址,然后发给客户端。无论是进来的流量,还是出去的流量,都必须经过负载均衡器。
优点:集群中的物理服务器可以使用任何支持 TCP/IP 的操作系统,只有负载均衡器需要一个合法的IP地址。
缺点:扩展性有限。当服务器节点(普通PC服务器)增长过多时,负载均衡器将成为整个系统的瓶颈,因为所有的请求包和应答包的流向都经过负载均衡器。当服务器节点过多时,大量的数据包都交汇在负载均衡器那,速度就会变慢!
原理:由于互联网上的大多Internet服务的请求包很短小,而应答包通常很庞大,使用nat模式庞大的应答数据包也必须经过负载均衡器,这就加重了负载均衡器的负担,隧道模式就是优化这个问题的。所以隧道模式就是,把客户端发来的数据包,封装一个新的IP头标记(仅目的IP)发给RS,RS收到后,先把数据包的头解开,还原数据包,处理后,直接返回给客户端,不需要再经过负载均衡器。注意,由于RS需要对负载均衡器发过来的数据包进行还原,所以说必须支持IPTUNNEL协议。所以,在RS的内核中,必须编译支持IPTUNNEL这个选项
优点:负载均衡器只负责将请求包分发给后端节点服务器,而RS将应答包直接发给用户。所以,减少了负载均衡器的大量数据流动,负载均衡器不再是系统的瓶颈,就能处理很巨大的请求量,这种方式,一台负载均衡器能够为很多RS进行分发。而且跑在公网上就能进行不同地域的分发。
缺点:隧道模式的RS节点需要合法IP,这种方式需要所有的服务器支持”IP Tunneling”(IP Encapsulation)协议,服务器可能只局限在部分Linux系统上。
原理:负载均衡器和RS都使用同一个IP对外服务。但只有DR对ARP请求进行响应,所有RS对本身这个IP的ARP请求保持静默。也就是说,网关会把对这个服务IP的请求全部定向给DR,而DR收到数据包后根据调度算法,找出对应的RS,把目的MAC地址改为RS的MAC(因为IP一致)并将请求分发给这台RS。这时RS收到这个数据包,处理完成之后,由于IP一致,可以直接将数据返给客户,则等于直接从客户端收到这个数据包无异,处理后直接返回给客户端。由于负载均衡器要对二层包头进行改换,所以负载均衡器和RS之间必须在一个广播域,也可以简单的理解为在同一台交换机上。
原理:FULL NAT 在client请求VIP 时,不仅替换了package 的dst ip,还替换了package的 src ip;但VIP 返回给client时也替换了src ip,具体分析如下:
首先client 发送请求[package] 给VIP;VIP 收到package后,会根据LVS设置的LB算法选择一个合适的realserver,然后把package 的DST IP 修改为realserver;把sorce ip 改成 lvs 集群的LB IP ;realserver 收到这个package后判断dst ip 是自己,就处理这个package ,处理完后把这个包发送给LVS VIP;LVS 收到这个package 后把sorce ip改成VIP的IP,dst ip改成 client ip然后发送给client。
FULL NAT 模式也不需要 LBIP 和realserver ip 在同一个网段;
Director Server根据各台服务器的负载情况,通过高度算法动态选择一台Real Server
LVS目前实现了10种调度算法
常用调度算法有4种(轮询、加权轮询、最少连接、加权最少连接)
源地址散列(Source Hashing)
最短的期望的延迟(Shortest Expected Delay Scheduling SED)
## LVS服务器
VIP:172.25.254.200
DIP:172.25.20.1
## WEB服务器1
web1:172.25.20.2
## WEB服务器2
web2:172.25.20.3
yum install ipvsadm -y
chkconfig ipvsadm on
service ipvsadm start
服务安装与前期配置
WEB服务器1和WEB服务器2 nginx安装完成之后,修改下nginx默认发布页方便后面区分,在两台服务器上分别执行以下命令:
vim /usr/local/nginx/html/index.thml
nginx server 22222222 ##在web2上输入的时候把22222222 换成33333333便于区分
lvs配置可以通过编辑配置文件进行配置,也可以通过脚本进行配置,个人推荐使用脚本,因为修改配置很方便
DR模式配置通过命令的方式
a. 配置LVS服务器(server1)
#### LVS服务器(server1)
chkconfig ipvsadm on
service ipvsadm start
ipvsadm ##查看ipvsadm条目,如果存在可以执行下一条命令删除
ipvsadm -D -t 172.25.254.200:80 ##删除ipvsadm条目172.25.254.200:80 (一般用下面这条删除所有的命令)
ipvsadm -C ##删除所有ipvsadm条目
ipvsadm -A -t 172.25.20.1:80 -s rr ##添加ipvsadm条目,-A表示追加条目,-t表示使用tcp协议,-s rr表示使用轮询算法
ipvsadm -a -t 172.25.20.1:80 -r 172.25.20.2 -g ##-a表示追加规则,-t表示使用tcp协议,-r表示real-server,-g表示使用DR模型
ipvsadm -a -t 172.25.20.1:80 -r 172.25.20.3 -g
ipvsadm
下图说明成功
我的是做过解析的,如果没做解析显示可能为
[root@server1 sbin]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.200:http rr
-> 172.25.20.2:http Route 1 0 0
-> 172.25.20.1:http Route 1 0 0
b.配置后台的两个Real Server服务器(以web1为例,web2相同)
### Real Server服务器(server2)
[root@server2 ~] echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@server2 ~] echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
[root@server2 ~] echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@server2 ~] echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
[root@server2 ~] ifconfig lo:0 172.25.254.200 netmask 255.255.255.255 broadcast 172.25.20.1 ##在lo上设置集群服务的ip地址
[root@server2 ~] route add -host 172.25.254.200 dev lo:0 ##在lo上设置集群服务的路由
[root@server2 ~] route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.10.6.200 * 255.255.255.255 UH 0 0 0 lo
10.10.6.0 * 255.255.255.0 U 0 0 0 eth0
link-local * 255.255.0.0 U 1002 0 0 eth0
default 172.25.254.200 0.0.0.0 UG 0 0 0 eth0
其实就是路由器的问题,因为路由器一般是动态学习ARP包的(一般动态配置DHCP的话),当内网的机器要发送一个到外部的ip包,那么它就会请求路由器的Mac地址,发送一个arp请求,这个arp请求里面包括了自己的ip地址和Mac地址,而linux默认是使用ip的源ip地址作为arp里面 的源ip地址,而不是使用发送设备上面的 ,这样在lvs这样的架构下,所有发送包都是同一个VIP地址,那么arp请求就会包括VIP地址和设备 Mac,而路由器收到这个arp请求就会更新自己的arp缓存,这样就会造成ip欺骗了,VIP被抢夺,所以就会有问题。
arp缓存为什么会更新了,什么时候会更新呢,为了减少arp请求的次数,当主机接收到询问自己的arp请求的时候,就会把源ip和源Mac放入自己的arp表里面,方便接下来的通讯。如果收到不是询问自己的包(arp是广播的,所有人都收到),就会丢掉,这样不会造成arp表里面无用数据太多导致 有用的记录被删除。
在设置参数的时候将arp_ignore 设置为1,意味着当别人的arp请求过来的时候,如果接收的设备上面没有这个ip,就不做出响应,默认是0,只要这台机器上面任何一个设备上面有这个ip,就响应arp请求,并发送mac地址
c.测试(浏览器测试或者curl测试,推荐用curl,浏览器缓存有时会对结果有影响)
d.相关脚本
####Director脚本
[root@server1 ~]# vim /etc/init.d/lvs_dr
#!/bin/bash
# LVS script for VS/DR
/etc/rc.d/init.d/functions
VIP=172.25.20.1
RIP1=172.25.20.2
RIP2=172.25.20.3
PORT=80
case "$1" in
start)
echo "starting........"
/sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev eth0:0
# Since this is the Director we must be able to forward packets
echo 1 > /proc/sys/net/ipv4/ip_forward
# Add an IP virtual service for VIP 10.10.6.200 port 80
# In this recipe, we will use the round-robin scheduling method.
# In production, however, you should use a weighted, dynamic scheduling method.
/sbin/ipvsadm -C
/sbin/ipvsadm -A -t $VIP:80 -s rr
# Now direct packets for this VIP to
# the real server IP (RIP) inside the cluster
/sbin/ipvsadm -a -t $VIP:80 -r $RIP1:80 -g
/sbin/ipvsadm -a -t $VIP:80 -r $RIP2:80 -g
# /bin/touch /var/lock/subsys/ipvsadm &> /dev/null
echo "success"
ipvsadm
;;
stop)
# Stop forwarding packets
echo 0 > /proc/sys/net/ipv4/ip_forward
# Reset ipvsadm
/sbin/ipvsadm -C
# Bring down the VIP interface
/sbin/ifconfig eth0:0 down
/sbin/route del $VIP
/bin/rm -f /var/lock/subsys/ipvsadm
echo "ipvs is stopped..."
;;
status)
if [ ! -e /var/lock/subsys/ipvsadm ]; then
echo "ipvsadm is stopped ..."
else
echo "ipvs is running ..."
ipvsadm -L -n
fi
;;
*)
echo "Usage: $0 {start|stop|status}"
;;
esac
[root@server2 ~]# /etc/init.d/lvs_dr stop
[root@server2 ~]# /etc/init.d/lvs_dr start
####Real Server启动脚本(以web1为例,web2相同)
[root@server2 ~]# vim /etc/init.d/lvs_dr
#!/bin/bash
# Script to start LVS DR real server.
# description: LVS DR real server
. /etc/rc.d/init.d/functions
VIP=172.25.20.1
host=`/bin/hostname`
case "$1" in
start)
# Start LVS-DR real server on this machine.
/sbin/ifconfig lo down
/sbin/ifconfig lo up
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev lo:0
echo "success"
route
;;
stop)
# Stop LVS-DR real server loopback device(s).
/sbin/ifconfig lo:0 down
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
;;
status)
# Status of LVS-DR real server.
islothere=`/sbin/ifconfig lo:0 | grep $VIP`
isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
if [ ! "$islothere" -o ! "isrothere" ];then
# Either the route or the lo:0 device
# not found.
echo "LVS-DR real server Stopped."
else
echo "LVS-DR real server Running."
fi
;;
*)
# Invalid entry.
echo "$0: Usage: $0 {start|status|stop}"
exit 1
;;
esac
[root@server2 ~]# /etc/init.d/lvs_dr stop
[root@server2 ~]# /etc/init.d/lvs_dr start
NAT模式配置通过脚本实现
a. 配置LVS服务器(server1)
#### LVS服务器(server1)
vim /etc/init.d/lvs_nat
#!/bin/bash
VIP=172.25.254.200
RIP1=172.25.20.2
RIP2=172.25.20.3
case "$1" in
start)
echo "start LVS of DirectorServer NAT"
echo "1" >/proc/sys/net/ipv4/ip_forward
/sbin/iptables -F
/sbin/ipvsadm -C
/sbin/ifconfig eth0:0 $VIP netmask 255.255.255.0 up
/sbin/ipvsadm -A -t $VIP:80 -s rr
/sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -m
/sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -m
/sbin/ipvsadm
;;
stop)
echo "stop LVS of DirectorServer NAT"
echo "0" >/proc/sys/net/ipv4/ip_forward
/sbin/ipvsadm -C
/sbin/ifconfig eth0:0 down
;;
*)
/etc/init.d/lvs_nat stop
/etc/init.d/lvs_nat start ##启动脚本,开启LVS服务
b.配置后台的两个Real Server服务器(以web1为例,web2相同)
### Real Server服务器(server2)
[root@server2 ~] iptables -F
[root@server2 ~] nginx
[root@server2 ~] route del default ##删除原来的默认网关
[root@server2 ~] route add default gw 172.25.254.200 ##后添加一个默认网关为LVS服务器上的Eth1 IP
[root@server2 ~] route
c.测试 方法同上
感谢关注,该模式暂时未测试通过,稍后更新。。。
[root@server1 ~]# ifconfig tunl0 172.25.254.200 broadcast 172.25.254.200 netmask 255.255.255.255 up
[root@server1 ~]# ipvsadm -A -t 172.25.254.200:80 -s rr
Service already exists
[root@server1 ~]# ipvsadm -D -t 172.25.254.200:80
[root@server1 ~]# ipvsadm -A -t 172.25.254.200:80 -s rr
[root@server1 ~]# ipvsadm -a -t 172.25.254.200:80 -r 172.25.20.2 -i
[root@server1 ~]# ipvsadm -a -t 172.25.254.200:80 -r 172.25.20.3 -i
[root@server1 ~]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.200:http rr
-> server2:http Tunnel 1 0 0
-> server3:http Tunnel 1 0 0
[root@server1 ~]#
[root@server2 ~]# ifconfig tunl0 172.25.254.200 broadcast 172.25.254.200 netmask 255.255.255.255 up
[root@server2 ~]# echo 1 >/proc/sys/net/ipv4/conf/tunl0/arp_ignore
[root@server2 ~]# echo 2 >/proc/sys/net/ipv4/conf/tunl0/arp_announce
[root@server2 ~]# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
[root@server2 ~]# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
[root@server2 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.25.20.0 * 255.255.255.0 U 0 0 0 eth0
link-local * 255.255.0.0 U 1002 0 0 eth0
[root@server2 ~]#
[root@server2 ~]# echo 0 > /proc/sys/net/ipv4/conf/tunl0/rp_filter
[root@server2 ~]# echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
[root@server2 ~]# route add -host 172.25.254.200 dev tunl0
[root@server2 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.25.254.200 * 255.255.255.255 UH 0 0 0 tunl0
172.25.20.0 * 255.255.255.0 U 0 0 0 eth0
link-local * 255.255.0.0 U 1002 0 0 eth0
在客户端上打开LVS上的VIP地址:172.25.254.200即可打开网页,刷新也可以看到网页在变化;
####1.LVS server 配置
[root@server1 ~]# vim /etc/init.d/lvs_tun
#!/bin/bash
VIP=172.25.254.200
RIP1=172.25.20.2
RIP2=172.25.20.3
. /etc/rc.d/init.d/functions
case "$1" in
start)
echo "start LVS of DirectorServer Tun"
/sbin/ifconfig tunl0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route del -host $VIP
/sbin/route add -host $VIP dev tunl0
/sbin/ipvsadm -C
/sbin/ipvsadm -A -t $VIP:80 -s rr
/sbin/ipvsadm -a -t $VIP:80 -r $RIP1:80 -i
/sbin/ipvsadm -a -t $VIP:80 -r $RIP2:80 -i
/sbin/ipvsadm
echo "success"
;;
stop)
echo "stop LVS of DirectorServer Tun"
/sbin/ifconfig tunl0 down
/sbin/ipvsadm -C
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
[root@server1 ~]# chmod +x /etc/init.d/lvs_tun
[root@server1 ~]# /etc/init.d/lvs_tun stop
[root@server1 ~]# /etc/init.d/lvs_tun start
####2.后台两个Real Server服务器的配置(以web1为例,web2相同)
[root@server2 ~]# vim /etc/init.d/lvs_tun
#!/bin/bash
VIP=172.25.254.200
. /etc/rc.d/init.d/functions
case "$1" in
start)
echo "start LVS of RealServer Tun"
/sbin/ifconfig tunl0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route del -host $VIP
/sbin/route add -host $VIP dev tunl0
echo "1" >/proc/sys/net/ipv4/conf/tunl0/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/tunl0/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/tunl0/rp_filter
echo "success"
;;
stop)
echo "close LVS of RealServer Tun"
/sbin/route del -host $VIP
/sbin/ifconfig tunl0 down
echo "0" >/proc/sys/net/ipv4/conf/tunl0/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/tunl0/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/tunl0/rp_filter
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
[root@server2 ~]# chmod +x /etc/init.d/lvs_tun
[root@server2 ~]# /etc/init.d/lvs_tun stop
[root@server2 ~]# /etc/init.d/lvs_tun start
在客户端上打开LVS上的VIP地址:172.25.254.200即可打开网页,刷新也可以看到网页在变化;