lvs三种模式工作原理
LVS:Linux Virtual Server,即Linux虚拟服务器,是一个虚拟的服务器集群系统。
NAT模式
NAT(Networl Address Transtation)网络地址转换,内网主机可以通过路由NAT实现访问外网主机
- client请求资源,当报文达到director时,源和目标IP是CIP-VIP,IPVS会强行修改目标地址为RIP,将报文从INPUT发向POSTROUTING,源和目标IP修改为CIP-RIP,RS验证目标地址是本地地址,则接受报文并处理请求
- RS响应请求,由于报文源IP是CIP,所以相应报文的目标IP是CIP;将响应报文发送给网关director后,director会通过SNAT将源IP修改为VIP,这样client才可以明确是相应它请求报文的数据包
特点
- director与RS必须在同一个局域网内
- RS的网关必须指向director的私网DIP
- 请求和响应报文都需要director转发,会成为整个系统的瓶颈
- 支持端口映射,client访问80端口,director可以映射到RS的8080端口上
- director必须是Linux系统
- director需要两个网卡,一个与互联网通信的公网VIP,一个与RS通信的私网DIP
TUN模式
IP隧道技术又称IP封装,在源和目标IP地址的基础上, 利用新的源和目标IP地址对数据报文进行第二次封装
- client请求资源,源和目标IP为CIP-VIP的报文达到director,IPVS会利用隧道技术将DIP-RIP封装在请求报文中,经POSTROUTING链发送至RS,RS本地需要配置tunl0地址为VIP,当RS接收到报文,二次封装的目标地址为本地eth0地址,原始目标地址VIP为本地tunl0地址,所以RS就会认定是发送给自己的数据包,就会处理请求
- RS响应请求,由于请求报文源和目标IP是CIP-VIP,所以相应报文的源和目标地址应为VIP-CIP;此时报文会经由RS的网关路由一直送达client
特点
- VIP、DIP、RIP都是公网IP
- RS网关不会也不能指向DIP
- 请求报文经过director,响应报文直接由RS发送给client,director不再成为系统瓶颈
- RS必须支持隧道技术
- 不支持端口映射
DR(direct route)模式
- client请求资源,请求报文经过路由到达交换机,然后交换机查看目标IP为VIP,则修改源和目标MAC后再封装报文发送给director,IPVS则将报文源MAC修改为DIP的MAC地址,目标MAC修改为RIP的MAC地址,然后经POSTROUTING链发送出去,通过交换机转送给RS。DR模式会在lo接口上配置一个虚拟地址VIP,当RS收到报文拆封发现目标MAC地址是自己,目标IP地址也是自己的lo地址VIP,就会处理请求
- RS相应请求,由于请求报文的目标IP是VIP,所以响应报文就通过lo接口传送到eth0网卡发出
特点
- 保证前端路由将目标地址为VIP的报文全部发送给DS,而不是RS
- RS的RIP可以使用私有地址,但也可以使用公网地址
- RS和director必须在同一物理网络中
- 请求报文有director调度,但响应报文不一定经由director
- 不支持端口映射
- RS的网关不能指向DIP
调度算法
rr,轮询算法(round robin),调度器会将所有的请求平均分配给每个服务器
wrr,加权轮询(weight round robin),给每个RS分配权重比例
lc,最小连接(least connections),把新请求分配到当前连接数最小的服务器上,集群系统的真是服务器具有相近的系统性能,采用最小连接调度算法可以比较好地负载均衡
wlc,加权最小连接(weight least connections),在lc算法上为每台服务器分配权重比例
内核参数
Linux内核参数之arp_ignore和arp_announce arp_ignore参数的作用是控制系统在收到外部的arp请求时,是否要返回arp响应。 arp_ignore参数常用的取值主要有0,1,2,3~8较少用到: 0:响应任意网卡上接收到的对本机IP地址的arp请求(包括环回网卡上的地址),而不管该目的IP是否在接收网卡上。 1:只响应目的IP地址为接收网卡上的本地地址的arp请求。 2:只响应目的IP地址为接收网卡上的本地地址的arp请求,并且arp请求的源IP必须和接收网卡同网段。 3:如果ARP请求数据包所请求的IP地址对应的本地地址其作用域(scope)为主机(host),则不回应ARP响应数据包,如果作用域为全局(global)或链路(link),则回应ARP响应数据包。 4~7:保留未使用 8:不回应所有的arp请求 sysctl.conf中包含all和eth/lo(具体网卡)的arp_ignore参数,取其中较大的值生效。
arp_announce的作用是控制系统在对外发送arp请求时,如何选择arp请求数据包的源IP地址。(比如系统准备通过网卡发送一个数据包a,这时数据包a的源IP和目的IP一般都是知道的,而根据目的IP查询路由表,发送网卡也是确定的,故源MAC地址也是知道的,这时就差确定目的MAC地址了。而想要获取目的IP对应的目的MAC地址,就需要发送arp请求。arp请求的目的IP自然就是想要获取其MAC地址的IP,而arp请求的源IP是什么呢? 可能第一反应会以为肯定是数据包a的源IP地址,但是这个也不是一定的,arp请求的源IP是可以选择的,控制这个地址如何选择就是arp_announce的作用) arp_announce参数常用的取值有0,1,2。 0:允许使用任意网卡上的IP地址作为arp请求的源IP,通常就是使用数据包a的源IP。 1:尽量避免使用不属于该发送网卡子网的本地地址作为发送arp请求的源IP地址。 2:忽略IP数据包的源IP地址,选择该发送网卡上最合适的本地地址作为arp请求的源IP地址。 sysctl.conf中包含all和eth/lo(具体网卡)的arp_ignore参数,取其中较大的值生效。 arp_ignore和arp_announce参数在DR模式下的作用
- arp_ignore
因为DR模式下,每个真实服务器节点都要在环回网卡上绑定虚拟服务IP。这时候,如果客户端对于虚拟服务IP的arp请求广播到了各个真实服务器节点,如果arp_ignore参数配置为0,则各个真实服务器节点都会响应该arp请求,此时客户端就无法正确获取LVS节点上正确的虚拟服务IP所在网卡的MAC地址。假如某个真实服务器节点A的网卡eth1响应了该arp请求,客户端把A节点的eth1网卡的MAC地址误认为是LVS节点的虚拟服务IP所在网卡的MAC,从而将业务请求消息直接发到了A节点的eth1网卡。这时候虽然因为A节点在环回网卡上也绑定了虚拟服务IP,所以A节点也能正常处理请求,业务暂时不会受到影响。但时此时由于客户端请求没有发到LVS的虚拟服务IP上,所以LVS的负载均衡能力没有生效。造成的后果就是,A节点一直在单节点运行,业务量过大时可能会出现性能瓶颈。
所以DR模式下要求arp_ignore参数要求配置为1。
- arp_announce
每个机器或者交换机中都有一张arp表,该表用于存储对端通信节点IP地址和MAC地址的对应关系。当收到一个未知IP地址的arp请求,就会再本机的arp表中新增对端的IP和MAC记录;当收到一个已知IP地址(arp表中已有记录的地址)的arp请求,则会根据arp请求中的源MAC刷新自己的arp表。 如果arp_announce参数配置为0,则网卡在发送arp请求时,可能选择的源IP地址并不是该网卡自身的IP地址,这时候收到该arp请求的其他节点或者交换机上的arp表中记录的该网卡IP和MAC的对应关系就不正确,可能会引发一些未知的网络问题,存在安全隐患。 所以DR模式下要求arp_announce参数要求配置为2。 四、arp_ignore和arp_announce参数的配置方法 arp_ignore和arp_announce参数分别有all,default,lo,eth1,eth2…等对应不同网卡的具体参数。当all和具体网卡的参数值不一致时,取较大值生效。
一般只需修改all和某个具体网卡的参数即可(取决于你需要修改哪个网卡)。
NAT模式实现http负载均衡
环境说明
DR | DIP:192.168.100.150 | VIP:192.168.100.250 |
---|
RS1 | IP:192.168.100.110 | 网关为DR网关 | RS2 | IP:192.168.100.120 | 网关为DR网关 |
根据服务器的角色修改主机名
[root@localhost ~]# hostname DR
[root@localhost ~]# bash
[root@DR ~]#
[root@localhost ~]# hostname RS1
[root@localhost ~]# bash
[root@RS1 ~]#
[root@localhost ~]# hostname RS2
[root@localhost ~]# bash
[root@RS2 ~]#
关闭防火墙和selinux
[root@DR ~]# systemctl disable --now firewalld.service
[root@DR ~]# setenforce 0
[root@RS1 ~]# systemctl disable --now firewalld.service
[root@RS1 ~]# setenforce 0
[root@RS2 ~]# systemctl disable --now firewalld.service
[root@RS2 ~]# setenforce 0
DR配置VIP
[root@DR ~]# ip addr add 192.168.100.250/24 dev ens33 //临时IP
[root@DR ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:22:f9:9c brd ff:ff:ff:ff:ff:ff
inet 192.168.100.150/24 brd 192.168.100.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.100.250/24 scope global secondary ens33
valid_lft forever preferred_lft forever
[root@DR ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
BOOTPROTO=static
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.100.150
NETMASK=255.255.255.0
GATEWAY=192.168.100.2 //网关
DNS1=114.114.114.114
在RS1和RS2上面下载httpd
[root@RS1 ~]# yum -y install httpd
[root@RS1 ~]# echo "hello 192.168.100.110" > /usr/share/httpd/noindex/index.html
[root@RS1 ~]# systemctl restart httpd
[root@RS2 ~]# yum -y install httpd
[root@RS2 ~]# echo "hello 192.168.100.120" > /usr/share/httpd/noindex/index.html
[root@RS2 ~]# systemctl restart httpd
配置 RS1网关为DR网关
[root@RS1 ~]# sed -ri 's/^(GATEWAY=).*/\192.168.100.2/' /etc/sysconfig/network-scripts/ifcfg-ens33
[root@RS1 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
BOOTPROTO=static
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.100.110
NETMASK=255.255.255.0
GATEWAY=92.168.100.2
DNS1=114.114.114.114
配置 RS2网关为DR网关
[root@RS2 ~]# sed -ri 's/^(GATEWAY=).*/\192.168.100.2/' /etc/sysconfig/network-scripts/ifcfg-ens33
[root@RS2 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
BOOTPROTO=static
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.100.120
NETMASK=255.255.255.0
GATEWAY=92.168.100.2
DNS1=114.114.114.114
DR上配置转发规则
[root@DR ~]# yum -y install ipvsadm
//开启转发功能
[root@DR ~]# vim /etc/sysctl.conf
[root@DR ~]# sysctl -p
net.ipv4.ip_forward = 1
//配置转发规则
[root@DR ~]# ipvsadm -At 192.168.100.250:80 -s rr
[root@DR ~]# 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.100.250:80 rr
[root@DR ~]# ipvsadm -at 192.168.100.250:80 -r 192.168.100.110:80 -m
[root@DR ~]# ipvsadm -at 192.168.100.250:80 -r 192.168.100.120:80 -m
[root@DR ~]# ipvsadm -Sn > /etc/sysconfig/ipvsadm
[root@DR ~]# cat /etc/sysconfig/ipvsadm
-A -t 192.168.100.250:80 -s rr
-a -t 192.168.100.250:80 -r 192.168.100.110:80 -m -w 1
-a -t 192.168.100.250:80 -r 192.168.100.120:80 -m -w 1
测试
[root@DR ~]# curl 192.168.100.250
hello 192.168.100.120
[root@DR ~]# curl 192.168.100.250
hello 192.168.100.110
DR模式实现http负载均衡
DR | DIP:192.168.100.150 | VIP:192.168.100.250 |
---|
RS1 | IP:192.168.100.110 | VIP:192.168.100.250 | RS2 | IP:192.168.100.120 | VIP:192.168.100.250 |
根据服务器的角色修改主机名
[root@localhost ~]# hostname DR
[root@localhost ~]# bash
[root@DR ~]#
[root@localhost ~]# hostname RS1
[root@localhost ~]# bash
[root@RS1 ~]#
[root@localhost ~]# hostname RS2
[root@localhost ~]# bash
[root@RS2 ~]#
关闭防火墙和selinux
[root@DR ~]# systemctl disable --now firewalld.service
[root@DR ~]# setenforce 0
[root@RS1 ~]# systemctl disable --now firewalld.service
[root@RS1 ~]# setenforce 0
[root@RS2 ~]# systemctl disable --now firewalld.service
[root@RS2 ~]# setenforce 0
在RS1和RS2上下载http
[root@RS1 ~]# yum -y install httpd
[root@RS1 ~]# echo "hello 192.168.100.110" > /usr/share/httpd/noindex/index.html
[root@RS1 ~]# systemctl restart httpd
[root@RS2 ~]# yum -y install httpd
[root@RS2 ~]# echo "hello 192.168.100.120" > /usr/share/httpd/noindex/index.html
[root@RS2 ~]# systemctl restart httpd
DR配置VIP
[root@DR ~]# ip addr add 192.168.100.250/24 dev ens33 //添加临时IP
[root@DR ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:22:f9:9c brd ff:ff:ff:ff:ff:ff
inet 192.168.100.150/24 brd 192.168.100.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.100.250/24 scope global secondary ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe22:f99c/64 scope link
valid_lft forever preferred_lft forever
RS1和RS2配置内核参数
[root@RS1 ~]# vim /etc/sysctl.conf
[root@RS1 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS2 ~]# vim /etc/sysctl.conf
[root@RS2 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
RS上配置VIP
一定要先设置好内核参数在配置VIP,如果先配置VIP,VIP配置好后会立即通告给所有人,而修改内核参数就是为了不通告
[root@RS1 ~]# ip addr add 192.168.100.250/24 dev ens33 //添加临时IP
[root@RS1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f2:c3:12 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.110/24 brd 192.168.100.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.100.250/24 scope global secondary ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fef2:c312/64 scope link
valid_lft forever preferred_lft forever
[root@RS2 ~]# ip addr add 192.168.100.250/24 dev ens33 //添加临时IP
[root@RS2 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:e4:bd:ac brd ff:ff:ff:ff:ff:ff
inet 192.168.100.120/24 brd 192.168.100.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.100.250/24 scope global secondary ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fee4:bdac/64 scope link
valid_lft forever preferred_lft forever
DR上配置转发规则
[root@DR ~]# yum -y install ipvsadm
[root@DR ~]# ipvsadm -At 192.168.100.250:80 -s rr
[root@DR ~]# ipvsadm -at 192.168.100.250:80 -r 192.168.100.110:80 -g
[root@DR ~]# ipvsadm -at 192.168.100.250:80 -r 192.168.100.120:80 -g
[root@DR ~]# ipvsadm -Sn
-A -t 192.168.100.250:80 -s rr
-a -t 192.168.100.250:80 -r 192.168.100.110:80 -g -w 1
-a -t 192.168.100.250:80 -r 192.168.100.120:80 -g -w 1
[root@DR ~]# ipvsadm -Sn > /etc/sysconfig/ipvsadm
测试
[root@DR ~]# curl 192.168.100.250
hello 192.168.100.120
[root@DR ~]# curl 192.168.100.250
hello 192.168.100.110
|