LVS-DR 模式网络拓扑图:
LVS-DR 工作原理:
1、客户端向VIP发出请求,请求报文中源IP为CIP,目标IP为VIP,源MAC为客户端的MAC,目标MAC为LVS调度器的MAC(Director)
2、LVS调度器接收到请求后,修改了请求报文中的目标MAC地址(Director会根据算法将请求报文中的目标MAC地址,修改成指定的RS的MAC地址)。并将请求进行广播。
3、RS接受到广播后,拆开报文,发现目标MAC地址是自己,于是开始响应请求。并直接将响应请求发送到客户端。响应的过程不经过LVS调度器。
LVS DR模式的特性:
1、CIP必须能够和VIP通讯,所以通常VIP是外网地址
2、DIP和RIP为同一物理网络,否则无法向RS发送ARP广播
3、RS上必须配置VIP地址,否则响应报文无法送达客户端,RS上的VIP对外界是不可见的,但RS可以接收目标地址为VIP的网络请求,并在回应数据包时将源地址设置为该VIP地址
4、RS上必须做ARP抑制,使RS不响应来自CIP的请求,相当于指定Director来响应CIP的请求
5、调度器几乎支持所有的UNIX、LINUX系统,但不支持windows,但是RS可以为windows
6、RS的网关不能指向DIP,应该指向出口网关
7、DR模式下,不支持端口映射,即Director不能更改请求报文的端口
8、DR模式效率很高,但配置麻烦,访问量不是非常大的情况下推荐使用haproxy或者nginx。标准:日访问量2000W PV以下,或者并发请求1W以下的可以考虑使用haproxy或nginx或使用LVS-NAT模式。
9、直接对外的访问业务,例如:web服务做RS节点,RS最好使用外网IP,如果不直接对外的业务,例如MySQL、存储系统RS节点,最好使用内网IP
LVS-NAT 模式的特性:
1、NAT模式将请求的报文的响应的报文通过调度器进行重写,再转发给RS
2、只需要调度器LB上配置WAN公网IP即可,调度器也要有私网IP和RS节点通讯
3、所有RS节点的网关指向LVS调度器
4、由于请求和响应报文的数据都经过LVS调度器,所有访问量较大的情况下,LVS调度器有较大的瓶颈,一般最多支持节点数10-20台
5、NAT模式支持端口映射,即用户请求为10.10.10.1:80 可以通过调度器转发到10.10.10.2:8080
6、所有NAT内部RS节点只需要配置私有LAN IP即可
7、由于数据包要经过LVS调度器转发,因此需要调度器开启内核转发功能
LVS应用场景:
LVS负载调度器可以应用于绝大多数的TCP和UDP协议
TCP:HTTP、FTP、PROXY、SMTP、POP3、IMAP4、DNS、LDAP、HTTPS、SSMTP等
UDP:DNS、NTP、ICP、视频、音频流播放协议等
LVS-DR安装配置:
查看内核版本
# uname -rm 2.6.32-573.el6.x86_64 x86_64
确认系统内核是否安装了ip_vs
# lsmod | grep ip_vs ip_vs_rr 1420 1 ip_vs 126534 3 ip_vs_rr libcrc32c 1246 1 ip_vs ipv6 335589 314 ip_vs,bridge,ip6t_REJECT
如果grep不到任何信息,则通过创建软连接来解决
ln -sf /usr/src/kernels/2.6.32-642.4.2.el6.x86_64/ /usr/src/linux ll /usr/src total 8 drwxr-xr-x. 2 root root 4096 Sep 23 2011 debug drwxr-xr-x. 3 root root 4096 Aug 30 18:05 kernels lrwxrwxrwx 1 root root 43 Aug 30 18:12 linux -> /usr/src/kernels/2.6.32-642.4.2.el6.x86_64/
注意 /usr/src/kernel/目录后面有多个文件,以uname -r的结果为准。如果上面的
2.6.32-642.4.2.el6.x86_64
不存在,则可能是系统没有安装kernel-devel包,可以通过yum -y install kernel 解决
安装lvs
1、yum安装
yum -y install ipvsadm
2、源码安装
下载ipvsadm源码包:
wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.24.tar.gz
wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz
安装依赖包:
yum -y install libnl* popt*
安装ipvsadm:
# tar zxf ipvsadm-1.26.tar.gz # cd ipvsadm-1.26 #make && make install
#ipvsadm //执行ipvsadm命令,把命令装载到内核 #lsmod | grep ip_vs ip_vs 126534 0 libcrc32c 1246 1 ip_vs ipv6 335589 312 ip_vs,ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6
ipvsadm 命令
集群服务相关: -A:添加一个集群服务 -t:tcp服务 -u:udp服务 -f:firewall mark,通常用于将两个或以上的服务绑定为一个服务进行处理时使用 service-address: -t:IP:port -u:IP:port -f firewall_mark -s:指定调度方法,默认为wlc -p timeout:persistent connection,持久连接 -E:修改定义过的集群服务 RS相关命令: -a:向指定的集群中添加RS -t|-u|-f service—address:指明将RS添加至哪个Cluster Service中 -r:指定RS,可以包含IP+port 只有支持端口映射的LVS类型才允许此处使用跟集群服务中不同的端口 LVS类型: -g:Gateway,DR 默认为DR类型 -i:ipip,TUN -m:masquerade,NAT -w:指定RS的权重 -e:修改指定的RS属性 -d -t|u|f service-address::删除指定的集群服务 清空所有的集群服务: -C 保存规则:(使用输出重定向) ipvsadm-save ipvsadm -S 载入执行的规则:(使用输入重定向) ipvsadm-restore ipvsadm -R 查看ipvs规则等: -L:[option] -n:以数字格式显示IP地址 -c:显示连接数相关信息 --stats:显示统计数据(进来的报文数,出去的报文数等) --rate:报文传输速率(平均每秒连接数、平均每秒进来的连接数、平均每秒出去的字节数、平均每秒进来的字节数) --timeout:超时时常输出 --daemon:显示ipvs集群服务本身的状态数据以及多播接口 --sort:对虚拟服务和RS做排序 --exact:对输出数据不做单位换算,显示其精确值 -Z:计数器清零,清楚统计数据
LVS-DR配置示例:
环境:
3台CentOS 6.7 1台物理机Mac
cat /etc/redhat-release CentOS release 6.7 (Final)
角色:
CIP:172.16.206.1
DIP:172.16.206.129
VIP:172.16.206.110
RIP:172.16.206.128 (web server) 172.16.206.130(web server)
Director配置:
1、配置VIP
#ifconfig eth0:0 172.16.206.110 netmask 255.255.255.255 broadcast 172.16.206.110
2、关闭防火墙或者清空规则
service iptables stop / iptables-F
3、配置IPVS
# ipvsadm -A -t 172.16.206.110:80 -s rr # ipvsadm -a -t 172.16.206.110:80 -r 172.16.206.128 -g # ipvsadm -a -t 172.16.206.110:80 -r 172.16.206.130 -g # ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.206.110:80 rr -> 172.16.206.128:80 Route 1 0 0 -> 172.16.206.130:80 Route 1 0 0
RS配置:
1、配置VIP与路由, 注意两台RS都需要配置
# ifconfig lo:0 172.16.206.110 netmask 255.255.255.255 broadcast 172.16.206.110 # route add -host 172.16.206.110 dev lo:0 //这条配置不是必须的
2、抑制ARP配置
# 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
3、在RS上测试访问本地的web服务器
# curl 172.16.206.130130
# curl 172.16.206.128128
4、客户端测试访问http://172.16.206.110
刷新页面后,变成130 ,表示配置成功
arp_ignore参数是定义linux主机在收到ARP请求数据包后,发送ARP响应数据包的条件级别,该参数的取值范围是0~8,各取值的意义分别是:
0(默认值)-- 只要ARP请求数据包所请求的IP地址属于任一本地地址(即任意一个本机配置的IP地址),就会回应ARP响应数据包,即使该IP地址不属于接收到ARP请求数据包的网卡。
1 -- 只有ARP请求数据包所请求的IP地址属于当前网卡的IP地址,才会回应ARP响应数据包。
2 -- 除了满足1的条件外,还要满足ARP请求数据包的发送方IP地址也属于当前网卡所属子网,这样才会回应ARP响应数据包。
3 -- 如果ARP请求数据包所请求的IP地址对应的本地地址其作用域(scope)为主机(host),则不回应ARP响应数据包,如果作用域为全局(global)或链路(link),则回应ARP响应数据包。
4~7 -- 保留
8 -- 即使ARP请求数据所请求的IP地址属于任何一个本地地址,也不回应ARP响应数据包。
将arp_ignore级别设置为1,表示只有RIP所在网卡接受的请求报文中的目标IP
arp_announce参数是定义linux主机发送ARP请求数据包时如何选择数据包中使用的发送方IP地址(即Sender IP address)。在系统准备通过网卡发送一个IP数据包前,该IP数据包的源IP地址和目标IP地址通常是已经知道的,同时发送的网卡也已经确定,那数据链路层的源MAC地址当然也确定了,最后剩下的就是确定数据链路层的目标MAC地址了,而该目标MAC地址就需要通过ARP地址解释协议来获取,于是系统首先需要发送ARP请求数据包获取目标MAC地址。结合上面关于ARP原理的描述,我们知道,发送ARP请求数据包时需要包含发送方IP地址,该IP地址应该是什么呢?大家可能想当然的以为就是要发送的IP数据包的源IP地址,其实这个是不一定的,尤其是主机有多个网络接口和IP地址时,而arp_announce正是控制该发送方IP地址的选择条件的。arp_announce参数的取值分别是0、1、2,这些取值的意义如下:
0(默认值)-- 允许使用任一网络接口配置的IP地址(即任一本地地址),通常就是待发送的IP数据包的源IP地址。
1 -- 尽量避免使用不属于该网络接口(即发送数据包的网络接口)子网的本地地址作为发送方IP地址。根据我对官方原文的理解,就是说如果主机包含多个子网,而IP数据包的源IP地址属于其中一个子网,虽然该IP地址不属于本网口的子网,但是也可以作为ARP请求数据包的发送方IP地址,否则就会按照取值为2的方式选择发送方IP地址。
2 -- 忽略IP数据包的源IP地址,总是选择网口所配置的最合适的IP地址作为ARP请求数据包的发送方IP地址(一个网口可能会配置多个IP地址)。
arp_announce的作用是什么呢?设置为不同的值会有什么不同的作用呢?或者说有什么不同的影响呢?下面我们来举个例子说明不同值的影响。不过要理解以下的影响,我们要了解,对于网络设备(三层交换机、路由器)及主机,其ARP地址表(包含IP地址和MAC地址对应关系的表)是如何建立的:当设备或主机收到一个ARP请求数据包时,它会把ARP请求数据包的发送方IP地址和MAC地址的对应关系放入自身的ARP地址表。理解了上面所说的,我们来看看实际的案例场景:假设linux主机有A、B两块网卡,其对应的IP地址分别为IP_A、IP_B,对应的MAC地址为MAC_A、MAC_B,假设一个应用程序准备与外部通信,它的socket绑定了源IP地址为IP_A,但是根据系统路由及相关设置,其通信数据包将会从B网卡发送,在发送数据包前,系统会通过网卡B发送ARP请求数据包。如果我们将arp_announce的值设定为0,那该ARP请求数据包的发送方IP地址是IP_A,而发送方MAC地址为MAC_B,这样就会在网络设备或对方主机的ARP地址表上留下IP_A与MAC_B的对应记录,但是实际正确的应该是IP_A对应MAC_A、IP_B对应MAC_B,所以这可能会引起潜在的网络问题,具体问题和表现与网络的拓扑结构及网络配置有关。而如果我们将arp_announce设置为2,那在发送ARP请求数据包时,发送方IP地址将不是IP_A,而是IP_B,这样就不会引起刚才所说的问题
关于arp_ignore 和arp_announce的配置解释,请参考:
http://www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
http://blog.chinaunix.net/uid-13423994-id-5146098.html
参考资料:
lvs的配置可以写成脚本:请参考:
http://blog.chinaunix.net/uid-25954426-id-3478536.html