Bootstrap

LVS_三种模式_Keepalived

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.19VIPLVS调度器对外服务IP(虚拟IP)
192.168.126.16DIPLVS调度器服务IP(真实IP)
192.168.126.17RIP后端响应服务器1
192.168.126.18RIP后端响应服务器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 (内网网卡)DIPLVS调度器连接内网的ip
ens33: 192.168.126.23 (外网网卡)VIPLVS调度器对外服务IP(虚拟IP)192.168.126.2
ens33: 192.168.126.20 (外网网卡)DIPLVS调度器服务IP(真实IP)192.168.126.2
192.168.80.129(内网网卡)RIP后端响应服务器1192.168.80.128
192.168.80.130(内网网卡)RIP后端响应服务器2192.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.23VIPLVS调度器虚拟IP
192.168.126.20DIPLVS调度器服务IP(真实IP)
192.168.126.21RIP后端web服务器之一
192.168.126.22RIP后端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 {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   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 {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   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就漂移到附调度机上。并且依然可以负载均衡。

;