前言
本文以DR模式来进行实验!
首先这次研究这个LVS的前景,是因为公司要给客户的Master服务器做一个虚拟IP来提供访问,是在一个局域网下。想通过虚拟IP访问正式的环境,通过Master本身的IP访问测试服务器。(一度认为这样有点浪费LVS的强大 哈哈哈哈)当然我怎么又会只为了实现这一点就完事了呢,我也亲自尝试一下LVS的高可用和负载。继续往下看。
我们先一点点代入LVS
一、Nginx 和 LVS的区别
Nginx我们都很常遇见,通过其反向代理或者基于反向代理来做负载均衡,当我们实现反向代理的时候
后端的服务器可以一个是购物车一个是订单,不同的url不同的映射 然后基于反向代理来做负载 把其中一个购物车做成十个还是一百个。 因为Nginx是七层的负载均衡技术,要想知道是谁的发的请求 就一定要和客户端进行握手。 LVS是四层的负载均衡技术。我们看一下这个网络层次图。
这样相比出来 我们会发现LVS是没有握手的一个过程,换句话他并不是一个完整的四层负载,而是基于网络层和链路层的数据包传输。是数据包级别的负载。所以Nginx能做的事情,LVS是做不了的。 Nginx因为要与客户端握手他能承受的并发是远远要小于LVS的。在企业中 一般都是 先由LVS hou住流量 由Nginx hou住握手 再转到后台服务器。
而且使用LVS做负载 其后端服务必须是镜像的
二、路由器
我们要先补一个知识, NAT (Network Address Translation 网络地址转换)
假设在家里有两台机器 第一台是192.168.1.8 然后还有一台是192.168.1.6 我和我女朋友一人一台。
然后家里有一台路由器,路由器里面也包含了交换机 。 路由器有两个网口连接两台设备 ,路由器也有一个IP地址192.168.1.1。为什么要买路由器呢? 路由器会有一个私有地址和公网地址,当你交了钱运营商会给你分配一个公网地址(6.6.6.6)可访问外网。 并且私有地址不会出现在互联网上 解决了地址不够用的情况。
接下来 我们来模拟一个场景。当你访问百度的时候 数据包会通过默认网关走到路由器 路由器会把你的私有地址替换成公网地址 然后用公网地址去访问百度,百度处理完之后要发回来。是不是只要把6.6.6.6:12121 换成你的电脑IP就可以了 数据就可以传回你的电脑。
因为修改的是源地址(source),起名叫S-NAT (源地址替换协议)
那如果我女朋友 也用12121的端口来访问百度 这个时候我们会发现如果还像上面那面替换IP 就行不通了。当百度的数据包返回到路由器时,不知道该把数据包给哪台机器了。
这个时候路由器会准备一个表,通过mac 映射解决这个问题。 当我访问百度的时候,这个表会记录一下 123 是来自与192.168.1.8:12121 ,当我女朋友访问的时候 表会记录一下321 是来自于192.168.1.6:12121。并且去访问百度的时候会把12121 替换成 路由器自己记录的数 123。 是不是各自的通信就通了。
三、LVS三种模式
1.语义
首先我们先规定一些名词和词汇方便理解:
1.客户端肯定会有他们的IP地址 ——> CIP
2.虚拟IP 服务器单独拉出来的一个虚拟网卡,作为用户请求的目标的 IP 地址 ——> VIP
3.VIP是单点的,要和后台的server连接会有一个分发IP ——> DIP
4.后台的server,真实服务器 ——> RIP
2.NAT模式 地址转换
接下来通过上面的路由器 来看一下LVS中的NAT模式
如下图, 当客户端想访问我们的VIP,通过VIP做负载来访问server,这时候我们会发现 客户端发来的数据包 会直接被丢弃。VIP并没有找到后台的 sever。 那么中间这台负载均衡服务器要做一件什么事情才能让后台server收到客户端发来的数据包呢?
是不是要将 VIP替换成RIP 就可以找到后台的server了。这个转换叫 D-NAT(目标地址转换)
这样通过netstat -natp
就可以看到连接的对应关系。 这个时候百度的数据包返回的时候,客户端会收来自RIP 的数据包么? 当然是不会了。因为曾经CIP是给VIP 他不知道世界上还有一个RIP 就会丢弃数据包。 这个时候就需要负载均衡服务器恢复VIP给CIP的返回。 这样地址就可以对应上了。跟路由器很像。
但是我们会发现这个模式有弊端。
非对称:
其实在互联网当中客户端发的请求头是特别小的,但是服务端给客户端返回的量会很大。
带宽成为瓶颈:
来的数据包和回的数据包 都会经过负载均衡服务器。
地址转换:
消耗计算机算力
3. DR模式 直接路由模型
首先要先明白 无论D-NAT有多少缺点 他都有一个优点就是可以实现负载均衡,对于中小流量访问,这个模式可以满足。但是对于大流量,如何来解决这个弊端呢?
如果能让返回的数据包不再经过负载均衡服务器 而是让他直接返回就好了。
如下图,我们会发现如果要想RIP直接给CIP返回数据包。在RIP下 netstat -natp
就应该看到VIP和CIP的映射关系。 计算机如果要产生这样的映射关系 那么在RIP的服务器就要有一个IP地址叫VIP。
VIP在多台机器都会出现,但是在互联网上这种情况就会发生冲撞,就需要处理一下,RS中的VIP只有自己知道 别人是不知道的,负载均衡服务器的IP暴露出去,RS中的VIP隐藏起来(隐藏VIP,对外隐藏 对内可见 隐藏原理下面会介绍
)。这样的话 netstat -natp
的映射关系就通了。
但是我们会发现 当CIP访问VIP,如果不转换RIP ,VIP是不能把数据包扔给RIP的。 这里要注意一下 在通信当中除了网络层下面还有二层链路层(MAC地址)。如果在这个数据包的基础之上我们再套一层链路层,链路层我们放的是RIP的MAC地址。(注意:这里动的是链路层,而不是网络层。
) 然后这个时候负载均衡服务器通过MAC地址找到了RIP(下一跳),在RIP中也存有隐藏的VIP ,有了对应的映射关系。 处理完数据包返回到CIP。
当然这个模式也是有弊端的。
只可运用在同一局域网:
上面我们提到了DR模式之所有要比NAT模式要快 是因为基于2层链路层MAC地址实现的,MAC地址是点到点 没有办法跨网络 。
4.TUN模式 隧道模式
上面两种模式要么速度慢,要么没有办法跨网络。
那么有没有一种模式 速度没有那么满,也可以进行跨网络呢 ?
答案就是TUN隧道模式,什么叫做隧道模式呢 ,很好理解 如下图 其实就是IP的数据包 背着IP的数据包。我们生活中的VPN和翻墙是和隧道挂钩的,比如说在我国,在大陆上网可能会受到防火墙的约束,一些国外的网站无法访问的 。但是在我国香港 上网是没有约束的可以访问谷歌之类的。我们就可以在香港买一个云主机,在云主机中搭建一个VPN的server端,在国内的电脑装了客户端 这样国内的主机到香港的主机就会出现一个隧道,当他想访问谷歌的时候 数据包都会扔给香港 通过香港往国外转。 这样就可以解决一个物理位置限制的问题。
四、LVS的DR模型试验搭建
1.环境
我这里的实验环境是 在win10安装了VMware 搭建了4台服务器
软件版本: CentOS7.9 、 ipvsadm1.27 、 keepalived1.3.5
node01 192.168.241.129 搭建LVS + keepalived(Master)
node02 192.168.241.130 后台真实服务器(RS1)
node03 192.168.241.131 后台真实服务器(RS2)
node04 192.168.241.132 搭建LVS + keepalived(BACKUP)
VIP : 192.168.241.200
网络环境:
网络架构图:
隐藏VIP方法:对外隐藏,对内可见
一、修改内核
/proc/sys/net/ipv4/conf/*IF*/
arp_ignore: 定义接收到ARP请求时的响应级别;
0:只要本地配置的有相应地址,就给予响应;
1:仅在请求的目标(MAC)地址配置请求 到达的接口上的时候,才给予响应;
arp_announce:定义将自己地址向外通告时的通告级别;
0:将本地任何接口上的任何地址向外通告;
1:试图仅向目标网络通告与其网络匹配的地址;
2:仅向与本地接口上地址匹配的网络进行通告;
二、设置隐藏的vip
ifconfig lo:3 192.168.241.200 netmask 255.255.255.255
补充 :/proc/sys/net/ipv4/conf/
我们注意一下这个目录,这是一个虚拟目录并不是磁盘上的 只有开机才会出现,里面是内核和所有进程把里面的变量抽象成文件 改了这里面的值 就相当于改了内核里面的变量参数的值。在修改word的时候 会有一个隐藏的临时文件 那么/proc/sys/net/ipv4/conf/这个路径代表的是内核的地址空间 用vi去编辑这个文件 并有一个临时文件 这约等于在地址空间产生一个变量 这样是会被约束的 所以这个目录下只能通过 echo来进行覆盖。
2. 部署
node1 ~ node04:
yum install net-tools // 安装ifconfig
查看自己的网卡信息:
node01:
// 添加虚拟VIP网卡信息
ifconfig ens33:8 192.168.241.200/24
// 24 相当于255.255.255.0 不同版本服务器网卡名字可能不同 我这里是ens33
node02~node03:
// 修改内核
echo 1 > /proc/sys/net/ipv4/conf/ens33/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/ens33/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
// 设置隐藏的vip
ifconfig lo:3 192.168.241.200 netmask 255.255.255.255
//(这里不可以用255.255.255.0 ,掩码和ip进行与运算的时候会造成死循环,数据包发送不出去。)
配置访问RS后台服务器 node2 ~ node03:
yum install httpd -y // 安装httpd用来模拟后台
systemctl start httpd.service // 启动httpd
systemctl status httpd.service // 查询运行状态
vi /var/www/html/index.html // 设置访问界面
systemctl status firewalld //查看防火墙状态
firewall-cmd --list-ports //查询外部可访问端口
firewall-cmd --zone=public --add-port=80/tcp --permanent // 置防火墙开启可访问80端口,或者直接关闭防火墙
sed -i 's/=enforcing/=disabled/g' /etc/sysconfig/selinux //设置宽容模式 不然主备都会有VIP
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --protocol vrrp -j ACCEPT //开放VRRP
firewall-cmd --reload // 重启防火墙
外部主机浏览器直接访问node02、03 from 192.168.241.1x
LVS服务配置 node01:
yum install ipvsadm
ipvsadm -A -t 192.168.241.200:80 -s rr //-A 进包规则 -t tcp协议 -s rr 轮询调度(这里的80端口也需要开通)
ipvsadm -a -t 192.168.241.200:80 -r 192.168.241.130 -g -w 1 // -a 负载 -r 服务地址 -g 轮询 -w 权重
ipvsadm -a -t 192.168.241.200:80 -r 192.168.241.131 -g -w 1
查看配置: ipvsadm -ln
清空以上配置:
ipvsadm -C // 如果配置错了 可以清空 重新配置
验证:
// 浏览器访问 192.168.241.200 看到负载 疯狂F5
node01:
netstat -natp // 结论看不到socket连接(证明是没有握手的 基于四层)
node02~node03:
netstat -natp // 结论看到很多的socket连接
node01:
ipvsadm -lnc // 查看记录
TCP 00:57 FIN_WAIT 192.168.241.1:51587 192.168.241.200:80 192.168.241.130:80
FIN_WAIT: 连接过,偷窥了所有的包
SYN_RECV: 基本上lvs都记录了,证明lvs没事,一定是后边网络层出问题
至此 DR模式实验 已经结束了 也看到负载的效果
五、通过Keepalived部署LVS
1.问题
上面通过lvs实现了负载 随之会带来两个问题:
问题1:lvs会挂,业务下线,单点故障
问题2:RS会挂,一部分用户会情求异常,lvs还存有这个RS的负载记录
问题3:需要人为手动部署,如果关机了 那么就需要重新部署
解决问题1:单点故障 一个有问题,那么我们就用一堆 一变多!
解决问题2:RS挂了怎么确定? 访问一下 验证的应用层的http协议 判断返回200 OK
解决问题3:通过程序把人替换掉 这个程序就是keepalived
keepalived作用:
1.监控自己服务
2.master通告自己还活着,backup监听master状态,master挂了,一堆backup推举出一个新的master。
3.配置:vip,添加ipvs, keepalived是有自己的配置文件的
4.对后端server做健康检查
2.部署
node1
// 清空DR实验的负载和网卡 不需要手动配置 而是有keepalived 自动配置。
ipvsadm -C // 清空负载
ifconfig ens33:8 down // 删除VIP虚拟网卡
node1 、 node04
// 安装keepalived 和 ipvsadm
yum install keepalived ipvsadm -y
// 找到keepalived.conf配置文件 保存一个备份
cd /etc/keepalived/
cp keepalived.conf keepalived.conf.bak
// 编辑配置文件
vi keepalived.conf
vrrp_instance VI_1 {
state MASTER # node04 改为 BACKUP
interface ens33 # 网卡
virtual_router_id 51
priority 100 # node04 权重改小为50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
# 配置虚拟VIP网卡信息
192.168.241.200/24 dev eth0 label eth0:3
}
}
# VIP
virtual_server 192.168.241.200 80 {
delay_loop 6 # 设置健康状态检查时间
lb_algo rr # 调度算法,这里用了 rr 轮询算法
lb_kind DR # 这里测试用了 DR 模式
nat_mask 255.255.255.0
persistence_timeout 0
protocol TCP
# 后端真实服务器1
real_server 192.168.241.130 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200 # 返回200证明server健康
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
# 后端真实服务器2
real_server 192.168.241.131 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
// 在node04上把node01的conf文件复制过来
scp root@192.168.241.129:/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
启动keepalived:
systemctl daemon-reload (重新加载)
systemctl enable keepalived.service (设置开机自动启动)
systemctl disable keepalived.service (取消开机自动启动)
systemctl start keepalived.service (启动)
systemctl stop keepalived.service (停止)
systemctl status keepalived.service (查看状态)
验证:我们只需要先启动node01中的keepalived,这个时候我们查询网卡会发现多了一个我们在配置文件中添加的网卡信息,我们再启动node04(BACKUP)会发现04的没有配置的网卡信息,只要我们停了01,04才会出现网卡信息。当01重启后,04网卡信息又会消失。整个操作对用户来说是透明的。
总结
以上通过LVS和keepalived 实现了双机热备 ,当Master挂到之后,Backup会接替Master的工作,Master修复后又继续工作。Backup又恢复到待机的状态。