lvs_dr

实验需求(4台虚拟机)

eth0		192.168.1.110		单网卡  client(可以使用windows浏览器代替,但会有缓存影响)
eth0 192.168.1.186 单网卡 dir 调度器
eth0 192.168.1.185 单网卡 rs1 真实服务器1
eth0 192.168.1.190 单网卡 rs2 真实服务器2
192.168.1.160 VIP
关闭各虚拟机的iptables

配置环境

  • dir安装lvs的lvs管理软件
yum install -y ipvsadm
  • 2台rs上安装nginx
yum install -y nginx
echo "rs1 nginx" > /usr/share/nginx/html/index.html
echo "rs2 nginx" > /usr/share/nginx/html/index.html

dir脚本

vim /usr/local/sbin/lvs_dr.sh

#!/bin/bash
# director服务器上开启路由转发功能
# echo 1 > /proc/sys/net/ipv4/ip_forward
# 测试发现因为调度器跟real_server在同一网段,如果需要转发给外网或别的网段就打开
ipv=/sbin/ipvsadm
vip=192.168.1.160
rs1=192.168.1.185
rs2=192.168.1.190
ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up
# 注意子网掩码是255.255.255.255,代表vip所在网段没有别的主机了
route add -host $vip dev eth0:0
# 增加一条路由
$ipv -C
$ipv -A -t $vip:80 -s rr
$ipv -a -t $vip:80 -r $rs1:80 -g -w 1
$ipv -a -t $vip:80 -r $rs2:80 -g -w 1
# -g代表dr模式

执行dir脚本

sh /usr/local/sbin/lvs_dr.sh

查看dir是否搭建成功

[root@dir sbin]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.160:80 rr
-> 192.168.1.185:80 Route 1 0 0
-> 192.168.1.190:80 Route 1 0 0

real_server1 和 real_server2 脚本

vim /usr/local/sbin/lvs_rs.sh

#!/bin/bash
vip=192.168.1.160
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce

执行脚本

sh /usr/local/sbin/lvs_rs.sh

测试:(在client上测试)

curl 192.168.1.160
[root@dir ~]# curl 192.168.1.160
rs1 nginx
[root@dir ~]# curl 192.168.1.160
rs2 nginx
[root@dir ~]# curl 192.168.1.160
rs1 nginx
[root@dir ~]# curl 192.168.1.160
rs2 nginx

lvs_dr环境中arp参数

dr模式下,会查询各网卡信息(在dir上查看arp的信息)

[root@dir ~]# arp -n
Address HWtype HWaddress Flags Mask Iface
192.168.1.110 ether 00:0c:29:5a:c3:48 C eth0
192.168.1.185 ether 00:0c:29:be:c6:a9 C eth0
192.168.1.1 ether 84:c9:b2:2a:05:b1 C eth0
192.168.1.190 ether 00:0c:29:c4:57:a1 C eth0
192.168.1.115 ether 10:bf:48:de:5d:54 C eth0

请求流程如下

client在发起请求之前,会发一个arp广播的包,在网络中找“谁是vip”,
由于所有的服务器,lvs和res都有vip,为了让client的请求送到lvs上,
所以必须让res不能响应client发出的arp请求,
(这也是为什么要禁止res上arp的请求和响应)下面就是lvs转发的事情了: 1. client向目标vip发送请求,lvs接收;此时ip包和数据信息如下:
src mac dst mac src_ip dst_ip
192.168.1.110 192.168.1.160 2. lvs根据负载均衡的算法,选择一台realserver,然后把realserver1的mac地址作为目的mac地址,发送到局域网中
src mac dst mac src_ip dst_ip
192.168.1.110 192.168.1.160 3. realserver1在局域网中收到这个请求以后,发现目的ip和本地匹配,于是进行处理;
处理完成以后,直接把源ip和目的ip直接对调,然后经过网关直接返回给用户;
src mac dst mac src_ip dst_ip
192.168.1.160 192.168.1.110

以下参考http://blog.csdn.net/han156/article/details/78452219

ipvsadm脚本详细解析

  1. 客户端:CIP
  2. 调度器VS:VIP,DIP(VIP用于接收客户端的请求;DIP用于和本网段中的RS通讯,以便获取$RIP的MAC地址;)
  3. 真实服务器RS:VIP,RIP(VIP用于发送响应包给客户端;RIP用于和调度器通讯,以便调度器区分不同的RS;)
客户端发送一个目标是VIP的请求包,通过路由器最终到达调度器。
进入VIP的网卡,经过调度器的PREROUTING链之后,查看自己的路由表,发现目标是自己,然后就会发往INPUT链;
在数据到达INPUT链之前,被IPVS拦下来,通过查看IPVS中的定义的规则和算法确定了要将该请求发送到哪台RS服务器上。
("规则"就是通过ipvsadm命令添加的数据,例如:"ipvsadm -a -t $VIP:80 -r $RIP:80 -g -w 1") 在发送请求包之前,调度器会先发送一个广播包,询问"$RIP,你的mac地址是什么?"
$RIP收到广播之后,就发送一个回应的广播包,说:"$RIP的MAC地址是*****"。
(注意:并不是每次都要询问$RIP的MAC地址的,如果调度器中有缓存的话,也就不会再问了。)

问题:有人可能会有疑问,RS上不是拒绝响应arp请求的吗?怎么还会回应!

RIP中配置的两个参数,arp_ignore=1,表示
"如果这个arp请求,是询问我这个接口上的IP的mac地址的话,我才会响应。
而0,表示,这个arp只要是询问我这个主机上的任何一个IP,我都要响应。"
由于调度器发的arp请求中,询问的IP是$RIP,所以,只会有$RIP对应的那个网卡才会响应。 调度器收到$RIP回应的广播包之后,就将客户端的请求重新封装,
请求包中的源IP和目标IP不变,将包中的目标mac地址改成$RIP的mac地址,然后将包发送给$RIP所对应的RS服务器。 当RS收到从调度器转发来的客户端的请求的时候,通过解封装后,得知客户端的请求,
然后做出响应,将响应包通过本机上经过特殊处理的VIP,发送给网关。通过互联网发送给客户端。

DR配置中,有几个比较特别的步骤:

  • LVS上的:
ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up
# 表示:在eth0网卡上声明一个网卡别名eth0:0,它对应的IP是$VIP,他的广播域是他自己;
#(将VIP和DIP绑定在一个物理网卡上。)
route add -host $vip dev eth0:0
# 表示:在路由表中添加一条路由,指定,目标IP地址是$RIP的数据包,走eth0:0接口。
#(由于LVS上的VIP和DIP是在一个网卡上的,必须通过eth0:0接口才可以出去。)
  • RS上的:
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
# 表示:在本地回环网卡上声明一个网卡别名lo:0,他对应的IP是VIP,它的广播域是他自己;
route add -host $vip lo:0
# 表示:在路由表中添加一条路由,指定,目标IP地址是$VIP的数据包,走lo:0接口。
#(从这个接口,他出不去,只会在lo:0里面转。)
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore # 表示:arp请求,如果是询问我这个接口上的IP的mac地址的话,我才会响应。
# 而0,表示,这个arp只要是询问我这个主机上的任何一个IP,我都要响应。
# 由于每个RS上都有VIP,默认值"0",会造成局域网中IP地址冲突。
# 当路由器询问谁$VIP的mac地址的时候,RS不要响应。 # 注意:对于arp_ignore参数,all/ 和{interface}/ 下两者同时比较,取较大一个值生效。 echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce # 表示:不对外声明我在使用Vip地址,因为由于调度器和RS在同一个网络中,
# 如果RS声明自己有$VIP的地址的话,会造成通讯紊乱,影响调度器和路由器之间的通讯。
# all/ 和{interface}/ 下两者同时比较,取较大一个值生效。
# 提高约束级别有益于从指定的目标接受应答,而降低级别可以给予更多的arp查询者以反馈信息 # 注意:默认情况下,上面四个参数的值都是"0";
dr模式小结
DR模式最大的特点是LBserver和后端的rs都要配置同一个VIP
(rs端vip要配置在回环网卡上,即只让LBserver上的vip对外) 通过LBserver将client端发过来数据包添加MAC头,通过MAC直接将数据包传到后端rs上
(所以LBserer的ip与rs的ip要在同一物理网段内) 此时后端回环网卡上也配置了同一个vip,正好对应数据包上的目的ip。
rs收到数据包后不用通过LBserver返回数据包,而是直接将数据包返还给client
(这也是为什么dr模式rs上也需要配置公网ip)
待确定的问题

在调度器上不能请求vip,直接执行curl vip会等待很久然后返回无host

猜测是发出的数据不能进入dir的vip网卡,而后端real_server的vip只能通过MAC地址接收

(但这个信息包没有包含网卡信息)

lvs_dr的更多相关文章

  1. keepalived深度结合lvs_dr模式

    keepalived与dr模式结合 keepalived介绍 keepalived可提供vrrp以及health-check功能,可以只用它提供双机浮动的vip(vrrp虚拟路由功能), 这样可以简单 ...

  2. LVS_DR模式构建配置

    一.环境准备 lvs负载均衡器 系统:centos6.8 ip:192.168.2.203 vip:192.168.2.17 web服务器RS1 系统:centos6.8 ip:192.168.2.2 ...

  3. 用pyhton配置LVS_DR模式

    import paramiko vip = '192.168.42.250' ds = '192.168.42.8' rs1 = '192.168.42.9' rs2 = '192.168.42.10 ...

  4. LVS集群之DR模式 实现

    ps:做 dr 模式 之前,先把之前做过的操作清空掉 1.ipvsadm -ln 查看规则 2.ipvsadm -C 清空规则 3.ipvsadm -ln 确认 4.iptables -t nat - ...

  5. LB集群

    LB集群   1. LB.LVS介绍LB集群是load balance 集群的简写,翻译成中文就是负载均衡集群LVS是一个实现负载均衡集群的开源软件项目 LVS架构从逻辑上可分为调度层(Directo ...

  6. 负载均衡lvs_dr_tcp_http单调度

    准备三台虚拟,均为CentOS6.5 x86_64注意,配置过程中,保持端口的一致性.director (eth0 192.168.1.189, vip eth0:0: 192.168.1.18) D ...

  7. 使用LVS实现负载均衡原理及安装配置详解

    负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F5.Netscale.这里主要是学 ...

  8. 初探LVS NAT与DR

    1. LB.LVS介绍LB集群是load balance 集群的简写,翻译成中文就是负载均衡集群 LVS是一个实现负载均衡集群的开源软件项目 LVS架构从逻辑上可分为调度层(Director).ser ...

  9. keepalive之LVS-DR架构

    author:JevonWei 版权声明:原创作品 Keepalive实战之LVS-DR 实验目的:构建LVS-DR架构,为了达到LVS的高可用目的,故在LVS-DR的Director端做Keepal ...

随机推荐

  1. tornado SSL 证书获取与服务器配置

    转载注明出处: http://www.cnblogs.com/ityoung/p/8296088.html 自动化测试/持续集成/测试开发 QQ交流群: 70160503 服务端生成证书 进入 ope ...

  2. eslint 的基本配置介绍

    eslint 这个代码规则,是在用webpack +vue-cli这个脚手架时候接触的,默认的规则可能不太习惯我们日常平时的代码开发,需要对这个规则稍加改造. 下面的是 eslintrc.js的基本规 ...

  3. 正则表达式中的 \b 什么意思?

    以前经常看到类似这样的正则表达式:\bhi\b 不知道什么意思,今天特意去查了下. 原来\b是正则表达式规定的一个特殊代码,也叫元字符,\b代表着单词的开头或结尾,也就是单词的分界处.

  4. Keepalived概述和安装(1)

    一.Keepalived概述 本文主要了解开源高可用负载均衡集群利器keepalived,掌握keepalived的安装,运用keepalived配置高可用集群,并能够实现keepalived与负载均 ...

  5. CSS position: absolute、relative定位问题详解

    CSS2.0 HandBook上的解释:  设置此属性值为 absolute 会将对象拖离出正常的文档流绝对定位,而不考虑它周围内容的布局.假如其他具有不同 z-index 属性的对象已经占据了给定的 ...

  6. 【Java学习笔记之十七】Java中普通代码块,构造代码块,静态代码块区别及代码示例分析

    //执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1 普通代码块 //普通代码块:在 ...

  7. 【Java学习笔记之七】java函数的语法规则总结

    函数的概述 发现不断进行加法运算,为了提高代码的复用性,就把该功能独立封装成一段独立的小程序,当下次需要执行加法运算的时候,就可以直接调用这个段小程序即可,那么这种封装形形式的具体表现形式则称作函数. ...

  8. [bzoj3287] Mato的刷屏计划

    第一眼以为是傻逼斜率优化>_< f[i]表示按i次最多可输出字符数..f[i]=max{ f[i-1]+1,(i-j-1)*f[j] },j<i-2 结果n在100+的时候就喜闻乐见 ...

  9. c语言基础学习07_关于指针的复习

    ============================================================================= 指针变量之间赋值是需要兼容的. 例如:int ...

  10. Oracle_rowid_rownum分页

      Oracle_rowid_rownum_分页 --rowid select * from account where rowid='AAASR6AAEAAAAJWAAA';       selec ...