一、 为什么需要“备胎”?理解高可用
想象一下,你运营着一个重要的在线服务,比如一个电商网站。如果承载这个网站的服务器突然宕机了,会发生什么?用户无法访问,订单无法处理,直接意味着经济损失和口碑下降。单台服务器就像独木桥,一旦出问题,整个服务就中断了。
“高可用”就是为了解决这个问题而生的。它的核心思想很简单:消除单点故障。通俗地说,就是给重要的服务器准备一个或多个“备胎”(备用服务器)。当正在工作的主服务器因为硬件故障、网络问题或需要维护而“歇菜”时,备胎能够立刻自动顶上去,接过所有工作,保证服务不间断。这个过程对用户来说几乎是感觉不到的,就像赛车进站换胎一样快速、无缝。
实现高可用的方案有很多,今天我们要聊的是一个非常经典且轻量级的工具——Keepalived。它就像一个智能的“故障切换协调员”,专门负责管理哪台服务器应该对外提供服务。
二、 Keepalived:你的虚拟IP“魔术师”
Keepalived本身是一个用C语言写的开源软件,它的工作原理非常巧妙。它不直接处理你的业务数据(比如网页、数据库),而是通过管理一个虚拟IP地址来实现高可用。
你可以这样理解:
- 你有一个重要的服务,比如网站,它需要被用户通过一个IP地址(例如
192.168.1.100)访问。 - 你准备了两台内容完全一样的服务器,一台叫
Server-A(真实IP: 192.168.1.10),一台叫Server-B(真实IP: 192.168.1.20)。 - 正常情况下,你希望用户访问
192.168.1.100这个地址时,请求由性能更好的Server-A来处理。 - Keepalived 会在这个场景中,让
Server-A主动“霸占”这个192.168.1.100的虚拟IP。对于网络里的其他设备(用户、路由器等)来说,192.168.1.100就是Server-A。 - Keepalived 会在
Server-A和Server-B之间建立一个“心跳”连接,互相确认对方是否还“活着”。 - 一旦
Server-A故障,Server-B上的 Keepalived 检测不到“心跳”了,它就会立刻启动,把虚拟IP192.168.1.100“抢”到自己身上。于是,用户访问192.168.1.100的请求,就自动转到了Server-B。
这个虚拟IP漂移的过程非常快,通常在几秒钟内完成。Keepalived 就是通过这种“抢IP”的机制,实现了服务的自动切换。
三、 手把手搭建Keepalived双机热备
光说原理可能有点抽象,我们直接动手配置一个最常见的双机热备场景。假设我们要为Nginx Web服务器提供高可用。
技术栈声明: 本文所有示例均基于 Linux (CentOS 7/8) 操作系统环境。
首先,在两台服务器上都执行以下步骤:
安装Keepalived:
# 对于CentOS/RHEL系统,使用yum安装 sudo yum install -y keepalived # 对于Ubuntu/Debian系统,使用apt安装 sudo apt-get update sudo apt-get install -y keepalived安装并启动Nginx(示例服务):
sudo yum install -y nginx # CentOS # sudo apt-get install -y nginx # Ubuntu sudo systemctl start nginx sudo systemctl enable nginx在两台服务器上分别创建一个简单的测试页面,以便区分:
# 在 Server-A (192.168.1.10) 上执行 echo "This is Primary Server - A" | sudo tee /usr/share/nginx/html/index.html # 在 Server-B (192.168.1.20) 上执行 echo "This is Backup Server - B" | sudo tee /usr/share/nginx/html/index.html
接下来是核心配置。Keepalived的主配置文件是 /etc/keepalived/keepalived.conf。我们需要分别配置主备两台机器。
在 Server-A (主服务器) 上配置:
sudo vim /etc/keepalived/keepalived.conf
将内容清空,替换为以下配置:
# ==================== 全局定义部分 ====================
global_defs {
# 设置Keepalived的标识,在通知邮件中会用到,可以随意命名
router_id nginx_master
}
# ==================== VRRP实例定义部分 ====================
# 这是核心配置,定义了一个VRRP组(虚拟路由冗余协议组)
vrrp_instance VI_1 {
# 指定本机在此VRRP组中的角色。MASTER表示主服务器
state MASTER
# 指定用于VRRP通信的网络接口,请根据你服务器的实际网卡名修改,常见的有ens33, eth0等
# 使用 `ip addr` 命令查看你的网卡名称
interface ens33
# 虚拟路由ID。同一个VRRP组内的所有机器,这个ID必须完全相同,范围1-255
virtual_router_id 51
# 本机的优先级。MASTER的优先级应该比BACKUP高,范围1-254
priority 100
# VRRP通告间隔,单位秒。主备之间通过这个频率发送心跳包
advert_int 1
# ==================== 认证部分 ====================
# 主备之间通信的认证,防止非法设备加入VRRP组
authentication {
# 认证方式,PASS表示简单密码认证
auth_type PASS
# 认证密码,同一个VRRP组内的所有机器密码必须相同
auth_pass 1111
}
# ==================== 虚拟IP地址部分 ====================
# 这是最关键的部分!定义需要被漂移的虚拟IP地址
virtual_ipaddress {
# 可以定义多个虚拟IP,每行一个。这里我们定义了一个 192.168.1.100
# 注意:这个IP必须和你的物理IP在同一个网段,且未被其他设备占用
192.168.1.100
}
}
在 Server-B (备服务器) 上配置:
配置文件路径相同,内容大部分也相同,只有几个关键参数需要修改:
# ==================== 全局定义部分 ====================
global_defs {
router_id nginx_backup # 标识改为backup以示区分
}
# ==================== VRRP实例定义部分 ====================
vrrp_instance VI_1 {
# 角色改为BACKUP
state BACKUP
interface ens33 # 网卡名,确保和主服务器一致或根据实际情况修改
virtual_router_id 51 # 必须和主服务器相同!
# 优先级设置为比主服务器低。当主服务器恢复时,优先级高的会重新抢占为MASTER
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111 # 密码必须和主服务器相同!
}
virtual_ipaddress {
192.168.1.100 # 虚拟IP必须和主服务器相同!
}
}
配置完成后,在两台服务器上启动Keepalived服务,并设置开机自启:
sudo systemctl start keepalived
sudo systemctl enable keepalived
检查服务状态和虚拟IP是否绑定成功:
# 查看Keepalived运行状态
sudo systemctl status keepalived
# 查看网卡信息,在MASTER服务器上应该能看到虚拟IP (192.168.1.100)
ip addr show ens33
# 你会看到类似这样的输出,除了物理IP,还会多出一个 `192.168.1.100` 的IP
# 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
# link/ether 00:0c:29:xx:xx:xx brd ff:ff:ff:ff:ff:ff
# inet 192.168.1.10/24 brd 192.168.1.255 scope global noprefixroute dynamic ens33
# valid_lft 1234sec preferred_lft 1234sec
# inet 192.168.1.100/32 scope global ens33 <-- 这就是漂移过来的虚拟IP!
# valid_lft forever preferred_lft forever
现在,你可以打开浏览器,访问 http://192.168.1.100,应该会看到来自 Server-A 的页面 “This is Primary Server - A”。
进行故障模拟测试:
- 手动停止
Server-A上的 Keepalived 服务:sudo systemctl stop keepalived。 - 等待几秒钟(advert_int 设置的时间),然后在
Server-B上执行ip addr show ens33,你会发现虚拟IP192.168.1.100已经出现在Server-B的网卡上了。 - 此时再访问
http://192.168.1.100,页面会变成Server-B的 “This is Backup Server - B”。服务切换成功! - 重新启动
Server-A的 Keepalived:sudo systemctl start keepalived。由于Server-A的优先级 (100) 高于Server-B(90),虚拟IP又会自动漂移回Server-A。
四、 进阶玩法:用脚本监控真实服务
上面的基础配置只监控了Keepalived进程本身和网络。如果服务器本身没宕机,但上面运行的关键服务(比如Nginx、MySQL)自己挂掉了怎么办?用户访问虚拟IP,请求到了服务器,但服务不响应,问题依然没解决。
这就需要用到Keepalived的另一个强大功能:自定义监控脚本。Keepalived可以定期执行我们写的脚本,通过脚本的返回值来判断服务器是否“健康”。如果脚本检测失败(返回非0),即使Keepalived进程还在,它也会主动降低本机优先级,或者直接执行故障切换。
让我们来增强配置,增加对Nginx进程的监控:
首先,在两台服务器上创建监控脚本:
sudo vim /etc/keepalived/check_nginx.sh
写入以下内容:
#!/bin/bash
# Nginx健康检查脚本
# 返回值:0 表示健康,1 表示不健康
# 检查Nginx主进程是否存在。`pgrep -x nginx` 会查找精确名为‘nginx’的进程
# 如果进程存在,该命令返回0(成功),否则返回非0
if pgrep -x "nginx" > /dev/null
then
# 进程存在,脚本返回0,告诉Keepalived“我很健康”
exit 0
else
# 进程不存在,尝试重启一次Nginx(可选,根据你的策略决定)
# systemctl restart nginx
# 等待2秒再看是否启动成功
# sleep 2
# if pgrep -x "nginx" > /dev/null; then exit 0; fi
# 这里我们选择简单处理:检测失败就直接返回1,触发Keepalived切换
exit 1
fi
给脚本添加执行权限:
sudo chmod +x /etc/keepalived/check_nginx.sh
然后,修改两台服务器的 keepalived.conf 文件,在 vrrp_instance VI_1 { 配置块内部,virtual_ipaddress { 部分之前,添加以下配置:
# ==================== 健康检查脚本部分 ====================
# 定义追踪脚本,用于监控真实服务的状态
track_script {
# 引用下面定义的脚本块名称
chk_nginx
}
接着,在配置文件的最末尾(在 vrrp_instance 块的外面),添加新的配置块来定义这个脚本:
# ==================== 定义健康检查脚本 ====================
vrrp_script chk_nginx {
# 指定要执行的脚本路径
script "/etc/keepalived/check_nginx.sh"
# 脚本执行的间隔时间,单位秒
interval 2
# 如果脚本连续失败多少次,才认为服务真的故障了(防止网络抖动误判)
fall 2
# 如果脚本连续成功多少次,才认为服务恢复
rise 2
# 脚本执行的超时时间
timeout 2
# 这个参数很重要!如果脚本执行失败(返回非0),本机的优先级会减去这个值
# 比如主服务器 priority 100,减去20后变成80,就低于备机的90了,从而触发切换
weight -20
}
现在,即使 Server-A 的Keepalived和系统都正常,但如果你手动停止Nginx服务(sudo systemctl stop nginx),等待几秒后,虚拟IP也会自动漂移到 Server-B。这就实现了对应用层服务的高可用保护。
五、 应用场景、优缺点与注意事项
应用场景:
- Web服务器高可用: 如本文示例,为Nginx、Apache等提供故障转移。
- 负载均衡器高可用: 常用于LVS、HAProxy等负载均衡软件的前端,确保流量入口不中断。
- 数据库高可用: 可以为MySQL主从复制中的“主库”提供一个虚拟IP,配合MHA等工具实现主库故障切换。
- 企业内网服务: 为内部DNS、DHCP、文件共享等关键基础设施提供冗余。
技术优点:
- 简单轻量: 配置相对简单,资源占用小。
- 稳定可靠: 项目成熟,在大量生产环境中得到验证。
- 切换快速: 基于VRRP协议,故障切换通常在秒级完成。
- 功能灵活: 支持自定义健康检查脚本,能与各种服务集成。
技术缺点与局限:
- 脑裂问题: 这是最需要注意的问题!如果主备服务器之间的“心跳”网络中断,但两台服务器本身都正常运行,它们会都认为对方挂了,从而都去抢占虚拟IP,导致出现两个“主服务器”,服务混乱。解决脑裂需要配置额外的检测线路(如串口线、多块网卡绑定不同网络)或使用第三方仲裁脚本。
- 资源浪费: 备机在平时不处理业务(除非你做成主主或负载均衡模式),存在资源闲置。
- 数据同步非其职责: Keepalived只负责IP漂移,不负责两台服务器之间业务数据的同步(如网页文件、数据库数据)。你必须自行通过Rsync、DRBD、数据库复制等技术保证数据一致性。
- 单活: 基础的主备模式是单活的,只有一台机器对外服务。
重要注意事项:
- 确保虚拟IP可用: 配置的虚拟IP必须和物理网络在同一网段,且未被其他设备静态占用。
- 防火墙配置: VRRP协议使用IP协议号112(或组播地址224.0.0.18)。务必在主备服务器的防火墙上放行相关通信,否则“心跳”无法传递。
# 例如,使用firewalld sudo firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --permanent sudo firewall-cmd --reload - 网络稳定性: 主备服务器之间的网络链路质量至关重要,不稳定的网络会引发频繁的切换或脑裂。
- 日志监控: 养成查看
/var/log/messages或journalctl -u keepalived日志的习惯,里面记录了状态切换、脚本执行结果等关键信息。
六、 总结
Keepalived是一个以“虚拟IP漂移”为核心思想的经典高可用工具。它就像一位忠诚的哨兵,守护着你的服务入口。通过简单的配置,就能为许多无状态或配合有数据同步方案的服务,搭建起一道可靠的高可用防线。
它的核心价值在于简单、高效地解决了网络层面的单点故障。对于刚接触高可用的朋友来说,从Keepalived入手是一个非常好的选择,它能帮你建立起高可用的基本概念。
当然,它并非银弹。面对复杂的应用、有状态的服务、大规模集群,你可能需要结合LVS、HAProxy、以及更高级的集群管理软件如Kubernetes等来构建更完善的架构。但无论如何,理解并掌握Keepalived,都是你运维和架构知识体系中坚实而有用的一块拼图。
评论