Keepalived
Keepalived 是什么(高可用)
Keepalived 是一个用于实现 高可用 性(High Availability, HA)的服务,是一款基于 VRRP 协议的高可用软件,常用于主备切换和虚拟IP漂移,在服务故障时自动实现故障转移。
Keepalived 的核心功能
功能 | 说明 |
---|---|
VRRP | Virtual Router Redundancy Protocol,实现主备切换,保障VIP持续可用 |
健康检查(check) | 定时检测真实服务(如 Nginx、LVS、MySQL)是否存活 |
VIP 漂移 | 将一个虚拟 IP 绑定到当前健康的主节点上,故障时自动转移到备节点 |
结合 LVS | 通常与 LVS(Linux Virtual Server)一起部署,提供高可用负载均衡 |
安装 Keepalived
sudo apt-get update
sudo apt-get install -y keepalived
查看是否安装成功
keepalived -v
开启开机自启动:
sudo systemctl enable keepalived
Keepalived 常用命令
开启开机自启动:sudo systemctl enable keepalived
禁用开机自启动:sudo systemctl disable keepalived
开启服务:sudo systemctl start keepalived
关闭服务:sudo systemctl stop keepalived
重启服务:sudo systemctl restart keepalived
查看状态:sudo systemctl status keepalived
编辑配置文件
sudo vim /etc/keepalived/keepalived.conf
配置文件参数说明
# 定义一个 VRRP 实例,VI_1 是自定义的实例名称,每一个实例代表一个高可用虚拟路由组。
vrrp_instance VI_1 {
## 指定该节点的初始角色,MASTER:主节点,正常情况下负责绑定虚拟IP(VIP)。BACKUP:备用节点,在主节点不可用时接管 VIP。
# Keepalived 自动通过优先级判断主备,不是硬编码的主备,所以这个只是初始角色。
state MASTER
## 指定绑定 VIP 的网络接口(网卡名),例如 eth0、ens33、enp0s3 等。使用 ip a 查看当前系统的网卡名。
interface ens33
## 虚拟路由器的 ID,用于识别一个 VRRP 实例的组。所有参与该 VRRP 实例(主备)的服务器必须一致。范围:0~255,确保不同服务之间不要冲突。
virtual_router_id 51
## 指定该节点的优先级。数字越大,优先级越高。主节点应配置较高的值(如 100),备用节点配置较低(如 90)。当优先级高的节点恢复时,会自动抢占 VIP
priority 100
## 指定 VRRP 广播间隔时间(秒)。主节点每隔指定的秒发送一次心跳包,默认是 1 秒,一般无需修改
advert_int 1
## 禁用抢占
# nopreempt # 即使此节点优先级更高也不抢占 MASTER
## 延迟抢占 VIP
# 主节点恢复后,希望它稳定运行一段时间再接管 VIP,防止主节点频繁重启时反复抢占,导致服务中断
# nopreempt 和 preempt_delay 不能同时使用。如果两者都写了,以 nopreempt 为准
# preempt_delay 10 # 恢复后等待10秒才尝试抢占 MASTER
## 状态通知脚本(可选)
# notify_master "/path/to/script" # 成为 MASTER 时执行脚本
# notify_backup "/path/to/script" # 成为 BACKUP 时执行脚本
# notify_fault "/path/to/script" # 出现故障时执行脚本
# notify "/path/to/script" # 所有状态变更时都执行的统一脚本
## 本机实际 IP 地址(作为 VRRP 包发送源 IP)
unicast_src_ip 192.168.189.135
## 用于将 Keepalived 的 VRRP 心跳通信改为“单播”(Unicast)模式。不配置的话默认的是“组播”(Multicast)模式。云服务器(如阿里云、腾讯云)中,出于安全限制,组播通常被禁用或不可用。
unicast_peer {
192.168.189.136
192.168.189.137
}
## 用于设置主备之间的认证信息
authentication {
## 认证类型,一般用 PASS(明文密码)
auth_type PASS
## 认证密码(主备节点必须保持一致)
auth_pass 123456
}
## 指定一个或多个虚拟IP(VIP)。VIP 是客户端访问的目标地址,当主节点故障,VIP 会自动漂移到备节点
virtual_ipaddress {
192.168.189.100 # 虚拟IP 1,例如用于 web 服务A
192.168.189.101 # 虚拟IP 2,例如用于 web 服务B
192.168.189.102 # 虚拟IP 3,例如用于 mysql 服务
}
}
配置文件实操
- 主节点:192.168.189.135,优先级为 100
- 备节点:192.168.189.136,优先级为 90
- 第三节点:192.168.189.137,优先级为 80
这些参数必须在所有节点一致:vrrp_instance、virtual_router_id、advert_int、authentication、virtual_ipaddress
1. 主节点(192.168.189.135)配置
sudo vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
unicast_src_ip 192.168.189.135
unicast_peer {
192.168.189.136
192.168.189.137
}
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.189.100
}
}
重启 keepalived
sudo systemctl restart keepalived
2. 备节点(192.168.189.136)配置
sudo vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
unicast_src_ip 192.168.189.136
unicast_peer {
192.168.189.135
192.168.189.137
}
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.189.100
}
}
重启 keepalived
sudo systemctl restart keepalived
3. 第三节点(192.168.189.137)配置
sudo vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 80
advert_int 1
unicast_src_ip 192.168.189.137
unicast_peer {
192.168.189.135
192.168.189.136
}
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.189.100
}
}
重启 keepalived
sudo systemctl restart keepalived
测试是否配置成功
测试步骤:查看VIP在哪个节点上?发现在主节点上,把主节点关闭后,发现VIP漂移到备用节点上了
1. 在主节点(192.168.189.135)运行:
ip a | grep 192.168.189.100
输入如下内容,表示 VIP 被绑定到此节点
inet 192.168.189.100/32 scope global ens33
2. 关闭主节点的 Keepalived 服务:
sudo systemctl stop keepalived
3. 在备节点(192.168.189.136)运行:
ip a | grep 192.168.189.100
VIP 会自动漂移到备节点。
LVS
LVS 是什么(负载均衡)
LVS(Linux Virtual Server)是一个运行在 Linux 内核中的负载均衡器,它可以将大量的请求分发到多台后端服务器上,实现网站或服务的 Linux 内核级负载均衡。
LVS 的特点
特性 | 说明 |
---|---|
高性能 | 内核级处理,效率非常高,适合大规模并发 |
稳定可靠 | 运行在 Linux 内核中,成熟稳定 |
支持多种调度算法 | 如轮询(RR)、最少连接(LC)、加权等 |
透明性高 | 客户端无需感知后端服务器变化 |
扩展性强 | 可轻松添加或移除后端服务器 |
LVS 的负载均衡算法
算法名 | 全称 | 说明 |
---|---|---|
rr | Round Robin | 轮询,每台服务器轮流处理请求,适用于服务器性能差不多的情况。 |
wrr | Weighted Round Robin | 加权轮询,根据服务器权重分配请求,权重大者分配更多请求。 |
lc | Least Connection | 最少连接数优先,当前连接最少的服务器优先接收新请求。 |
wlc | Weighted Least Connection | 加权最少连接,在连接数基础上再加权,适用于连接时长差异较大的情况。 |
lblc | Locality-Based Least Connection | 基于本地性和最少连接数,适用于缓存服务器,提高命中率。 |
lblcr | Locality-Based Least Connection with Replication | 类似于 lblc,但支持多个复制服务器。 |
dh | Destination Hashing | 目的地址哈希,将请求根据目标 IP 哈希分配,适合源地址多样化场景。 |
sh | Source Hashing | 源地址哈希,将同一客户端的请求始终发往同一后端,适用于会话保持。 |
LVS 负载均衡的转发工作模式
模式 | 简介 | 优点 | 缺点或要求 |
---|---|---|---|
NAT | LVS 作为网关,所有流量都经过 LVS,再转发给后端 | 配置简单 | LVS 成为瓶颈,占用带宽 |
DR(Direct Routing) | 请求从 LVS 发出,但响应由后端服务器直接返回客户端 | 性能高,响应快 | 需要所有机器在同一网段,后端需绑定 VIP(不响应 ARP) |
TUN(IP隧道) | LVS 和后端服务器可以跨网段 | 跨地域部署可用 | 后端服务器需支持 IP 隧道 |
安装 LVS
sudo apt-get update
sudo apt-get install -y ipvsadm
编辑配置文件
sudo vim /etc/keepalived/keepalived.conf
配置文件参数说明
LVS 一般和 keepalived 搭配使用,LVS 配置写在 keepalived 的配置文件中
## 定义一个 LVS 虚拟服务(VIP + 端口),192.168.189.100 是虚拟 IP(VIP),80 是端口。
virtual_server 192.168.189.100 80 {
## 每 5 秒执行一次健康检查。值越小,检测频率越高,发现异常越快,但系统负担也会稍高。
delay_loop 5
## 指定使用什么 负载均衡算法
lb_algo wrr
## 指定负载均衡的转发工作模式
lb_kind DR
## 保持客户端连接的会话粘性,单位是秒,同一客户端在 60 秒内的请求都发送到同一台后端服务器。
persistence_timeout 60
## 该虚拟服务处理的是 TCP 协议的请求(如 HTTP、HTTPS、MySQL等)
protocol TCP
## 定义一台真实后端服务器,监听 IP 为 192.168.189.135,端口 80。
real_server 192.168.189.135 80 {
## 权重为 3(配合上面的 wrr 算法使用),3:表示这个服务接收3个请求
weight 3
## 健康检查(TCP 方式)
TCP_CHECK {
## 每次 TCP 连接检测最多等待 3 秒,3秒后就连接超时
connect_timeout 3
## 最多尝试连接 3 次
nb_get_retry 3
## 重试前延迟时间,每次失败后等待 2 秒再重试
delay_before_retry 2
## 检查端口(默认是 real_server 的端口)
connect_port 80
}
}
## 定义一台真实后端服务器,监听 IP 为 192.168.189.136,端口 80。
real_server 192.168.189.136 80 {
## 权重为 2(配合上面的 wrr 算法使用),2:表示这个服务接收2个请求
weight 2
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 2
connect_port 80
}
}
## 定义一台真实后端服务器,监听 IP 为 192.168.189.137,端口 8080。
real_server 192.168.189.137 8080 {
weight 1
# 健康检查(HTTP GET 请求)
HTTP_GET {
url {
## 检查的路径,例如 /healthz,你需要在该服务器上部署这个路径返回 200,例如:GET http://<real_server_ip>:80/healthz
path /healthz
## 响应体的 MD5 值,匹配这个 hash 才算健康,防止假回包。d41d8cd98f00b204e9800998ecf8427e:是空字符串("")的 MD5 值,即后端什么也不返回时的 MD5 值,这个值可以自定义
digest d41d8cd98f00b204e9800998ecf8427e
}
## 每次 TCP 连接检测最多等待 3 秒,3秒后就连接超时
connect_timeout 3
## GET 请求失败后重试次数
nb_get_retry 3
## 重试前延迟时间,每次失败后等待 2 秒再重试
delay_before_retry 2
## 请求的端口
connect_port 8080
}
}
}
HTTP_GET 健康检查 Restful API 示例:
1. 定义一个 get 接口
@RestController
public class HealthCheckController {
@GetMapping("/healthz")
public String healthCheck() {
return "AAABBBCCC";
}
}
2. 计算返回值的 MD5(用于 digest)
现在后端返回的是 "AAABBBCCC",你可以在 Linux 或 macOS 终端中执行:
echo -n "AAABBBCCC" | md5sum
输出:6207b5df5796e963410d3bc4b6a4218b -
把这个值配置在 HTTP_GET 健康检查的 digest 属性中,如下:
HTTP_GET {
url {
path /healthz
digest 6207b5df5796e963410d3bc4b6a4218b
}
......
}