一、案例分析
根据以下主机资源,做一个lvs的NAT模型的负载均衡实验,两台后端主机是http服务,具体的主机信息 如下:

1.需求分析
需求分析
1 配置主机网络环境
- 1.0 四台VM主机的配置
- 1.1 LVS主机网络环境配置
- 2 后端RS1主机网络配置
- 1.3 后端RS2主机网络配置
2 后端真实主机配置
- 2.1 后端RS1主机部署http服务
- 2.2 后端RS2主机部署http服务
3 LVS环境配置
- 3.1 部署LVS集群服务
- 3.2 测试LVS效果
---
技术点分析
1 配置主机网络环境
1.0 四台VM主机的配置
- LVS主机准备双网卡,其他主机都配备1个网卡
- lvs-client和lvs-server: ens33在同一个网段
- lvs-server: ens37、lvs-rs1和lvs-rs2的网卡在同一个网段
1.1 LVS主机网络环境配置
- VM主机准备双网卡,ens33是NAT模式,ens37是仅主机模式
- 双网段的ip网卡配置,开启ip数据包转发功能
1.2 后端RS1主机网络配置
- VM主机准备单网卡,是仅主机模式
1.3 后端RS2主机网络配置
- VM主机准备单网卡,是仅主机模式
1.4 客户端主机网络配置
- VM主机准备单网卡,是NAT模式
1.5 网络环境测试
- 在多台主机间测试网络效果
---
2 后端真实主机配置
2.1 后端RS1主机部署http服务
- yum方式安装http
- 定制后端http首页
- 注意:因为是仅主机网络,所以需要通过本地镜像的方式进行部署
2.2 后端RS2主机部署http服务
- yum方式安装http
- 定制后端http首页
- 注意:因为是仅主机网络,所以需要通过本地镜像的方式进行部署
---
3 LVS环境配置
3.1 部署LVS集群服务
- 创建LVS集群服务
- 增加RS主机条目
3.2 测试LVS效果
- 应该使用curl或者浏览器的方式来测试
- 不能用ping的方式来测试,因为我们是基于协议实现转发的,ping没有意义。
2.实操演示
1.定制lvs-client主机ip(ubuntu2404)
root@ubuntu12:~# cat /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
ens33:
addresses:
- "10.0.0.12/24"
nameservers:
addresses:
- 223.5.5.5
search: []
routes:
- to: "default"
via: "10.0.0.2"
网卡配置生效:
netplan apply
2 定制lvs-server主机ip(ubuntu2404)
定制网卡配置,ens33是NAT模式,ens37是仅主机模式,仅主机模式不用配置网关
root@ubuntu13:~# cat /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
ens33:
addresses:
- "10.0.0.13/24"
nameservers:
addresses:
- 223.5.5.5
search: []
routes:
- to: "default"
via: "10.0.0.2"
ens37:
addresses:
- "192.168.8.13/24"
网卡配置生效:
netplan apply
3 定制lvs-RS1主机ip (rocky10)
cat /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
uuid=73c7a7a5-c4b8-3ba4-ad47-d861792de734
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1753891144
[ethernet]
[ipv4]
method=manual
address1=192.168.8.14/24,10.0.0.2
dns=223.5.5.5;114.114.114.114
may-fail=false
[ipv6]
addr-gen-mode=eui64
method=auto
[proxy]
网卡配置生效
nmcli connection down ens160 && systemctl restart NetworkManager
成功停用连接 "ens160"(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/2)
4 定制lvs-RS2主机ip
cat /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1753891144
[ethernet]
[ipv4]
address=192.168.8.15/24
dns=8.8.8.8;114,114,114,144
method=manual
[ipv6]
addr-gen-mode=eui64
method=auto
[proxy]
网卡配置生效
nmcli connection down ens160 && systemctl restart NetworkManager
成功停用连接 "ens160"(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/2)
4.基础环境配置:
1. lvs主机开启数据转发
#定制内核参数
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/20-ip_forward.conf && sudo sysctl -p /etc/sysctl.d/20-ip_forward.conf
net.ipv4.ip_forward = 1
#测试效果
root@ubuntu12:~# sysctl -a |grep -i ip_forw
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
2 RS1主机定制网关
注意:如果网关不指向lvs主机的ip地址,那么数据包交给其他主机,导致数据包无法原路通过lvs返回出 去。但是因为他们属于同一个网段,数据包还是可以抓取到的,只不过没有意义而已。 lvs-rs1主机定制默认的网关出口为lvs主机
[root@rocky14 ~]# ip r add default via 192.168.8.13
[root@rocky14 ~]# ip route list
default via 192.168.8.13 dev ens160
192.168.8.0/24 dev ens160 proto kernel scope link src 192.168.8.14 metric 100
3 RS2主机定制网关
lvs-rs2主机定制默认的网关出口为lvs主机
[root@rocky15 ~]# ip r add default via 192.168.8.13
[root@rocky15 ~]# ip r list
default via 192.168.8.13 dev ens160
192.168.8.0/24 dev ens160 proto kernel scope link src 192.168.8.15 metric 100
4 lvs-rs1、rs2部署web服务
1 定制镜像仓库
定制本地镜像服务
#挂载磁盘
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
#备份原始文件
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/
cat > /etc/yum.repos.d/rocky.repo <<-eof
[local-rocky-baseos]
name=Local Rocky 10 BaseOS Repository
baseurl=file:///image/BaseOS
enabled=1
gpgcheck=0
[local-rocky-appstream]
name=Local Rocky 10 AppStream Repository
baseurl=file:///image/AppStream
enabled=1
gpgcheck=0
eof
#清缓存
yum clean all
#更新软件源
yum makecache
-
部署httpd服务
yum install -y httpd
yum install -y httpd vim
echo 'hello RS1
' > /var/www/html/index.html
systemctl start httpd
[root@rocky14 ~]#curl localhosthello RS1
5 lvs-server主机定制集群
1 软件环境安装
安装ipvsadm服务
root@ubuntu13:~# apt install ipvsadm
2 集群环境部署
定制lvs集群服务
ipvsadm -A -t 10.0.0.13:80 -s rr
增加RS主机列表
ipvsadm -a -t 10.0.0.13:80 -r 192.168.8.14 -m
root@ubuntu13:~# ipvsadm -a -t 10.0.0.13:80 -r 192.168.8.15 -m
注意:
我们这里用的是nat模式,所以再添加RS主机的时候,需要使用-m选项
查看集群主机效果
root@ubuntu13:~# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.13:80 rr
-> 192.168.8.14:80 Masq 1 0 0
-> 192.168.8.15:80 Masq 1 0 0
6 环境测试
6.1 客户端测试
客户端访问lvs的对外ip地址
root@ubuntu12:~# curl 10.0.0.13
<h1>hello RS2</h1>
root@ubuntu12:~# curl 10.0.0.13
<h1>hello RS1</h1>
root@ubuntu12:~# curl 10.0.0.13
<h1>hello RS2</h1>
root@ubuntu12:~# curl 10.0.0.13
<h1>hello RS1</h1>
结果显示:可以看到实现了流量的正常转发效果
二、keepalived
1.需求分析
keepalived高可用
环境:2台 ubuntu2404服务器作为lvs ds(ds A:10.0.0.11 ds B :10.0.0.12 ) (RS 1: 10.0.0.13 RS 2:10.0.0.14,均提供web服务)
虚拟 vip 10.0.0.100
要求:1.在2台ds上安装keepalived 配置文件(设置全局配置,vrrp实例配置,指定vip 优先级 ( ds A 优先级 高于 ds B ,)认证信息等,同时在配置文件中集成lvs虚拟服务和后端rs的配置)
2.启动2台ds的keepalived服务,查看keepalived状态和vip分配情况(验证vip是否在优先级高的ds A上)。在客户端主机上访问 vip ,验证能否正常访问web服务器且实现负载均衡
3.模拟ds A故障(如停止 ds A的keepalived服务或者关闭ds A 服务器),观察vip是否自动漂移到 ds B 上,客户端是否能继续通过vip访问web服务,实现高可用,之后回复ds A ,观察vip是否飘逸回ds A(根据配置的抢占模式)
1.1Keepalived中VIP的原理及使用限制
VIP工作原理
Keepalived中的虚拟IP(VIP)是基于VRRP(Virtual Router Redundancy Protocol)协议实现的高可用性解决方案,其核心原理如下:
-
VRRP组架构:
- 系统中存在一个MASTER节点和一个或多个BACKUP节点
- 所有节点组成一个VRRP组,共享同一个VIP
- 只有MASTER节点实际持有并响应VIP的流量
-
状态监控与故障转移:
- MASTER节点定期发送VRRP通告包(Advertisement)给BACKUP节点
- 当BACKUP节点在一定时间内未收到通告,会触发选举机制
- 优先级最高的BACKUP节点升级为新的MASTER,接管VIP
-
ARP更新机制:
- VIP切换时,新MASTER会发送Gratuitous ARP(免费ARP)包
- 通知网络设备更新ARP表,将VIP映射到新MASTER的MAC地址
- 确保网络流量正确导向
-
优先级与抢占策略:
- 节点通过priority参数设置优先级(0-255)
- 支持preempt(抢占)和nopreempt(非抢占)模式
- 影响节点恢复后是否立即夺回MASTER角色
使用限制
-
网络限制:
- VIP必须与物理接口在同一子网内,不支持跨网段
- 需要网络设备支持组播/广播(取决于VRRP版本)
- 防火墙需开放VRRP协议(协议号112)
-
云环境挑战:
- 公有云(AWS/Azure/GCP等)通常不支持标准VRRP
- 云平台安全组策略可能阻止VRRP通信
- 需要使用云厂商提供的替代方案(如ELB、浮动IP API)
-
脑裂风险:
- 网络分区时可能出现多个节点同时持有VIP的情况
- 需配置额外仲裁机制(如quorum disk、第三方仲裁服务)
-
切换时间:
- VIP切换通常需要1-3秒,无法实现零中断
- 对超低延迟要求的场景不适用
-
资源与扩展性:
- 单个VRRP实例支持的VIP数量有限
- 大量VIP会增加网络广播负担
- 每个节点的处理能力影响VIP切换速度
-
服务连续性:
- VIP切换不等于服务切换,应用层需要独立配置
- 需确保BACKUP节点具备足够的资源容量
-
特殊环境问题:
- 虚拟化环境中可能存在MAC地址过滤
- 某些交换机对频繁MAC地址变更有限制
- IPv6环境配置更复杂
在实际部署中,应结合业务需求和网络环境,合理设计VIP策略,并考虑使用额外的健康检查机制和通知系统,以提高整体可靠性。
1.2网络规划
| 服务器类型 | IP地址 | 角色 | 说明 |
|---|---|---|---|
| DS A | 10.0.0.11 | MASTER | 优先级100,主负载均衡器 |
| DS B | 10.0.0.12 | BACKUP | 优先级90,备用负载均衡器 |
| RS 1 | 10.0.0.13 | Real Server | Web服务器1 |
| RS 2 | 10.0.0.14 | Real Server | Web服务器2 |
| VIP | 10.0.0.100 | 虚拟IP | 客户端访问地址 |
为什么VIP选择10.0.0.100:
- 与DS服务器在同一网段,确保VRRP协议正常工作
- 避免跨网段路由复杂性
- 符合LVS DR模式的技术要求
2.实操演示
第一阶段:DS服务器配置
1. 准备工作(两台DS都执行)
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装必要软件
sudo apt install -y keepalived ipvsadm
# 确认实际网卡名称(通常为ens33、eth0等)
ip addr show
# 假设输出显示主网卡为ens33,后续配置将使用此名称
2. 配置内核参数(两台DS都执行)
sudo tee /etc/sysctl.d/90-lvs.conf > /dev/null <<'EOF'
# LVS DR模式必需的内核参数
net.ipv4.ip_forward = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens33.send_redirects = 0
# 防止反向路径过滤导致数据包被丢弃
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.ens33.rp_filter = 0
EOF
# 应用配置
sudo sysctl -p /etc/sysctl.d/90-lvs.conf
# 验证配置
sysctl net.ipv4.ip_forward net.ipv4.conf.all.rp_filter
3. 配置防火墙(两台DS都执行)
# 允许VRRP协议(协议号112)
sudo ufw allow proto vrrp comment 'VRRP protocol for Keepalived'
# 允许HTTP流量
sudo ufw allow 80/tcp comment 'HTTP service'
# 重新加载防火墙
sudo ufw reload
# 验证规则
sudo ufw status numbered
4. 配置DS A (10.0.0.11) - MASTER
sudo tee /etc/keepalived/keepalived.conf > /dev/null <<'EOF'
# 全局配置
global_defs {
router_id LVS_DS_A
script_user root
enable_script_security
notification_email {
admin@example.com
}
notification_email_from keepalived@ds-a.example.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
}
# VRRP实例配置
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass SecurePass123!
}
virtual_ipaddress {
10.0.0.100/24 dev ens33 label ens33:vip
}
# 当状态变化时执行脚本(可选)
notify_master "/etc/keepalived/scripts/notify_master.sh"
notify_backup "/etc/keepalived/scripts/notify_backup.sh"
notify_fault "/etc/keepalived/scripts/notify_fault.sh"
}
# 虚拟服务器配置(集成LVS)
virtual_server 10.0.0.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
# 健康检查脚本(可选)
# sorry_server 127.0.0.1 80
real_server 10.0.0.13 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 10.0.0.14 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
EOF
5. 配置DS B (10.0.0.12) - BACKUP
sudo tee /etc/keepalived/keepalived.conf > /dev/null <<'EOF'
# 全局配置
global_defs {
router_id LVS_DS_B
script_user root
enable_script_security
notification_email {
admin@example.com
}
notification_email_from keepalived@ds-b.example.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
}
# VRRP实例配置
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass SecurePass123!
}
virtual_ipaddress {
10.0.0.100/24 dev ens33 label ens33:vip
}
notify_master "/etc/keepalived/scripts/notify_master.sh"
notify_backup "/etc/keepalived/scripts/notify_backup.sh"
notify_fault "/etc/keepalived/scripts/notify_fault.sh"
}
# 虚拟服务器配置(与DS A相同)
virtual_server 10.0.0.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 10.0.0.13 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 10.0.0.14 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
EOF
6. 创建状态通知脚本(两台DS都执行)
# 创建脚本目录
sudo mkdir -p /etc/keepalived/scripts
# 创建通知脚本
sudo tee /etc/keepalived/scripts/notify_master.sh > /dev/null <<'EOF'
#!/bin/bash
LOG_FILE="/var/log/keepalived-state.log"
HOSTNAME=$(hostname)
VIP="10.0.0.100"
DATE=$(date +"%Y-%m-%d %H:%M:%S")
echo "[$DATE] $HOSTNAME became MASTER for VIP $VIP" >> $LOG_FILE
# 可以在这里添加其他操作,如发送邮件通知
EOF
sudo tee /etc/keepalived/scripts/notify_backup.sh > /dev/null <<'EOF'
#!/bin/bash
LOG_FILE="/var/log/keepalived-state.log"
HOSTNAME=$(hostname)
VIP="10.0.0.100"
DATE=$(date +"%Y-%m-%d %H:%M:%S")
echo "[$DATE] $HOSTNAME became BACKUP for VIP $VIP" >> $LOG_FILE
EOF
sudo tee /etc/keepalived/scripts/notify_fault.sh > /dev/null <<'EOF'
#!/bin/bash
LOG_FILE="/var/log/keepalived-state.log"
HOSTNAME=$(hostname)
VIP="10.0.0.100"
DATE=$(date +"%Y-%m-%d %H:%M:%S")
echo "[$DATE] $HOSTNAME entered FAULT state for VIP $VIP" >> $LOG_FILE
EOF
# 设置脚本权限
sudo chmod +x /etc/keepalived/scripts/*.sh
sudo touch /var/log/keepalived-state.log
sudo chown root:root /var/log/keepalived-state.log
7. 启动和验证Keepalived服务(两台DS都执行)
# 启动服务
sudo systemctl start keepalived
# 设置开机自启
sudo systemctl enable keepalived
# 检查服务状态
sudo systemctl status keepalived --no-pager
# 检查VIP分配(应该在DS A上)
ip addr show ens33 | grep 10.0.0.100
# 检查LVS规则
sudo ipvsadm -ln
# 监控日志
sudo journalctl -u keepalived -f --since "1 minute ago"
第二阶段:RS服务器配置
1. 配置内核参数(两台RS都执行)
sudo tee /etc/sysctl.d/90-lvs-rs.conf > /dev/null <<'EOF'
# LVS DR模式在RS上的必需参数
# arp_ignore: 控制ARP请求响应
# 1 = 只响应目标IP地址是接收网卡上配置的本地地址的ARP请求
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
# arp_announce: 控制ARP宣告
# 2 = 总是使用最佳本地地址(避免使用VIP作为源地址)
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
# 禁用rp_filter,防止丢弃非预期路径的数据包
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
EOF
# 应用配置
sudo sysctl -p /etc/sysctl.d/90-lvs-rs.conf
2. 创建RS配置脚本(两台RS都执行)
sudo tee /usr/local/bin/lvs-rs-config.sh > /dev/null <<'EOF'
#!/bin/bash
# LVS Real Server 配置脚本
# 适用于 DR 模式,配置 lo:0 接口和 ARP 参数
VIP="10.0.0.100"
INTERFACE="lo:0"
function start() {
echo "Starting LVS Real Server configuration for VIP $VIP..."
# 1. 在lo接口上添加VIP
if ! ip addr show $INTERFACE | grep -q "$VIP"; then
ip addr add $VIP/32 dev lo
ip link set $INTERFACE up
echo "VIP $VIP configured on $INTERFACE"
else
echo "VIP $VIP already configured on $INTERFACE"
fi
# 2. 添加路由(确保返回流量通过正确接口)
if ! ip route show table all | grep -q "local $VIP"; then
ip route add local $VIP dev lo proto kernel scope host table local
echo "Route for $VIP added to local table"
fi
# 3. 应用内核参数(双重保障)
sysctl -p /etc/sysctl.d/90-lvs-rs.conf >/dev/null 2>&1
echo "LVS Real Server configuration completed successfully"
}
function stop() {
echo "Stopping LVS Real Server configuration for VIP $VIP..."
# 1. 移除VIP
if ip addr show $INTERFACE | grep -q "$VIP"; then
ip addr del $VIP/32 dev lo
echo "VIP $VIP removed from $INTERFACE"
fi
# 2. 移除路由
if ip route show table all | grep -q "local $VIP"; then
ip route del local $VIP dev lo
echo "Route for $VIP removed from local table"
fi
echo "LVS Real Server configuration stopped"
}
function status() {
if ip addr show $INTERFACE | grep -q "$VIP"; then
echo "LVS Real Server is RUNNING for VIP $VIP"
echo "Current configuration:"
ip addr show $INTERFACE
ip route show table local | grep $VIP
else
echo "LVS Real Server is NOT RUNNING for VIP $VIP"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 2
start
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit 0
EOF
# 设置脚本权限
sudo chmod +x /usr/local/bin/lvs-rs-config.sh
# 首次运行配置
sudo /usr/local/bin/lvs-rs-config.sh start
# 验证配置
sudo /usr/local/bin/lvs-rs-config.sh status
3. 创建systemd服务(两台RS都执行)
sudo tee /etc/systemd/system/lvs-rs.service > /dev/null <<'EOF'
[Unit]
Description=LVS Real Server Configuration for DR Mode
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/lvs-rs-config.sh start
ExecStop=/usr/local/bin/lvs-rs-config.sh stop
ExecReload=/usr/local/bin/lvs-rs-config.sh restart
[Install]
WantedBy=multi-user.target
EOF
# 重载systemd配置
sudo systemctl daemon-reload
# 启动服务并设置开机自启
sudo systemctl start lvs-rs
sudo systemctl enable lvs-rs
# 检查服务状态
sudo systemctl status lvs-rs --no-pager
4. 验证RS配置(两台RS都执行)
# 检查VIP是否配置在lo接口
ip addr show lo
# 检查路由表
ip route show table local | grep 10.0.0.100
# 检查ARP参数
sysctl net.ipv4.conf.all.arp_ignore net.ipv4.conf.all.arp_announce
# 测试Web服务(确保已安装并运行)
sudo apt install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx
# 创建不同内容的测试页面(区分RS1和RS2)
if [ "$(hostname)" = "rs1" ]; then
echo "<h1>Real Server 1 (10.0.0.13)</h1>" | sudo tee /var/www/html/index.html
else
echo "<h1>Real Server 2 (10.0.0.14)</h1>" | sudo tee /var/www/html/index.html
fi
第三阶段:验证和测试
1. 初始验证(从客户端执行)
# 检查VIP是否可达
ping -c 3 10.0.0.100
# 访问Web服务
curl http://10.0.0.100
# 应该看到来自RS1或RS2的响应
# 多次访问测试负载均衡
for i in {1..10}; do
curl http://10.0.0.100 | grep -o "Real Server [12]"
sleep 0.5
done
# 应该看到RS1和RS2交替响应
# 检查HTTP头
curl -I http://10.0.0.100
2. 详细验证(从DS A执行)
# 检查Keepalived状态
sudo systemctl status keepalived --no-pager
# 检查VIP
ip addr show ens33
# 检查LVS规则
sudo ipvsadm -ln
# 应该看到类似以下输出:
# IP Virtual Server version 1.2.1 (size=4096)
# Prot LocalAddress:Port Scheduler Flags
# -> RemoteAddress:Port Forward Weight ActiveConn InActConn
# TCP 10.0.0.100:80 rr persistent 50
# -> 10.0.0.13:80 Route 1 0 0
# -> 10.0.0.14:80 Route 1 0 0
# 检查ARP表(确保VIP的MAC地址是DS A的MAC)
arp -an | grep 10.0.0.100
# 检查内核日志
dmesg | grep -i keepalived
3. 模拟故障转移(从DS A执行)
# 1. 停止DS A的Keepalived服务
sudo systemctl stop keepalived
# 2. 在DS B上观察VIP转移(在另一个终端执行)
# 在DS B上执行:
ip addr show ens33 | grep 10.0.0.100
# 应该在几秒内看到VIP出现在DS B上
# 3. 从客户端验证服务连续性
curl http://10.0.0.100
# 服务应该仍然可用
# 4. 检查DS B的Keepalived日志
sudo journalctl -u keepalived -f --since "1 minute ago"
# 5. 检查状态通知日志
cat /var/log/keepalived-state.log
4. 恢复和抢占测试(从DS A执行)
# 1. 重启DS A的Keepalived服务
sudo systemctl start keepalived
# 2. 在DS A上观察VIP恢复(抢占模式)
ip addr show ens33 | grep 10.0.0.100
# 应该在几秒内看到VIP回到DS A上(因为priority 100 > 90)
# 3. 从客户端验证
curl http://10.0.0.100
# 服务应该仍然可用
# 4. 检查状态日志
cat /var/log/keepalived-state.log
# 应该看到DS A恢复为MASTER,DS B降级为BACKUP
第四阶段:维护和监控
1. 创建健康检查脚本(可选,增强可靠性)
sudo tee /etc/keepalived/scripts/check_rs_health.sh > /dev/null <<'EOF'
#!/bin/bash
# 检查RS健康状态,可在keepalived配置中使用
RS_LIST=("10.0.0.13" "10.0.0.14")
PORT=80
TIMEOUT=3
for RS in "${RS_LIST[@]}"; do
# 使用curl检查HTTP状态
if curl -m $TIMEOUT -s -o /dev/null -w "%{http_code}" "http://$RS:$PORT" | grep -q "200"; then
echo "$RS is HEALTHY" >> /var/log/keepalived-health.log
else
echo "$RS is UNHEALTHY" >> /var/log/keepalived-health.log
# 可以在这里添加通知逻辑
fi
done
EOF
sudo chmod +x /etc/keepalived/scripts/check_rs_health.sh
sudo touch /var/log/keepalived-health.log
2. 配置Prometheus监控(可选)
# 安装node_exporter
sudo apt install -y prometheus-node-exporter
# 创建Keepalived状态脚本
sudo tee /usr/local/bin/keepalived-status.sh > /dev/null <<'EOF'
#!/bin/bash
if systemctl is-active --quiet keepalived; then
if ip addr show ens33 | grep -q "10.0.0.100"; then
echo "keepalived_state{role=\"active\"} 1"
echo "keepalived_state{role=\"backup\"} 0"
else
echo "keepalived_state{role=\"active\"} 0"
echo "keepalived_state{role=\"backup\"} 1"
fi
else
echo "keepalived_state{role=\"active\"} 0"
echo "keepalived_state{role=\"backup\"} 0"
fi
EOF
sudo chmod +x /usr/local/bin/keepalived-status.sh
原理解析
1. LVS DR模式工作原理
客户端
│
▼
10.0.0.100 (VIP) ←─┐
│ │
▼ │
DS (Director) │
│ │
▼ │
10.0.0.13/14 (RS) │
│ │
└────────────────┘ (RS直接响应给客户端,不经过DS)
- 请求流程:客户端 → VIP (DS) → RS
- 响应流程:RS → 客户端 (直接,不经过DS)
- 关键要求 :
- VIP必须配置在DS和RS的lo接口上
- RS必须抑制ARP响应,避免网络混乱
- DS和RS必须在同一物理网络
2. VRRP协议工作原理
正常状态:
DS A (MASTER): 持有VIP,发送VRRP通告
DS B (BACKUP): 监听通告,处于待命状态
故障转移:
DS A故障 → 停止发送通告
DS B检测到 → 等待3个通告间隔 → 宣布自己为MASTER → 接管VIP
恢复抢占:
DS A恢复 → 发送高优先级通告
DS B收到 → 降级为BACKUP → 释放VIP
DS A重新获取VIP
3. 关键内核参数解释
arp_ignore = 1:
只响应目标IP是接收网卡上配置的本地地址的ARP请求
防止RS响应VIP的ARP请求,避免网络混乱
arp_announce = 2:
总是使用最佳本地地址响应ARP
确保RS使用真实IP而不是VIP响应ARP
rp_filter = 0:
禁用反向路径过滤
允许接收来自非预期接口的数据包
对LVS DR模式至关重要
故障排除指南
常见问题及解决方案
-
VIP无法启动
# 检查网卡名称是否正确 ip addr show # 检查内核参数 sysctl net.ipv4.ip_forward net.ipv4.conf.all.rp_filter # 检查Keepalived日志 journalctl -u keepalived -f -
RS不响应请求
# 检查RS的lo接口配置 ip addr show lo # 检查ARP参数 sysctl net.ipv4.conf.all.arp_ignore net.ipv4.conf.all.arp_announce # 检查防火墙 sudo ufw status -
VRRP通告问题
# 检查防火墙是否允许VRRP sudo ufw status | grep VRRP # 使用tcpdump抓包分析 sudo apt install -y tcpdump sudo tcpdump -i ens33 host 224.0.0.18 -n -
负载均衡不工作
# 检查LVS规则 sudo ipvsadm -ln # 检查RS健康状态 curl -I http://10.0.0.13 curl -I http://10.0.0.14