LVS和Keepalived
LVS
LVS概述
LVS(Linux Virtual Server) 是 Linux 内核中集成的一套负载均衡框架,通过 IPVS(IP Virtual Server)模块实现。
基于 IP 和端口(如 TCP/UDP 协议)进行流量转发,不解析应用层(七层)的协议内容
ipvsadm 是一个 用户空间工具,用于配置和管理 LVS 内核模块。它提供命令行接口,允许管理员定义虚拟服务器、添加 / 删除后端服务器,以及调整调度策略。
| 特性 | NAT 模式 | DR 模式 |
|---|---|---|
| 数据包流向 | 请求和响应都经过 Director | 请求经过 Director,响应直接返回客户端 |
| 网卡要求 | Director 需要双网卡 | 单网卡即可 |
| 性能 | 较低(需处理双向流量) | 较高(仅处理请求) |
| 后端网关 | RS 网关必须指向 Director | RS 网关设置为真实网关 |
| 调度器参数 | -m(NAT 模式) | -g(DR 模式) |
NAT模式
Director配置
- 关闭iptables
systemctl stop firewalld
systemctl disable firewalld
- 启用 IP 转发
# 临时启用
echo "1" > /proc/sys/net/ipv4/ip_forward
# 永久生效(编辑 /etc/sysctl.conf)
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
-
配置 VIP
ip addr add 1.1.1.100/32 dev ens37 -
配置 LVS
yum install ipvsadm -y
ipvsadm -C
ipvsadm -A -t 1.1.1.100:80 -s rr
ipvsadm -a -t 1.1.1.100:80 -r 192.168.248.80:8080 -m # 添加后端服务器,使用 NAT 方式
ipvsadm-save > /etc/sysconfig/ipvsadm
RS配置
- 配置路由
ip route del default
ip route del 1.1.1.0/24
ip route add default via 192.168.248.50 dev ens33 # 写Director的IP
ip route add default via 1.1.1.50 dev ens37 # 写Director的IP
DR模式
Director配置
- 绑定VIP到网卡ens33
# 临时绑定(重启失效)
ip addr add 192.168.248.61/32 dev ens33 label ens33:0
# 永久绑定(CentOS)
cat > /etc/sysconfig/network-scripts/ifcfg-ens33:0 <<EOF
DEVICE=ens33:0
BOOTPROTO=none
IPADDR=192.168.248.61
NETMASK=255.255.255.255
ONBOOT=yes
EOF
systemctl restart network
- 设置内核参数
# 禁用 ARP 响应(让 VIP 只通过 Director 响应)
echo "1" > /proc/sys/net/ipv4/conf/ens33/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/ens33/arp_announce
# 永久生效
cat >> /etc/sysctl.conf <<EOF
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
EOF
sysctl -p
- 配置LVS规则
yum install -y ipvsadm
ipvsadm -C # 清空之前的规则
ipvsadm -A -t 192.168.248.61:8080 -s rr # 创建 LVS 服务,使用轮询调度算法
ipvsadm -a -t 192.168.248.61:8080 -r 192.168.248.80:8080 -g # 添加 Real Server,使用 DR 方式
ipvsadm-save > /etc/sysconfig/ipvsadm # 保存配置到系统启动时自动加载
ipvsadm -Ln # 查看 LVS 规则
RS配置
- 配置VIP到lo接口
# 临时绑定(重启失效)
ip addr add 192.168.248.61/32 dev lo
# 永久绑定(CentOS) lo子接口
# Centos7不支持在lo接口配置 IPADDR_SECONDARIES="192.168.248.61/32 192.168.248.62/32"
cat > /etc/sysconfig/network-scripts/ifcfg-lo:0 <<EOF
DEVICE=lo:0
BOOTPROTO=none
IPADDR=192.168.248.61
NETMASK=255.255.255.255
ONBOOT=yes
EOF
systemctl restart network
- 设置内核参数
# 临时配置
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore # 禁止lo响应 ARP请求
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce # 防止广播lo接口的 ARP请求
# 永久配置(追加到 /etc/sysctl.conf)
cat >> /etc/sysctl.conf <<EOF
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
EOF
sysctl -p
抓包分析
首先我们统计下arp 表
| IP | MAC |
|---|---|
| 192.168.248.10 | 00:0c:29:81:26:7e |
| 192.168.248.80 | 00:0c:29:6e:6e:6e |
| 192.168.248.60 | 00:0c:29:b6:ff:10 |
| 192.168.248.61 | 00:0c:29:b6:ff:10 |
数据包流向:
简单的说,就是client发送给Director的请求,Director转发给RS,然后RS直接回复Client。
其实从这也可以看出,TCP3次握手和四次挥手,只看IP不看MAC
- "SYN
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:81:26:7e
目的MAC:00:0c:29:b6:ff:10" - "TCP Retransmission |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:b6:ff:10
目的MAC:00:0c:29:6e:6e:6e" - "SYN,ACK |
源IP:192.168.248.61
目的IP:192.168.248.10
源MAC:00:0c:29:6e:6e:6e
目的MAC:00:0c:29:81:26:7e" - "ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:81:26:7e
目的MAC:00:0c:29:b6:ff:10" - "TCP Dup ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:b6:ff:10
目的MAC:00:0c:29:6e:6e:6e" - "GET / HTTP/1.1 |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:81:26:7e
目的MAC:00:0c:29:b6:ff:10" - "TCP Retransmission |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:b6:ff:10
目的MAC:00:0c:29:6e:6e:6e" - "源IP:192.168.248.61
目的IP:192.168.248.10
源MAC:00:0c:29:6e:6e:6e
目的MAC:00:0c:29:81:26:7e" - "源IP:192.168.248.61
目的IP:192.168.248.10
源MAC:00:0c:29:6e:6e:6e
目的MAC:00:0c:29:81:26:7e" - "源IP:192.168.248.61
目的IP:192.168.248.10
源MAC:00:0c:29:6e:6e:6e
目的MAC:00:0c:29:81:26:7e" - "ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:81:26:7e
目的MAC:00:0c:29:b6:ff:10" - "TCP Dup ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:b6:ff:10
目的MAC:00:0c:29:6e:6e:6e" - "ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:81:26:7e
目的MAC:00:0c:29:b6:ff:10" - "TCP Dup ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:b6:ff:10
目的MAC:00:0c:29:6e:6e:6e" - "FIN,ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:81:26:7e
目的MAC:00:0c:29:b6:ff:10" - "TCP Retransmission |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:b6:ff:10
目的MAC:00:0c:29:6e:6e:6e" - "FIN,ACK |
源IP:192.168.248.61
目的IP:192.168.248.10
源MAC:00:0c:29:6e:6e:6e
目的MAC:00:0c:29:81:26:7e" - "ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:81:26:7e
目的MAC:00:0c:29:b6:ff:10" - "TCP Dup ACK |
源IP:192.168.248.10
目的IP:192.168.248.61
源MAC:00:0c:29:b6:ff:10
目的MAC:00:0c:29:6e:6e:6e"
问题
RS在lo上配置VIP的作用
RS在lo上配置了VIP的作用就是,Director 转发数据包时,没有修改源/目的IPV4地址,而是修改MAC地址
所以Director转发给RS时,目的地址是VIP,RS收到数据包后,会发现是发给自己的VIP的,就直接处理了,否则RS会丢包或转发
RS在lo上配置了VIP,但实际上接收数据包的还是物理网卡是吗?
因为ipvsadm -a -t 192.168.248.51:8080 -r 192.168.248.70:8080 -g
Director 负责修改数据包的目的 MAC 地址,使其指向 RS 的物理网卡,所以不是发给lo
虽然 VIP 绑定在 lo 接口,但 Linux 内核认为本地所有接口的 IP 均属于主机本身。因此,无论数据包从哪个接口进入,只要目标 IP 是本地任意接口配置的 IP,内核都会将其视为 “本地进程需处理的数据包”,直接将其路由到本地协议栈
arp_ignore参数解析
控制是否响应 ARP 请求
0(默认):只要 ARP 请求的 IP 存在于本机任何网卡,就回应 MAC 地址(可能导致 ARP 混乱)。
1:仅当 ARP 请求的 IP 与接收网卡的 IP 严格匹配时,才回应 MAC 地址
-
Director[会响应arp]
ens33.arp_ignore=1
Director 只响应目标 IP 是自身物理网卡 IP 的 ARP 请求,VIP 配在 ens33:0 上,内核认为 ens33 配置了 VIP(因为 ens33:0 共享 IP 空间)。
ens33.arp_ignore=1 → 允许响应。 -
RS[不响应arp]
VIP:
配置在 lo 接口(如 192.168.248.51/32)。
物理网卡(如 ens33):未配置 VIP,仅配置真实 IP(如 192.168.248.70)。
ARP 参数:
lo.arp_ignore=1,lo.arp_announce=2。
ens33.arp_ignore=0(默认值)。
当 ARP 请求到达 ens33 [ARP请求到达的都是物理网卡]
请求内容:Who has 192.168.248.51? Tell 192.168.248.10
内核处理流程:
检查接收接口 ens33:ens33 配置的 IP 是 192.168.248.70,与请求的 192.168.248.51 不匹配。
检查 arp_ignore 值:ens33.arp_ignore=0 → 允许继续检查其他接口。
检查其他接口:发现 lo 接口配置了 192.168.248.51。
检查 lo 的 arp_ignore 值:lo.arp_ignore=1 → 要求请求必须从 lo 接口接收才响应。
但实际请求是从 ens33 接收的,与 lo 无关 → 不响应。
arp_announce参数解析
决定系统在发送 ARP 响应时,使用哪个 IP 和 MAC 地址作为源
0(默认):允许使用任意本地 IP 地址作为 ARP 响应的源 IP,无论该 IP 配置在哪个接口。
2:严格只使用本网卡的 IP 地址进行 ARP 宣告
-
Director[物理网卡的源IP和MAC地址进行响应arp]
ens33.arp_announce=2
确保是 ens33 发送 ARP 响应,不使用 VIP 作为源 IP。 -
RS[防止RS广播VIP的ARP请求]
防止 RS 主动广播 VIP 的 ARP 请求,避免客户端缓存错误的 MAC 地址
keepalived
| 主机 | 内网 IP (ens33) | 外网 IP (ens37) | VIP | 角色 |
|---|---|---|---|---|
| Client | 192.168.248.10/24 | 无 | 无 | 客户端发起请求 |
| Director1 | 192.168.248.50/24 | 1.1.1.50/24 | 192.168.248.100 | 主负载均衡器 |
| Director2 | 192.168.248.60/24 | 1.1.1.60/24 | 192.168.248.100 | 备负载均衡器 |
| RS | 无 | 1.1.1.80/24 | 无 | 应用服务器 |
keepalived概述
- 抢占模式:指当主节点(Master)恢复正常后,会主动从当前备用节点(Backup)夺回虚拟 IP(VIP)及服务资源的控制权,恢复为主节点。
- 非抢占模式:主节点恢复后,需手动切换或通过其他策略(如权重值)才能重新成为 Master,备用节点不会主动让出资源。
避免因主节点短暂故障恢复后频繁切换 VIP,适合对稳定性要求高、切换代价大的场景。
keepalived配置
- Master
! Configuration File for keepalived
global_defs {
router_id LVS_MASTER
}
vrrp_instance VI_1 {
state BACKUP # 实测这里得配置为BACKUP,不然还是会抢占
interface ens33 # 绑定到内网网卡
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.248.100 # 内网 VIP
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens37 # 绑定到内网网卡
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
virtual_ipaddress {
1.1.1.100 # 内网 VIP
}
}
virtual_server 192.168.248.100 80 {
delay_loop 6 # 检查间隔时间(秒),但下面的real_server 8080并没有配置,所以这里配置的延迟检查其实是无效的
lb_algo rr # 负载均衡算法,rr 表示轮询
lb_kind NAT # 负载均衡类型,NAT 表示 NAT 模式
persistence_timeout 50 # 持久连接超时时间(秒)
protocol TCP
real_server 1.1.1.80 8080 { # RS 外网 IP
weight 1
}
}
- Backup
! Configuration File for keepalived
global_defs {
router_id LVS_BACKUP
}
vrrp_instance VI_1 {
state BACKUP
interface ens33 # 绑定到内网网卡
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
nopreempt
virtual_ipaddress {
192.168.248.100 # 内网 VIP
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens37 # 绑定到内网网卡
virtual_router_id 52
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
nopreempt
virtual_ipaddress {
1.1.1.100 # 内网 VIP
}
}
virtual_server 192.168.248.100 80 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 1.1.1.80 8080 { # RS 外网 IP
weight 1
}
}
- 健康检查
# 纯TCP连接检查
TCP_CHECK {
connect_port 8080 # 检查端口
connect_timeout 3 # 连接超时
retry 3 # 重试次数
delay_before_retry 3 # 重试间隔
}
RS配置路由
配置默认路由指向VIP:1.1.1.100

修改日志路径
tail -f /var/log/messages # 默认路径
修改keepalived日志存储路径(修改keepalived配置文件)
vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 0"
vim /etc/rsyslog.conf
local0.* /var/log/keepalived.log #添加一行配置
systemctl restart rsyslog # rsyslog,系统日志管理工具,负责统一管理所有日志的流转
systemctl restart keepalived


浙公网安备 33010602011771号