LVS(Linux Virtual Server)也就是Linux 虚拟服务器
Nginx负载均衡和LVS负载均衡主要区别:
工作层次:
- Nginx 负载均衡:Nginx 是一个反向代理服务器,主要工作在 OSI 模型的第 4 层(传输层)和第 7 层(应用层)。它可以理解 HTTP、HTTPS 和其他应用层协议,因此可以根据具体的请求内容(根据location匹配内容)进行负载分发。
- LVS负载均衡:LVS 主要工作在 OSI 模型的第 4 层(传输层)。它主要关注 IP 和传输层协议(如 TCP、UDP),而不关心应用层协议。这使得 LVS 可以基于IP端口进行负载分发。
配置和管理:
- Nginx 负载均衡:Nginx 使用灵活的配置文件来管理负载均衡设置。这使得管理员可以轻松地添加、删除和修改后端服务器,以及设置复杂的负载均衡策略。此外,Nginx 提供了丰富的模块,可以进行访问控制、缓存、限速,动静分离等多种功能。
- LVS 负载均衡:LVS 配置相对复杂,需要对 IP 虚拟化和内核网络栈有一定了解。通过使用 LVS 的管理工具(如
ipvsadm
或keepalived
),管理员可以配置和监控负载均衡设置。
性能:
- Nginx 负载均衡:作为反向代理服务器,Nginx 会将请求转发给后端服务器,然后将响应返回给客户端。这会导致一定程度的性能损失,尤其是在处理大量小文件或高并发请求时。但是,Nginx 的高性能和优化设计,使得这种性能损失相对较小。
- LVS 负载均衡:由于 LVS 只关注 IP 层和传输层,它可以实现高性能的数据包转发。LVS 使用内核级别的负载均衡,性能损失相对较小,适用于处理高并发、高吞吐量的网络服务。
LVS组成
LVS 由两部分程序组成,包括 ipvs 和 ipvsadm。
- ipvs(ip virtual server):LVS 是基于内核态的netfilter框架实现的 IPVS 功能, 工作在内核态。用户配置 VIP 等相关信息并传递到 IPVS 就需要用到 ipvsadm 工具。
- ipvsadm:ipvsadm 是LVS用户态的配套工具,可以实现VIP和RS的增删改查功能,是基于 netlink 或raw socket方式与内核 LVS 进行通信的,如果LVS类比于netfilter,那 ipvsadm 就是类似iptables工具的地位。
- 一个在用户空间,一个在系统内核
LVS工作模式
短语:
- CIP:Client IP,表示的是客户端 IP 地址。
- VIP:Virtual IP,表示负载均衡对外提供访问的 IP 地址
- RIP:RealServer IP,表示负载均衡后端的真实服务器 IP 地址。
- DIP:Director IP,表示负载均衡与后端服务器通信的 IP 地址。
- CMAC:客户端的 MAC 地址,准确的应该是 LVS 连接的路由器的 MAC 地址。
- VMAC:负载均衡 LVS 的 VIP 对应的 MAC 地址。
- DMAC:负载均衡 LVS 的 DIP 对应的 MAC 地址。
- RMAC:后端真实服务器的 RIP 地址对应的 MAC 地址
开源 LVS 版本有 3 种工作模式,DR 模式 NAT 模式 Tunnel 模式
DR 模式
如图,PREROUTING链判断目的IP是VIP,确定VIP是本地IP,然后将其送往INPUT链。ipvs将数据包通过DIP的网卡发送给POSTROUTING链,其中源MAC自动修改为 DIP的MAC(因为从DIP的网卡发送出去的),并且将目的MAC修改为RIP的MAC, 源IP和目的IP保持不变 。因为有RMAC,所以交换机能把报文送到RS上。而RS配置的本地lo网卡配置了VIP这个地址,所以RS会接受处理这个报文。但是RS经过配置不响应ARP请求,所以不会响应对VIP的ARP请求。
NAT 模式
INPUT链上的ipvs将数据包的目的IP修改为RIP,然后发送给POSTROUTING链。 POSTROUTING链将数据包发送至后端服务器处理。因为RS(外网卡关闭)的默认网关指向LVS,所以RS只能通过LVS(这个环节功能为RS的路由器)上网,LVS的FORWARD链上的ipvs将RIP(无效的内网地址)转换为VIP(有效的公网地址),这样才能响应客户端请求。
Tunnel 模式
INPUT链上的ipvs将包含VIP的数据然后 IP 头部前边额外增加了一个 IP 头(以DIP为源ip,RIP为目的ip)。该数据包根据DIP.RIP通过网络到达RS。RS收到后ipip模块将Tunnel头部卸载,最后响应客户端。
Tunnel网卡是一种虚拟网卡,主要用于在不同网络之间建立隧道连接,将数据包封装在隧道中进行传输。听起来像VPN,估计和VPN关系不小,应该是vpn和tunnel网卡关系不小。
LVS DR模式rr算法搭建
环境准备(前两个IP在同一台机器上):
ip | 角色 | 作用 |
---|---|---|
192.168.126.19 | VIP | LVS调度器对外服务IP(虚拟IP) |
192.168.126.16 | DIP | LVS调度器服务IP(真实IP) |
192.168.126.17 | RIP | 后端响应服务器1 |
192.168.126.18 | RIP | 后端响应服务器2 |
关闭三台firewalld及selinux,同步时钟源
LVS服务器配置
安装ipvsadm
yum install ipvsadm -y
在LVS调度器上配置VIP
这里采用虚拟网卡,当然也可以使用独立网卡配置
ip addr add 192.168.126.19/32 dev ens33
# 临时生效,下次开机重启丢失
nmcli con mod ens33 +ipv4.addr 192.168.126.19/32
systemctl restart network
#永久生效,下次开机还在,需要重启网络服务
成功后
使用ipvsadm添加ipvs规则
[root@localhost ~]# ipvsadm -A -t 192.168.126.19:80 -s rr
-A:表示添加一个新的虚拟服务器
-t:表示该虚拟服务器监听的IP地址和端口号
-s rr:表示虚拟服务器使用的负载均衡算法
这里使用了Round Robin算法,这个算法会通过每个服务节点依次轮流分配请求
从而实现负载均衡。
[root@localhost ~]# ipvsadm -a -t 192.168.126.19:80 -r 192.168.126.17 -g
-a: 表示添加一个新的服务器规则
-r: 指定目标服务器的IP地址
-g: 指定目标服务器的通信端口
这个命令中没有指定具体的通信端口
所以这个规则会将原始请求的端口转发到目标服务器上端口为80的服务上,也就是默认通信端口。
[root@localhost ~]# ipvsadm -a -t 192.168.126.19:80 -r 192.168.126.18 -g
[root@localhost ~]# ipvsadm --set 1 2 1
设置连接超时时间
[root@localhost ~]# ipvsadm -Ln
# 查看
RS服务器配置
两台realserver分别安装http或者nignx,这里选择nginx,并配置好页面
192.168.126.17:
192.168.126.18:
绑定虚拟地址到lo网卡
# 临时生效,下次开机重启丢失
ip addr add 192.168.126.19/32 dev lo label lo:1
# 永久生效,需要添加到网卡文件
DEVICE=lo:1
IPADDR=192.168.126.19
NETMASK=255.255.255.255
NETWORK=127.0.0.0
# If you're having problems with gated making 127.0.0.0/8 a martian,
# you can change this to something else (255.255.255.255, for example)
BROADCAST=127.255.255.255
ONBOOT=yes
NAME=loopback
# 然后重启网络
systemctl restart network
配置成功后
这一步是为了将客户端请求分发到真实服务器上:因为如果 RS 没有配置 VIP ,那么报文到达 RS 后就会被丢弃。既然要让RS能够处理目标地址为vip的IP包,首先必须要让RS能接收到这个包。在lo上配置VIP能够完成接收包并将结果返回client。
抑制ARP
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
结果当然是两台RS都能响应CIP的请求
LVS NAT模式rr算法搭建
环境准备(前3个IP在同一台机器上):
ip | 角色 | 作用 | 网关 |
---|---|---|---|
ens37: 192.168.80.128 (内网网卡) | DIP | LVS调度器连接内网的ip | |
ens33: 192.168.126.23 (外网网卡) | VIP | LVS调度器对外服务IP(虚拟IP) | 192.168.126.2 |
ens33: 192.168.126.20 (外网网卡) | DIP | LVS调度器服务IP(真实IP) | 192.168.126.2 |
192.168.80.129(内网网卡) | RIP | 后端响应服务器1 | 192.168.80.128 |
192.168.80.130(内网网卡) | RIP | 后端响应服务器2 | 192.168.80.128 |
LVS配置
添加VIP
ip addr add 192.168.126.23/32 dev ens33
# 临时生效,下次开机重启丢失
nmcli con mod ens33 +ipv4.addr 192.168.126.19/32
systemctl restart network
#永久生效,下次开机还在,需要重启网络服务
配置lvs服务器为RS的路由器
[root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@localhost ~]# iptables -F
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.80.0/24 -o ens33 -j MASQUERADE
配置ipvs规则(建立lvs集群)
[root@localhost ~]# ipvsadm -A -t 192.168.126.23:80 -s rr
[root@localhost ~]# ipvsadm -a -t 192.168.126.23:80 -r 192.168.80.129 -m
[root@localhost ~]# ipvsadm -a -t 192.168.126.23:80 -r 192.168.80.130 -m
RS配置
配置nginx:略
关闭外网网卡
ifdown ens33
# 关闭后只能用VMware操作虚拟机
添加网关指向lvs的内网IP
route add default gw 192.168.80.128
启动nginx
结果:同上
LVS Tunnel模式rr算法搭建
环境准备(可以同上LVS NAT模式)
ip | 角色 | 作用 |
---|---|---|
192.168.126.23 | VIP | LVS调度器虚拟IP |
192.168.126.20 | DIP | LVS调度器服务IP(真实IP) |
192.168.126.21 | RIP | 后端web服务器之一 |
192.168.126.22 | RIP | 后端web服务器之一 |
LVS配置
关闭内网网卡,应该不是必要操作
ip link set ens37 down
配置LVS tunl网卡上的虚拟IP(VIP)
modprobe ipip
# 加入隧道模块
ip addr show
# 发现多了一块隧道模式的网卡
ip addr del 192.168.126.23/32 dev ens33
# 把ens33上的虚拟IP删除(我用之前的虚拟机)
ip addr add 192.168.126.23/32 dev tunl0
# 将VIP添加到tunl0网卡上
ip link set up tunl0
# 使网卡生效
开启包转发功能
echo "1" >/proc/sys/net/ipv4/ip_forward
# 这个是临时生效,如果做了上面的永久配置
# 这个就不用做了
设置ipvsadm转发规则
ipvsadm -C
# 清除先前规则,我发现重启后规则也自动清空了
ipvsadm --set 1 2 1
ipvsadm -A -t 192.168.126.23:80 -s rr
ipvsadm -a -t 192.168.126.23:80 -r 192.168.126.21 -i
ipvsadm -a -t 192.168.126.23:80 -r 192.168.126.22 -i
RS配置
开启外网网卡,如果用之前关闭的话。
ifup ens33
关闭先前内网网卡,应该不是必要操作
ip link set ens37 down
添加tunl0隧道并添加VIP
modprobe ipip
关闭arp解析
cat >/etc/sysctl.conf<<EOF
net.ipv4.conf.tunl0.arp_ignore = 1
net.ipv4.conf.tunl0.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.tunl0.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
EOF
sysctl -p
修改反向过滤规则
防止入包和出包有出入而导致丢包的现象。
sysctl -a | grep rp_filter
# 查看反向检验参数,-a表示显示所有的参数,
把所有参数为1的改成0,ens37的应该不用改,但我随手改了。
sysctl -w net.ipv4.conf.default.rp_filter=0
sysctl -w net.ipv4.conf.ens33.rp_filter=0
结果:同上
Keepalived
Keepalived 是使用C语言编写的路由热备软件
keepalived安装
yum install -y curl gcc openssl-devel libnl3-devel net-snmp-devel
# 安装依赖
yum install -y keepalived
keepalived工作原理
keepalived工作在TCP/IP参考模型的第三、四和第五层,也就是网络层、传输层个和应用层
- 网络层:通过ICMP协议向集群每个节点发送一个ICMP数据包(类似于ping功能),如果某个节点没有返回响应数据包,那么认定此节点发生了故障, Keepalived将报告此节点失效,并从集群中剔除故障节点
- 传输层:通过TCP协议的端口连接和扫描技术来判断集群节点是否正常, keepalived一旦在传输层探测到这些端口没有响应数据返回,就认为这些端口所 对应的节点发生故障,从集群中剔除故障节点
- 应用层:用户可以通过编写程序脚本来运行keepalived,keepalived根据脚本来检测各种程序或者服务是否正常,如果检测到有故障,则把对应的服务从服务器中删除
会启动3个进程实现上述功能,分别为:core(核心进程),check和vrrp
- core:负责主进程的启动,维护和全局配置文件的加载;
- check:负责健康检查
- vrrp:用来实现vrrp协议(Virtual Router Redundancy Protocol)虚拟路由冗余协议。当网络设备发生故障时,可以不影响主机之间通信情况下进行设备切换。
keepalived+nginx实现对nginx的高可用
做一个简单的模型
环境准备相对简单,两台机子安装好keepalived和nginx就够了
安装配置启动nginx,安装keepalived:略
关闭防火墙及selinux:略
nginx1配置Keepalived:
[root@localhost tools]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script nginx_check {
script "/tools/nginx_check.sh"
interval 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.126.25
}
track_script {
nginx_check
}
notify_master /tools/master.sh
notify_backup /tools/backup.sh
notify_fault /tools/fault.sh
notify_stop /tools/stop.sh
}
nginx2配置Keepalived:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script nginx_check {
script "/tools/nginx_check.sh"
interval 1
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 52
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.126.25
}
track_script {
nginx_check
}
notify_master /tools/master.sh
notify_backup /tools/backup.sh
notify_fault /tools/fault.sh
notify_stop /tools/stop.sh
}
两台主机配置相关脚本目录及文件
mkdir /tools
cd /tools
vim master.sh
ip=$(hostname -I | awk '{print $1}')
dt=$(date+'%Y%m%d %H:%M:%S')
echo"$0--${ip}--${dt}">> /tmp/kp.log
vim backup.sh
ip=$(hostname -I | awk '{print $1}')
dt=$(date+'%Y%m%d %H:%M:%S')
echo"$0--${ip}--${dt}">> /tmp/kp.log
vim fault.sh
ip=$(ip addr|grep inet| grep 192.168 |awk '{print $2}')
dt=$(date +'%Y%m%d %H:%M:%S')
echo"$0--${ip}--${dt}">> /tmp/kp.log
vim stop.sh
ip=$(ip addr|grep inet| grep 192.168| awk '{print $2}')
dt=$(date +'%Y%m%d %H:%M:%S')
echo"$0--${ip}--${dt}">> /tmp/kp.log
vim nginx_check.sh
#!/bin/bash
result=`pidof nginx`
# pidof nginx用于查找指定nginx的进程ID
# 在这里查看ngixn是否运行
# 运行就为0
if [ ! -z "${result}" ];
then
exit 0
else
exit 1
fi
添加权限
chmod +x *.sh
systemctl restart keepalived
结果
虚拟IP到返回server1的页面
在server1上关闭nginx,模拟nginx故障,返回server2的页面
如果再次启动nginx,又回到web1(因为是抢占模式)
Lvs+keepalived+nginx搭建高可用DR负载均衡集群
相当于就是上面那个LVS DR模式搭建,而把配置虚拟IP的活交给keepalived,而不是使用ipvsadm。但是VMAC有变化,但是不影响LVS系统运行。所以我猜vmac会变成备用调度机的MAC地址。
环境(同上):
RS配置 (两台)
同上(绑定虚拟地址到lo网卡,抑制ARP),不需要多做修改,但是我把nginx配置文件/etc/nginx/nginx.conf改了一点,65秒有点长。
DS配置(两台)
安装Keepalived,ipvsadm(ipvsadm其实不需要,只用于查看ipvs规则)
配置主调度器:
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.126.19
}
}
virtual_server 192.168.126.19 80 {
delay_loop 6
lb_algo rr
lb_kind DR
# persistence_timeout 50
protocol TCP
real_server 192.168.126.17 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.126.18 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
配置备用调度器:同上
state MASTER 改为:state BACKUP
priority 100 改小为:priority 99 或者比100小都行
启动RS nginx和DS keepalived服务
结果
VIP在主调度机上
主调度机上关闭keepalived或者宕机后,vip就漂移到附调度机上。并且依然可以负载均衡。