实现LVS负载均衡转发方式有三种,分别为NAT、DR、TUN模式,LVS均衡算法包括:RR(round-robin)、LC(least_connection)、W(weight)RR、WLC模式等(RR为轮询模式,LC为最少连接模式)。
重点理解NAT方式的实现原理和数据包的改变。
用户请求LVS VIP到达director(LVS服务器:LB),director(LVS服务器)将请求的报文(因为用户的请求有一个请求报文,也就是请求包里面,请求包里面有一个目标IP地址)的目标IP地址(目标IP地址是LVS的VIP)改成后端的realserver IP地址(因为LVS不能像nginx提供静态资源解析,所以LVS要串改报文当中的目标IP,改为后端随机一台nginx的IP),同时将报文的目标端口也改成后端选定的realserver相应端口,最后将报文发送到realserver,realserver将数据返给director,director再把数据发送给用户。(两次请求都经过director,所以访问大的话,director会成为瓶颈)。
(1) 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
(2) PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(3) IPVS比对数据包请求的服务是否为集群服务,若是,修改数据包的目标IP地址为后端服务器IP,然后将数据包发至POSTROUTING链。 此时报文的源IP为CIP,目标IP为RIP
(4) POSTROUTING链通过选路,将数据包发送给Real Server
(5) Real Server比对发现目标为自己的IP,开始构建响应报文发回给Director Server。 此时报文的源IP为RIP,目标IP为CIP
(6) Director Server在响应客户端前,此时会将源IP地址修改为自己的VIP地址,然后响应给客户端。 此时报文的源IP为VIP,目标IP为CIP
LVS/NAT模型的特性
NAT(Network Address Translation 网络地址转换)是一种外网和内外地址映射的技术,内网可以是私有网址,外网可以使用NAT方法修改数据报头,让外网与内网能够互相通信。NAT模式下,网络数据报的进出都要经过LVS的处理。LVS需作为RS(真实服务器)的网关。当包到达LVS时,LVS做目标地址转换(DNAT),将目标IP改为RS的IP。RS接收到包以后,仿佛是客户端直接发给它的一样。RS处理完,返回响应时,源IP是RS IP,目标IP是客户端的IP。这时RS的包通过网(LVS)中转,LVS会做源地址转换(SNAT),将包的源地址改为VIP,这样,这个包对客户端看起来就仿佛是LVS直接返回给它的。客户端无法感知到后端RS的存在。
(1)RIP和DIP必须在同一个IP网络,且应该使用私网地址;RS的网关要指向DIP;
(2)请求报文和响应报文都必须经由Director转发;Director易于成为系统瓶颈;
(3)支持端口映射,可修改请求报文的目标PORT;
(4)vs必须是Linux系统,rs可以是任意系统;
缺点:在整个过程中,所有输入输出的流量都要经过LVS 调度服务器。显然,LVS 调度服务器的网络I/O压力将会非常大,因此很容易成为瓶颈,特别是对于请求流量很小,而响应流量很大的Web类应用来说尤为如此。
优点:NAT模式的优点在于配置及管理简单,由于了使用NAT技术,LVS 调度器及应用服务器可以在不同网段中,网络架构更灵活,应用服务器只需要进行简单的网络设定即可加入集群。
LVS NAT模式实战
环境如下,系统为Centos7.X
Server1 |
192.168.179.102 |
LVS |
Server2 |
192.168.179.103 |
Server1 Nginx |
Server3 |
192.168.179.104 |
Server2 Nginx |
LVS:192.168.179.102 :安装ipvsadm软件包通过命令ipvsadm来管理ip_vs模块
[root@localhost ~]# yum install ipvsadm -y #通过ipvsadm来管理ip_vs模块
[root@localhost ~]# lsmod | grep -i ip_vs
[root@localhost ~]# modprobe ip_vs #加载ip_vs模块,如果不加载就实现不了负载均衡了
[root@localhost ~]# lsmod | grep -i ip_vs
ip_vs 141092 0
nf_conntrack 133387 1 ip_vs
libcrc32c 12644 3 xfs,ip_vs,nf_conntrack
LVS上配置网卡:内网网卡:ens32: 192.168.179.102(和后端Nginx在一个网段) 外网网卡:ens34:172.20.2.120(提供VIP服务)
[root@localhost ~]# ip a
2: ens32: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:0e:1a:bf brd ff:ff:ff:ff:ff:ff
inet 192.168.179.102/24 brd 192.168.179.255 scope global ens32
valid_lft forever preferred_lft forever
inet6 fe80::2d42:a0b1:1cdc:74c0/64 scope link
valid_lft forever preferred_lft forever
3: ens34: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:0e:1a:c9 brd ff:ff:ff:ff:ff:ff
inet 172.20.2.120/24 brd 172.20.2.255 scope global dynamic ens34
valid_lft 6238sec preferred_lft 6238sec
inet6 fe80::1047:3c34:2b9f:50e8/64 scope link
valid_lft forever preferred_lft forever
LVS配置路由转发功能(实现负载均衡)
#ipvsadm -A 代表添加VIP -t代表TCP协议 -s指定算法 rr轮询模式
[root@localhost ~]# ipvsadm -A -t 172.20.2.120:80 -s rr
[root@localhost ~]# 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.20.2.120:80 rr
#-a表示在VIP集群当中添加后端服务器真实IP -r表示real server -m表示NAT 模式 -g表示DR模式 -w表示权重(在虚拟集群172.20.2.120:80中,加入后端Realserver服务器192.168.179.103:80)
[root@localhost ~]# ipvsadm -a -t 172.20.2.120:80 -r 192.168.179.103:80 -m -w 100
[root@localhost ~]# 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.20.2.120:80 rr
-> 192.168.179.103:80 Masq 100 0 0
-a,往虚拟服务器集群中添加真实服务器;
-t,TCP协议;
-r,指定后端realserver服务器的IP和端口;
-m,指定NAT转发模式;
-w,weight权重设置;
#该文件内容为0,表示禁止数据包转发,1表示允许,将其修改为1。(LVS NAT模式能够实现数据转发,还要依靠Linux内核开启转发功能,所以需要如下设置)
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
0
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
1
#修改网关地址即下一跳地址为LVS内网网卡的地址(192.168.179.103 Realserver服务器的网关设置为LVS服务器的内网网卡IP地址192.168.179.102)
[root@real-server1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens32
GATEWAY=192.168.179.102
[root@real-server1 ~]# systemctl restart network
[root@real-server1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.179.102 0.0.0.0 UG 100 0 0 ens32
#查看LVS NAT模式集群配置信息,下所示:
[root@localhost ~]# 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.20.2.120:80 rr
-> 192.168.179.103:80 Masq 100 0 2
Forward: 转发方式,当前是路由转发
Weight: 权重
ActiveConn: 当前活跃的连接数
InActConn: 当前不活跃的连接数
如果需要中途加入一台Nginx,比如192.168.179.104这台Nginx,操作如下,和上面方法一样
#LVS 192.168.179.102上
[root@localhost ~]# ipvsadm -a -t 172.20.2.120:80 -r 192.168.179.104:80 -m -w 100
[root@localhost ~]# 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.20.2.120:80 rr
-> 192.168.179.103:80 Masq 100 0 0
-> 192.168.179.104:80 Masq 100 0 0
#Nginx 192.168.179.104
[root@real-server2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens32
GATEWAY=192.168.179.102
[root@real-server2 ~]# systemctl restart network
[root@real-server2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.179.102 0.0.0.0 UG 100 0 0 ens32
192.168.179.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32
未结合Keepalived实现对后端节点进行健康检查
[root@real-server1 ~]# pkill nginx
#如果你将后端一台Nginx下线了,LVS并不会对后端的real server做健康检查,可以看到需要配合keepalived来使用
[root@localhost ~]# tail -f /var/log/messages
#列表当中的192.168.179.104节点并未踢出后端的real server集群
[root@localhost ~]# 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.20.2.120:80 rr
-> 192.168.179.103:80 Masq 100 0 3
-> 192.168.179.104:80 Masq 100 1 29
[root@localhost ~]# 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.20.2.120:80 rr
-> 192.168.179.103:80 Masq 100 0 1
-> 192.168.179.104:80 Masq 100 0 1