centos   LB负载均衡集群 三种模式区别 LVS/NAT 配置  LVS/DR 配置  LVS/DR + keepalived配置  nginx ip_hash 实现长连接  LVS是四层LB  注意down掉网卡的方法  nginx效率没有LVS高  ipvsadm命令集  测试LVS方法 第三十三节课

 

LVS核心模块就是IPVS,安装在Director上,Director就是一个路由器,他包含有完成lvs功能的路由表,通过这些路由表把用户请求分发到real server。
同时,在Director上还要安装对realserver的监控模块LDirectord(LDirectord是heartbeat里面的一个插件,还需要perl-MailTools这个rpm包),这个模块用于监测各个real server服务的健康状况, 在real server不可用时把其从lvs路由表中剔除,在恢复时再重新加入

 

LVS即使其中一台web服务器挂掉,LVS依然会把请求分发到挂掉的服务器,这是LVS的缺点

LVS权重最大100 最小0

用户的登录态的保持
1、服务器间用共享存储
2、用长连接,不允许会话切换web服务器,让会话保持在一台服务器

服务器:session
客户端:cookies

 

 

 

三种模式区别

$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 1  //-a增加一个real server  -m NAT模式 -g dr模式 -t tun模式  -w权重

NAT模式:director负责接受请求和返回请求,realserver可以是任意操作系统,dr的vip和dip只需要不同网段就可以

DR模式/TUN模式:返回请求不需要经过director,director只负责分发接受的请求,realserver只能是Unix like操作系统

DR模式和TUN模式区别:TUN模式realserver和dr通信使用隧道(修改了ip包头),DR模式不使用隧道(修改MAC地址)

三种模式都不需要公网IP,客户端,dr,realserver都在同一个内网里面都可以

如果dr用公网ip,那么realserver的rip也要用公网ip

 

 

dip:director ip

rip:real server ip

 

上半节课

三种模式区别
LVS/NAT 配置
LVS/DR 配置

 

 

下半节课

LVS/DR + keepalived配置
nginx ip_hash 实现长连接
LVS是四层LB
注意down掉网卡的方法
nginx效率没有LVS高
ipvsadm命令集

 

 

 

 

nginx hash真实ip nginx ip_hash配置_开发工具

NAT模式(Virtual server via NAT(VS-NAT))

nginx hash真实ip nginx ip_hash配置_nginx hash真实ip_02

DR模式(Virtual Server via Direct Routing(VS-DR))

TUN模式(Virtual server via IP tunneling(VS-TUN))

nginx hash真实ip nginx ip_hash配置_nginx_03

 

 

 

常用的负载均衡开源软件有: nginx、lvs、keepalived
商业的硬件负载设备: F5、Netscale

1. LB、LVS介绍LB集群是load balance 集群的简写,翻译成中文就是负载均衡集群

LVS是一个实现负载均衡集群的开源软件项目
LVS架构从逻辑上可分为调度层(Director)、server集群层(Real server)和共享存储层

LVS可分为三种工作模式: ( dr模式参考这篇文章 http://os.51cto.com/art/201105/264303.htm 这篇介绍的还是挺详细的: http://www.it165.net/admin/html/201401/2248.html )
1、NAT NAT (调度器将请求的目标ip即vip地址改为Real server的ip, 返回的数据包也经过调度器,调度器再把源地址修改为vip)
2、TUN   IP tunneling(调度器将请求来的数据包封装加密通过ip隧道转发到后端的real server上,而real server会直接把数据返回给客户端,而不再经过调度器)
3、DR  Direct Routing(调度器将请求来的数据包的目标mac地址改为real server的mac地址,返回的时候也不经过调度器,直接返回给客户端)


LVS最最常用的4种调度算法:
1、轮询调度(Round Robin)(简称rr)
2、加权轮询(Weighted Round Robin)(简称wrr)
3、最少链接(least connection)(LC)  分配给现在最少链接那台机 
4、加权最少链接(Weighted Least Connections)(WLC)
等等 (其他算法,参考 http://www.aminglinux.com/bbs/thread-7407-1-1.html)

 

 

2. LVS/NAT配置
三台服务器一台作为director, 两台作为real server
Director 有一个ip (192.168.31.166) 和一个ip(192.168.21.166),

两个real server上只有ip(192.168.21.100)和(192.168.21.101) 并且需要把两个real server的内网网关(eth0的gateway)设置为director的内网ip(192.168.21.166)

检查一下网关是否成功设置  route -n  
两个real server 上都安装httpd: yum install -y httpd
Director上安装ipvsadm,  yum install -y ipvsadm
Direcotr 上 vim /usr/local/sbin/lvs_nat.sh //增加:



#! /bin/bash
# director 服务器上开启路由转发功能: 
echo 1 > /proc/sys/net/ipv4/ip_forward 
# 关闭icmp的重定向
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth1/send_redirects

# director 设置nat防火墙
iptables -t nat -F
iptables -t nat -X
iptables -t nat -A POSTROUTING -s 192.168.21.0/24 -j MASQUERADE
# director设置ipvsadm
IPVSADM='/sbin/ipvsadm'
$IPVSADM -C    //相当于iptables -F 清空规则
$IPVSADM -A -t 192.168.31.166:80 -s lc -p 30   //-A增加dr  -s算法 默认rr轮询 lc最少链接 -p长链接 30秒 30秒内不停发送keepalive包给realserver 30秒后断开链接
$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 1  //-a增加一个real server  -m 使用NAT模式 -g dr模式 -t tun模式  -w权重
$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.101:80 -m -w 1



192.168.31.166  VIP

192.168.21.166 DIP

192.168.21.100 RIP

192.168.21.101 RIP

192.168.31.x 

192.168.21.x 

直接运行这个脚本就可以完成lvs/nat的配置了:
/bin/bash /usr/local/sbin/lvs_nat.sh
通过浏览器测试两台机器上的httpd内容

查看一下规则



iptables -nvL -t nat



查看一下ipvsadm规则



ipvsadm -l



ipvsadm -ln



 

在客户端进行测试

Linux客户端



for i in `seq 1 100`; do curl 192.168.31.166;sleep 1;done



 

Windows客户端

 在浏览器输入  192.168.31.166

 

修改了规则需要重新执行一下



vi /usr/local/sbin/lvs_nat.sh   //修改规则
sh /usr/local/sbin/lvs_nat.sh  //重新执行脚本,使生效


 

nginx hash真实ip nginx ip_hash配置_开发工具_04

 

 

3. LVS/DR 配置

每个realserver返回请求不需要经过director,director只负责分发接受的请求

DR需要安装ipvsadm

RS不需要安装ipvsadm

三台机器:

director(eth0:192.168.31.166, vip eth0:0: 192.168.31.110) vip不需要配置i,只需要写在脚本里就可以
real server1(eth0 rip: 192.168. 31.100, vip lo:0: 192.168.31.110)
real server2(eth0 rip: 192.168.31.101, vip lo:0: 192.168.31.110)
Director 上 vim /usr/local/sbin/lvs_dr.sh //增加

#! /bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
ipv=/sbin/ipvsadm
vip=192.168.31.110
rs1=192.168.31.100 
rs2=192.168.31.101
ifdown eth0:0  //先down掉eth0:0 ,不然重新执行/usr/local/sbin/lvs_dr.sh 脚本会报网卡已启动
ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up //绑定vip netmask 表示无网段 注意机器上是否有eth0
route add -host $vip dev eth0:0 //加个路由
$ipv -C
$ipv -A -t $vip:80 -s wrr
$ipv -a -t $vip:80 -r $rs1:80 -g -w 1 //-g表示DR模式
$ipv -a -t $vip:80 -r $rs2:80 -g -w 1

两台rs上:vim /usr/local/sbin/lvs_dr_rs.sh
#! /bin/bash
vip=192.168.31.110
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up   //注意这里绑定的是lo 回环地址
route add -host $vip lo:0
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

关于arp_ignore和 arp_announce 参考:

然后director上执行: bash /usr/local/sbin/lvs_dr.sh
两台rs上执行: bash /usr/local/sbin/lvs_dr_rs.sh
Windows下浏览器测试访问

nginx hash真实ip nginx ip_hash配置_开发工具_05

 

测试

测试LVS 
机器1
echo "rs1rs1rs1rs1" >/usr/share/nginx/html/index.html
机器2
echo "rs2rs2rs2rs2" >/usr/share/nginx/html/index.html


 

下半节课 

 

4. LVS/DR + keepalived配置

keepalived可以帮助LVS检测后端服务器的存活,将请求只转发到存活的机器

keepalived的诞生本来是为LVS而设计的,后来加入了VRRP协议

注意:前面虽然我们已经配置过一些操作,但是下面我们使用keepaliave操作和之前的操作是有些冲突的,所以若是之前配置过DR,请首先做如下操作

dr上执行:



$ipv -C   //清空规则
$ifdown eth0:0



 

前面的lvs虽然已经配置成功也实现了负载均衡,但是我们测试的时候发现,当某台real server把httpd进程停掉,那么director照样会把请求转发过去,这样就造成了某些请求不正常。所以需要有一种机制用来检测real server的状态,这就是keepalived。它的作用除了可以检测rs状态外,还可以检测备用director的状态,也就是说keepalived可以实现ha集群的功能,当然了也需要一台备用director.
主备director都需要安装一下keepalived软件和ipvsadm,需要先安装epel扩展源



yum install -y keepalived
yum install -y ipvsadm



安装好后,编辑配置文件
vim /etc/keepalived/keepalived.conf //加入如下:



vrrp_instance VI_1 {
state MASTER #备用服务器上为 BACKUP
interface eth0
virtual_router_id 51
priority 100 #备用服务器上为90
advert_int 1
authentication {
auth_type PASS  #跟heartbeat一样要指定加密方式和密码
auth_pass 1111
}
virtual_ipaddress {
192.168.31.110   #直接取192.168.31.110这个LVS的vip作为keepalived的vip而不是另取一个新的vip
}
}
virtual_server 192.168.31.110 80 { #直接取192.168.31.110这个LVS的vip作为keepalived的vip而不是另取一个新的vip
delay_loop 6 #(每隔6秒查询realserver状态)
lb_algo wlc #(lvs 算法)
lb_kind DR #(Direct Route)
persistence_timeout 30 #(同一IP的连接30秒内被分配到同一台realserver)
protocol TCP #(用TCP协议检查realserver状态)

real_server 192.168.31.100 80 {
weight 100 #(权重)
TCP_CHECK {
connect_timeout 10 #(10秒无响应超时)
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.31.101 80 {
weight 100
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}



以上为主director的配置文件,从director的配置文件只需要修改

state MASTER -> state BACKUP
priority 100 -> priority 90

使用ip addr 查看vip是否已经启动



ip addr



 

配置完keepalived后,需要开启端口转发(主从都要做):
echo 1 > /proc/sys/net/ipv4/ip_forward
然后,两个rs上执行 /usr/local/sbin/lvs_dr_rs.sh 脚本
最后,两个director上启动keepalived服务(先主后从):
/etc/init.d/keepalived start
另外,需要注意的是,主从dr上启动keepalived服务会自动生成vip和ipvsadm规则,不需要再去执行dr里面的/usr/local/sbin/lvs_dr.sh 脚本。

由于keepalived没有单独日志,如果有问题,需要看 /var/log/message 里面的错误

nginx hash真实ip nginx ip_hash配置_开发工具_06

 

nginx hash真实ip nginx ip_hash配置_后端_07

两台rs上:vim /usr/local/sbin/lvs_dr_rs.sh

#! /bin/bash
vip=192.168.31.110
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up   //注意这里绑定的是lo 回环地址
route add -host $vip lo:0
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_announcesh  /usr/local/sbin/lvs_dr_rs.sh

停止rs2上的nginx,dr不会将请求发到rs2

/etc/init.d/nginx stop

nginx hash真实ip nginx ip_hash配置_nginx hash真实ip_08

Removing service [192.168.31.101]:80 from VS virtual server [192.168.31.110]:80

重新启动rs2上的nginx,dr会马上自动把请求发到rs2

/etc/init.d/nginx start

 

从上安装配置keepalived和ipvsadm



scp -P 2200 /etc/keepalived/keepalived.conf   192.168.31.112:/etc/keepalived/keepalived.conf
vi /etc/keepalived/keepalived.conf 
state MASTER #备用服务器上为 BACKUP
priority 100 #备用服务器上为90
/etc/init.d/keepalived start

tail /var/log/message
ipvsadm -ln
ip addr  //从上是没有vip的



 

主从切换模式



/etc/init.d/keepalived stop



或者



iptables -I OUTPUT  -d 224.0.0.18  -j DROP



 

5.nginx ip_hash 实现长连接
upstream test {
 ip_hash;
 server 192.168.31.100;
 server 192.168.31.101;
} server {
 listen 80;
 server_name bbs.aaa.cn; location / {
 proxy_pass http://test/;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }


}

支持下面负载均衡算法
轮询
加权轮询
ip_hash
URL_hash

ip_hash的坏处,服务器宕机,nginx依然会把请求发到宕机那台机,除非用轮询才会转发到别的机器或者用down标记那个宕机机器
# 正常情况下是由 tomcat3 来应答的,当 tomcat3 死掉后

upstream bbs_server_pool {
       ip_hash;
       server 192.168.1.80:8080;
       server 192.168.1.80:8081;
       server 192.168.1.80:8082 down;
    }

ip_hash的两个问题
1、是否支持权重  ,不支持权重
2、保持链接多长时间 ,不支持保持链接,只是根据来源ip总是发送到某一台机

 

测试

测试NGINX
机器1 
echo "rs1rs1rs1rs1" >/usr/share/nginx/html/index.html 
机器2 
echo "rs2rs2rs2rs2" >/usr/share/nginx/html/index.html

 

扩展学习:
haproxy+keepalived http://blog.csdn.net/xrt95050/article/details/40926255
nginx、lvs、haproxy比较 http://www.csdn.net/article/2014-07-24/2820837
keepalived中自定义脚本 vrrp_script http://www.linuxidc.com/Linux/2012-08/69383.htm

http://my.oschina.net/hncscwc/blog/158746nginx代理 http://www.apelearn.com/bbs/thread-64-1-1.html
nginx长连接 http://www.apelearn.com/bbs/thread-6545-1-1.html

 


 

LVS是四层LB

NAT模式

基于tcp/ip ,端口转发

所以端口,后边的服务都可以随便改,LVS只负责转发端口

httpd 可以改为nginx
$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 1 可以改为$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:8080 -m -w 1

NAT模式

权重设置
# director设置ipvsadm
IPVSADM='/sbin/ipvsadm'
$IPVSADM -C
$IPVSADM -A -t 192.168.31.166:80 -s wlc 
$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 2 
$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.101:80 -m -w 10或者
# director设置ipvsadm
IPVSADM='/sbin/ipvsadm'
$IPVSADM -C
$IPVSADM -A -t 192.168.31.166:80 -s wrr 
$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.100:80 -m -w 2 
$IPVSADM -a -t 192.168.31.166:80 -r 192.168.21.101:80 -m -w 10 
注意down掉网卡的方法
测试环境:centos6.6
不要用ifconfig eth0 up/down 的方法
ifconfig eth1:0 up/down 
SIOCSIFFLAGS: 无法指定被请求的地址 
要用ifup/ifdown
ifup eth1:0 
Determining if ip address 192.168.1.115 is already in use for device eth1...
[root@steven network-scripts]# ifconfig

 

另外,一个网卡多个ip,down掉一个ip并不会导致整个网卡down掉

eth1 Link encap:Ethernet HWaddr 00:0C:29:01:D5:CB 
 inet addr:192.168.1.106 Bcast:192.168.1.255 Mask:255.255.255.0
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
 RX packets:33032 errors:0 dropped:0 overruns:0 frame:0
 TX packets:4882 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000 
 RX bytes:8892933 (8.4 MiB) TX bytes:421479 (411.6 KiB)eth1:0 Link encap:Ethernet HWaddr 00:0C:29:01:D5:CB 
 inet addr:192.168.1.115 Bcast:192.168.1.255 Mask:255.255.255.0
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

 

---------------------------

# ifdown eth1:0
[root@steven network-scripts]# ifconfig
eth1 Link encap:Ethernet HWaddr 00:0C:29:01:D5:CB 
 inet addr:192.168.1.106 Bcast:192.168.1.255 Mask:255.255.255.0
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
 RX packets:33548 errors:0 dropped:0 overruns:0 frame:0
 TX packets:4938 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000 
 RX bytes:8925293 (8.5 MiB) TX bytes:427603 (417.5 KiB)lo Link encap:Local Loopback 
 inet addr:127.0.0.1 Mask:255.0.0.0
 UP LOOPBACK RUNNING MTU:65536 Metric:1
 RX packets:15 errors:0 dropped:0 overruns:0 frame:0
 TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:0 
 RX bytes:2508 (2.4 KiB) TX bytes:2508 (2.4 KiB)

 

nginx效率没有LVS高

nginx: 匹配域名 匹配目录 匹配URL,工作在七层

LVS:只能转发IP包,工作在四层

各有优势 


 

ipvsadm命令集

ipvsadm -ln
l:列出来
n:数字显示$IPVSADM -C //相当于iptables -F 清空规则
$IPVSADM -A //-A增加dr
$IPVSADM -a //-a增加一个real server
ipvsadm -ln //查看规则

两个后端apache的动静分离、负载均衡

http://www.apelearn.com/bbs/thread-64-1-1.html

跟lnmp/lamp阶段复习差不多

针对apache和nginx共同协作的网站架构,也可以根据动态内容和静态内容的请求来做负载均衡
如:

upstream apache.com{
            server  1.2.3.1:80;
            server  1.2.3.4:80;
        }
location   ~*   .*\.(php|phps|jsp)$ 
        {
                proxy_pass  http://apache.com;
        }

 

keepalived和VRRP协议
http://blog.csdn.net/xrt95050/article/details/40926255VRRP通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP多播(multicast)包(多播地址224.0.0.18)形式发送的。


xiaohuazi: VRRP协议简介 在现实的网络环境中,两台需要通信的主机大多数情况下并没有直接的物理连接。对于这样的情况,它们之间路由怎样选择?主机如何选定到达目的主机的下一跳路由,这个问题通常的解决方法有二种:
1、在主机上使用动态路由协议(RIP、OSPF等)
2、在主机上配置静态路由


VIP的飘动可以为我们解决很多问题,以前我试过使用ifup/ifdown的方式控制网卡的up/down来实现,这种方式有个小问题,就是每次VIP 飘动之后都要等上几十秒才能生效,感觉时间比较长,而且还要配合一些逻辑脚本才能很好地工作,有没有更好的方法呢?当然有,这就是本文的主角—— keepalived。

 


负载均衡的发展历程
1998 LVS项目成立
2000 HAProxy项目成立
2004 NGINX推出公共版本
2004 F5推出TMOS平台
2007 F5开始提供应用交付(ADC)产品
负载平衡、SSL卸载、压缩优化、TCP连接优化

(一)LVS的痛点
LVS最常用的有NAT、DR以及新的FULL NAT模式。上图比较了几种常见转发模式的优缺点。

我们认为LVS的每种模式都有其优点和缺点,但最大的问题是其复杂性。相信很多朋友看到这三种方式的优缺点、还有F5的单臂模式、双臂模式都会有云里雾里的感觉。

(二)LVS集群的痛点

nginx hash真实ip nginx ip_hash配置_nginx_09




雪上加霜的是咱们还需要考虑LVS的性能扩展和容灾方法,这使得整个方案更加的复杂。常见的有基于Keepalived的主备方式和ECMP两种。

Keepalived主备模式设备利用率低;不能横向扩展;VRRP协议,有脑裂的风险。而ECMP的方式需要了解动态路由协议,LVS和交换机均需要较复杂配置;交换机的HASH算法一般比较简单,增加删除节点会造成HASH重分布,可能导致当前TCP连接全部中断;部分交换机的ECMP在处理分片包时会有BUG。



基于DR转发方式

LVS支持四种转发模式:NAT、DR、TUNNEL和FULLNAT(FULLNAT最近新加入的模式 还为合并到内核主线),其实各有利弊。Vortex在设计之初就对四种模式做了评估,最后发现在虚拟化的环境下DR方式在各方面比较平衡,并且符合我们追求极致性能的理念。

DR方式最大的优点是绝佳的性能,只有request需要负载均衡器处理,response可以直接从后端服务器返回客户机,不论是吞吐还是延时都是最好的分发方式。

其次,DR方式不像NAT模式需要复杂的路由设置,而且不像NAT模式当client和后端服务器处于同一个子网就无法正常工作。DR的这个特性使他特别合适作为内网负载均衡。

此外,不像FULLNAT一样需要先修改源IP再使用 TOA 传递源地址,还得在负载均衡器DR和后端服务器上RS都编译非主线main line的Kernel Module,DR可以KISS(Keep It Simple, Stupid)地将源地址传递给后端服务器。


最后,虚拟化环境中已经采用Overlay虚拟网络了,所以TUNNEL的方式变得完全多余。而DR方式最大的缺点:需要LB和后端服务器在同一个二层网络,而这在UCloud的虚拟化网络中完全不是问题。主流的SDN方案追求的正是大二层带来的无缝迁移体验,且早已采用各种优化手段(例如ARP代理)来优化大二层虚拟网络。

 

f