LVS的DR模型配置
LVS的DR模型配置
介绍
下图为DR模型的通信过程,图中的IP不要被扑结构中的IP迷惑,图里只是为了说明DR的通信原理,应用到本例中的拓扑上其工作原理不变。
拓扑结构
服务器 | IP地址 | 角色 |
---|---|---|
Srv01 | 172.16.42.100 VIP: 172.16.42.111 |
LVS |
Srv03 | 172.16.42.102 VIP: 172.16.42.111 |
Nginx |
Srv04 | 172.16.42.103 VIP: 172.16.42.111 |
Nginx |
另外,我这4台主机都是2个网卡, 其中有ens33是172.16.42.0/24这个网络,ens34是192.168.100.0/24网络,这个网络在本例中没有用,请忽略。
部署LVS
安装LVS
其实LVS不需要安装当然这么说也不太严谨,而是说LVS是使用了内核的ip_vs功能它是内核支持的,它不是一个我们通常所理解的软件。目前CentOS 7安装默认就在内核中配置了ip_vs的支持。我们需要安装的是ipvsadm这个管理工具。可以通过yum -y install ipvsadm
来安装(在两台LVS都安装这个工具),安装完会有如下内容:
ipvsadm是用来配置ipvs规则的,这些规则运行在内存中,这就意味着关键就没有了,所以ipvsadm-save是用来保存规则的,而ipvsadm-restore则是用来加载规则到内存的。
ipvsadm-config这个东西ipvs规则文件,我们使用ipvsadm命令的时候可以把规则保存到这个文件中,ipvsadm.service是服务文件,虽然ipvsadm本身不是服务,但是为了实现开机可以自动加载ipvs规则,那么这个ipvsadm.service就是让开启自动执行ipvsadm-restore来加载规则到内存用的,当关机的时候自动保存规则。
ipvsadm命令简要说明
集群服务类命令:
参数 | 说明 |
---|---|
-A | 添加集群服务 -t:TCP服务 -u:UDP 服务 -f:防火墙标记,浏览电商网站的时候访问的是80也就是HTTP服务,添加购物车商品,然后去结账的时候就会用到HTTPS服务,也就是443,这明显是两个服务,这时候购物车就没东西了,因为很有可能会定向到不同的后端应用服务器上,所以为了避免这个问题,就会做标记把HTTP和HTTPS当做 同一种服务,80的标记是1,443的标记也是1,这样就可以了。也就是把不相同的服务定向到同一个服务的时候,就会用到防火墙标记。 Service-address:如果使用-t或者-u的时候,就是IP:PORT;如果使用-f的时候就是一个数字,这个标记是使用iptables打上的标记 -s:调度方法(算法),默认是WLC,该算法是LVS中最好的 |
-E | 修改集群服务,使用方法和-A相同 |
-p | 持久连接超时时长,默认360秒 |
-D | 删除集群服务 |
-C | 清空所有集群服务 |
应用服务器类:
参数 | 说明 |
---|---|
-a | 向集群服务中添加应用服务器 -t |
-g | 网关,指定LVS类型为DR模型,如果不设置则默认为DR模型 |
-i | IPIP,指定LVS类型为隧道模型,如果不设置默认为DR模型 |
-m | 指定LVS类型为NAT模型,如果不设置默认为DR模型 |
-w | 权重 |
-x | 连接上限 |
-y | 连接下限 |
-e | 修改指定的应用服务器属性 |
-d | 从指定的集群服务中删除应用服务器 |
-Z | 计数器清零 |
查看规则:
参数 | 说明 |
---|---|
-L | -n 数字格式显示IP地址 -c 显示每一个应用服务器的连接数(活动和非活动) --stats:显示统计数据, --rate:显示数据传输速率 --timeout:显示TCP/UDP会话时长,这个数字是LVS自己内部的 |
-n | 数字显示IP和端口 |
--stats参数输出说明
Conns | 连接数 |
---|---|
InPkts | 入栈的报文数量 |
OutPkts | 出栈的报文数量 |
InBytes | 入栈字节数量 |
OutByes | 出栈字节数量 |
--rate参数输出说明
CPS | 每秒连接数 |
---|---|
InPPS | 平均每秒入栈报文数 |
OutPPS | 平均每秒出栈报文数 |
InBPS | 平均每秒入栈字节数 |
OutBPS | 平均每秒出栈自己数 |
ARP的内核参数
由于LVS服务器和后端服务器的网卡上都配置了VIP,那么当客户端联系VIP的时候肯定是和LVS服务器的VIP进行通信,然后由LVS服务器基于规则进行调度,我们知道2层通信是基于MAC地址的,那么首次通信时客户端可能并不知道LVS服务器的MAC地址,那么就需要进行ARP广播来解析出VIP所在的服务器的MAC地址,那么显然对客户端进行ARP应答的只能是LVS服务器不能是后端服务器,所以我们就要在后端上修改内核参数来禁止ARP应答和宣告。那么有2个内核参数表示这两个设置:
arp_ignore:表示接收到ARP广播时的响应级别,默认值为0
-
0,默认值,表示响应所有,只要对方查询的IP配置在我自己这台主机上且无论ARP请求从哪个网卡进来,该主机都会响应
-
1,收到该ARP请求的网卡IP与ARP请求的IP一致,该主机才响应
arp_announce:定义将自己的地址向外通告的级别,默认是0
-
0,表示将本机所有的MAC地址都向外通告
-
1,多网卡主机且都配置了IP地址,那么该主机接入到网络时,无论哪个网卡接入到网络,该网卡都会向外宣告自己所有的MAC地址,所以1表示如果IP不在这个接口上,就避免向外通告,但是不保证一定不会下外通告。
-
2,仅向网卡IP直连的网络进行通告
为什么会有这些级别呢?因为主机可以有多个网卡,每个网卡都对应一个网段,默认情况下这个多网卡主机只要接入网络它就会把自己所在的所有网络地址都向外进行通告。
所以对于后端服务器,也就是本例子中的Nginx,我们应该在lo上配置子接口,且设置arp_ignore为1,arp_announce为2。
设置LVS服务器
设置IP地址,这个地址要在LVS服务器的物理网卡设置,我这里就是ens33
ifconfig ens33:0 172.16.42.111 netmask 255.255.255.255 broadcast 172.16.42.111 up
下面添加规则:
ipvsadm -A -t 172.16.42.111:80 -s rr
ipvsadm -a -t 172.16.42.111:80 -r 172.16.42.102 -g
ipvsadm -a -t 172.16.42.111:80 -r 172.16.42.103 -g
设置后端服务器
后端服务器的所有操作都是一样,我这里就演示一台。首先要保证2台后端服务器都安装了Nginx,我用Nginx只是为了后端提供一个Web服务而已,你使用Tomcat也是一样的。
通过这个命令查看当前服务器设置sysctl -a | egrep "arp_ignore|arp_announce"
可以看到这里每个网卡都有这2个参数还有一个All也有,那应该配置在哪里呢?all表示全局,理论上来说在all上配置就可以,但是为了上个双保险我们在ens33上也配置。
记住arp_announce配置为2;apr_ignore配置为1。
sysctl -w net.ipv4.conf.all.arp_announce=2
sysctl -w net.ipv4.conf.ens33.arp_announce=2
我使用sysctl -w来修改只是临时生效,重启就没有了,为了永久有效请修改
/etc/sysctl.conf
文件。
现在在说以为什么arp_announce配置为2,我这个主机有2个网卡,每个网卡所连接的是不同网段。我要使用的是ens33上面这个172.16.42.0/24这个网段,且VIP也是这个网段,当我把ens33的apr_announce配置为2 的时候,这就意味着当这个ens33接入网络时它不会对外宣告ens34的网络设置,也不会对外宣告lo的网络设置(因为我们要在lo上配置一个子接口,该接口的IP就是VIP),下面配置apr_ignore
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.ens33.arp_ignore=1
下面设置lo的子接口,这里为什么要32位呢?因为要把广播地址设置为自己,这样它的广播就不会广播到其他地方。
ifconfig lo:0 172.16.42.111 netmask 255.255.255.255 broadcast 172.16.42.111 up
下面我们在Srv01上ping一下这个地址,发现没有人应答,所以ping不通。
接下来添加一条路由,其目的是由于后端服务器是直接应答客户端请求的,所以就需要确保应答是其源IP一定是VIP(因为客户端请求的就是VIP),但是当LVS修改完数据包发送给后端服务器时,使用的是后端服务器的真实IP地址进行通信的,而网络通信是请求入栈是哪个接口,响应出栈还走哪个接口,这就势必导致后端服务器会使用自己的真实IP而不是VIP对客户端响应,这肯定是不对的,所以我们要通过这一条路由设置让ens33网卡收到数据包后转发给lo:0这个子接口,这样响应出栈的时候就会经过lo:0,这样也就会把响应报文的源IP设置为VIP了。
route add -host 172.16.42.111 dev lo:0
这条命令的含义是如果目标地址是172.16.42.111就要送到lo:0,这样就保证了入栈经过lo:0,那么出栈自然会经过。如果你不理解,那么就要好好看看最上面的图,二层通信是使用mac地址,而此时后端服务器收到这个数据包的时候,IP报文中源IP是客户端的IP,而目标IP则是VIP,只是数据链路层报文mac地址信息被LVS替换了。
之后启动后端服务的Nginx服务,两台后端服务器上都做上面的修改。
访问测试
到此LVS设置完毕。