零、keepalived架构和原理
1、什么是keepalived
Keepalived 是一款基于 VRRP (Virtual Router Redundancy Protocol,虚拟路由冗余协议) 实现的高可用 (HA, High Availability)解决方案。它最初是为 LVS(Linux Virtual Server)负载均衡软件设计的,用来监控集群中各个服务节点的状态,但因为其轻量、稳定,现在常用于 Nginx、HAProxy 等服务的双机热备高可用。

Keepalived 的核心工作可以总结为两件事:健康检查 (Health Checking)和故障转移 (Failover)。
核心协议:VRRP 的运作机制,VRRP 协议是为了解决静态路由单点故障而设计的。Keepalived 完美的实现了这个协议:
2、keepalived技术原理
虚拟 IP(VIP):在对外提供服务时,多台 Keepalived 服务器会虚拟出一个共同的 IP(即 VIP)。客户端所有的请求都直接访问这个 VIP。
2.1、主备竞选(Master/Backup)
集群中的节点通过配置的优先级(Priority)来决定身份。优先级最高的节点成为 Master(主节点),其余为 Backup(备节点)。
2.2、心跳机制
Master 节点会定期(默认每秒)向局域网内发送 VRRP 组播报文(组播地址通常为 224.0.0.18),通告自己还活着。
2.3、故障接管(ARP 欺骗)
当 Backup 节点在连续 3 个周期内没有收到 Master 的心跳包,就会认为 Master 宕机。此时,优先级最高的 Backup 会自动升级为 Master,并向局域网发送 免费 ARP 报文(Gratuitous ARP),通知交换机更新 MAC 地址映射,将流向 VIP 的流量瞬间引向自己。整个切换过程通常在数秒内完成,对客户端几乎透明。
一、virtualbox环境准备
| 主机名 | IP地址 | 系统类型 | 网卡名称 | 网卡类型 | 混杂模式 |
|---|---|---|---|---|---|
| keepalived-master | 172.16.10.11(VIP:172.16.10.10) | Ubuntu 22.04.5 LTS | enp0s9 | 内部网络(intnet2) | 拒绝 |
| keepalived-backup | 172.16.10.12 (VIP:172.16.10.10) | Ubuntu 22.04.5 LTS | enp0s9 | 内部网络(intnet2) | 拒绝 |
| client | 172.16.10.1 | Ubuntu 22.04.5 LTS | enp0s9 | 内部网络(intnet2) | 拒绝 |
二、安装配置keepalived
1、安装keepalived
bash
sudo apt-get install keepalived #在keepalived-master、keeepalived-backup两个节点执行安装命令
修改配置文件/etc/keepalived/keepalived.conf ,若没有则可以直接创建
2、在keepalived-master节点配置为主节点
bash
sudo nano /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER # 角色:主节点
interface enp0s9 # 替换为你的网卡名
virtual_router_id 1 # 虚拟路由ID,主备必须一致 (1-255)
priority 100 # 优先级,主节点要高于备节点
advert_int 1 # 心跳检测间隔(秒)
authentication {
auth_type PASS
auth_pass 123456 # 认证密码,主备必须一致
}
virtual_ipaddress {
172.16.10.10/24 # 虚拟IP(VIP),替换为你的VIP
}
}
3、在keepalived-backup节点配置为主节点
bash
sudo nano /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER # 角色:备节点
interface enp0s9 # 替换为你的网卡名
virtual_router_id 1 # 虚拟路由ID,主备必须一致 (1-255)
priority 90 # 优先级,主节点要高于备节点
advert_int 1 # 心跳检测间隔(秒)
authentication {
auth_type PASS
auth_pass 123456 # 认证密码,主备必须一致
}
virtual_ipaddress {
172.16.10.10/24 # 虚拟IP(VIP),替换为你的VIP
}
}
三、keepalived主备ping测试
1、keepalived-master主节点生效

在keepalived-master主节点查看虚拟地址是否生效,可以看到在主节点现有网卡的配置下生成了新的virtual IP:172.16.10.10/24。
bash
ip s s | grep enp0s9 #主备节点同时查看网卡地址

在172.16.140.1上ping 172.16.10.10,然后在keepalived-master和keepalived-backup上面使用tcpdump抓取icmp数据包,可以看到在主节点抓到了icmp的数据包,备节点没有抓到。
bash
ping -c 5 172.16.10.10 #client主机执行此命令
sudo tcpdump -i enp0s9 icmp -nv # 主备节点enp0s9网卡下抓取icmp数据包

2、keepalived-backup备节点生效
keepalived-master节点故障后,VIP:172.16.10.10漂移到keepalived-backup节点,继续使用tcpdump抓包观察,现在是备节点在响应主机client发出的请求。

bash
ip s s | grep enp0s9 #主备节点同时查看网卡地址

bash
ping -c 5 172.16.10.10 #client主机执行此命令
sudo tcpdump -i enp0s9 icmp -nv # 主备节点enp0s9网卡下抓取icmp数据包

四、在keepalived节点之前添加一台防火墙进行测试
场景:若在两个keepalived节点之前加一台防火墙,此时要配置访问白名单策略,要如何配置呢? 是填写真实目标IP地址、还是VIP、还是真实IP和VIP都添加呢?

1、virtualbox环境准备
| 主机名 | IP地址 | 系统类型 | 网卡名称 | 网卡类型 | 混杂模式 |
|---|---|---|---|---|---|
| keepalived-master | 172.16.10.11(VIP:172.16.10.10) | Ubuntu 22.04.5 LTS | enp0s9 | 内部网络(intnet2) | 拒绝 |
| keepalived-backup | 172.16.10.12(VIP:172.16.10.10) | Ubuntu 22.04.5 LTS | enp0s9 | 内部网络(intnet2) | 拒绝 |
| client | 172.16.10.1 | Ubuntu 22.04.5 LTS | enp0s9 | 内部网络(intnet1) | 拒绝 |
| iptables | 透明网桥,无需配置IP地址 | Ubuntu 22.04.5 LTS | enp0s9、enp0s10 | 内部网络(intnet2)、内部网络(intnet2) | 全部允许 |
2、主机iptables配置二层透明网桥
2.1、安装网桥管理工具和iptables持久化工具
bash
sudo apt install bridge-utils iptables iptables-persistent #bridge-utils 提供网桥管理工具;iptables-persistent 用于持久化防火墙规则
2.2、创建网桥
bash
# 1. 创建网桥
sudo brctl addbr br0
# 2. 将两块网卡(如enp0s8和enp0s9)加入网桥
# 请将下面的接口名替换为你系统实际的名称
sudo brctl addif br0 enp0s8
sudo brctl addif br0 enp0s9
# 3. 启用网桥和网卡
sudo ip link set br0 up
sudo ip link set enp0s8 up
sudo ip link set enp0s9 up
# 4、将网卡、网桥配置持久化
sudo nano /etc/netplan/00-network.yaml
network:
version: 2
renderer: networkd
ethernets:
enp0s9:
dhcp4: no
enp0s10:
dhcp4: no
bridges:
br0:
interfaces: [enp0s9,enp0s10]
dhcp4: no
parameters:
stp: false
2.3、启用桥接流量防火墙过滤
bash
1、# 手动加载内核模块 br_netfilter
sudo modprobe br_netfilter #此命令是临时生效,系统重启后需要重新执行此命令
2、# 启用iptables对桥接流量的处理
sudo sysctl net.bridge.bridge-nf-call-iptables=1
# 为了让规则永久生效,可以将以下配置写入 /etc/sysctl.conf
#值 = 0(默认):网桥二层转发流量跳过 iptables,防火墙不拦截、不记录;
#值 = 1:所有经过网桥转发的二层数据包,强制送入 iptables 过滤链(FORWARD),防火墙规则才能拦截 / 放行 ICMP、TCP、UDP 流量。
3、#实时加载
sysctl -p
3、ping测试
3.1、iptables节点配置防火墙规则
bash
#修改FORWARD链的默认处置动作为DROP
sudo iptables -P FORWARD DROP
#添加client访问keepalived-master和keepalived-backup的策略
sudo iptables -A FORWARD -s 172.16.10.10 -d 172.16.10.1 -p icmp -j ACCEPT
sudo iptables -A FORWARD -s 172.16.10.1 -d 172.16.10.10 -p icmp -j ACCEPT
#规则持久化
sudo netfilter-persistent save
#查看防火墙规则
sudo iptables -nvL -t filter

3.2、ping VIP测试
bash
#client节点上执行
ping 172.16.10.10
#keepalived-master、keepalived-backup节点执行抓包
sudo tcpdump -i enp0s9 icmp -nv
#iptables 网桥br0下抓包
sudo tcpdump -i br0 icmp -nv

结果:
| 主机 | 是否抓到数据包 |
|---|---|
| client | N/A |
| iptables | 是 |
| keepalived-master | 是 |
| keepalived-backup | 否 |
3.3、ping 真实IP测试
bash
#client节点上执行
ping 172.16.10.11
#keepalived-master、keepalived-backup节点执行抓取icmp但是不抓取vrrp协议
sudo tcpdump -i enp0s9 icmp and not vrrp-nv
#iptables 网桥br0下抓包
sudo tcpdump -i br0 icmp -nv

结果:
| 主机 | 是否抓到数据包 |
|---|---|
| client | N/A |
| iptables | 是 |
| keepalived-master | 否 |
| keepalived-backup | 否 |
3.4、结论
根据iptables策略和tcpdump抓包结果来看,二层透明防火墙只需要开通针对VIP的白名单策略即可。
参考:
1、virtualbox 网卡"内部网络"的三种模式

内部网络:内部网络无法与主机和互联网通信。
- 拒绝:网卡只接收目标 MAC 为本网卡 MAC的单播、本机广播;其他 MAC 报文直接丢弃。。
- 允许虚拟电脑:虚拟机内操作系统只能接收发给自身的单播、广播;同广播域其他主机的单播报文不会递交给虚拟机内核。
- 全部允许:网卡把链路上所有二层报文(所有单播、组播、广播)全部转发给虚拟机操作系统内核。