跳转到内容

高可用基础

高可用(High Availability, HA)的目标是消除单点故障,确保服务在部分组件出现问题时仍能继续运行。本文介绍 HA 的核心概念和在 EL 系发行版上常用的实现方案。

高可用是指系统能在约定的时间内提供可用服务的能力。通常用”几个 9”来衡量:

可用性每年允许停机时间
99.9%(三个9)8 小时 45 分钟
99.99%(四个9)52 分钟
99.999%(五个9)5 分钟

当主节点发生故障时,备用节点自动接管服务的过程。分为:

  • 主动-被动(Active-Passive):正常时只有主节点提供服务,备节点待命
  • 主动-主动(Active-Active):所有节点同时提供服务,某节点故障后流量自动分配到其余节点

将流量分发到多台后端服务器,既提高了处理能力,也提供了冗余。

Keepalived 使用 VRRP(虚拟路由冗余协议)在多台服务器之间共享一个虚拟 IP(VIP)。当主节点故障时,VIP 自动漂移到备节点。

在主备两台服务器上都执行:

Terminal window
sudo dnf install keepalived -y
Terminal window
sudo tee /etc/keepalived/keepalived.conf > /dev/null <<'EOF'
global_defs {
router_id LVS_MASTER
script_user root
enable_script_security
}
# 健康检查脚本
vrrp_script check_nginx {
script "/usr/local/bin/check_nginx.sh"
interval 2
weight -20
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0 # 根据实际网卡名称修改
virtual_router_id 51
priority 100 # 主节点优先级较高
advert_int 1
authentication {
auth_type PASS
auth_pass mySecretPass # 主备需一致
}
virtual_ipaddress {
192.168.1.100/24 # 虚拟 IP 地址
}
track_script {
check_nginx
}
# VIP 漂移时执行的通知脚本(可选)
notify_master "/usr/local/bin/notify.sh MASTER"
notify_backup "/usr/local/bin/notify.sh BACKUP"
notify_fault "/usr/local/bin/notify.sh FAULT"
}
EOF
Terminal window
sudo tee /etc/keepalived/keepalived.conf > /dev/null <<'EOF'
global_defs {
router_id LVS_BACKUP
script_user root
enable_script_security
}
vrrp_script check_nginx {
script "/usr/local/bin/check_nginx.sh"
interval 2
weight -20
fall 3
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90 # 备节点优先级较低
advert_int 1
authentication {
auth_type PASS
auth_pass mySecretPass
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
check_nginx
}
notify_master "/usr/local/bin/notify.sh MASTER"
notify_backup "/usr/local/bin/notify.sh BACKUP"
notify_fault "/usr/local/bin/notify.sh FAULT"
}
EOF
sudo tee /usr/local/bin/check_nginx.sh > /dev/null <<'EOF'
#!/bin/bash
# 检查 nginx 是否正常运行
if ! pidof nginx > /dev/null 2>&1; then
# 尝试重启
systemctl start nginx
sleep 2
if ! pidof nginx > /dev/null 2>&1; then
exit 1 # 返回非 0 表示检查失败
fi
fi
exit 0
EOF
chmod +x /usr/local/bin/check_nginx.sh
sudo tee /usr/local/bin/notify.sh > /dev/null <<'EOF'
#!/bin/bash
STATE=$1
HOSTNAME=$(hostname)
DATE=$(date '+%Y-%m-%d %H:%M:%S')
MAILTO="admin@example.com"
echo "[${DATE}] ${HOSTNAME} 切换为 ${STATE}" >> /var/log/keepalived_notify.log
echo "${HOSTNAME} 在 ${DATE} 切换为 ${STATE} 状态" | \
mail -s "[HA 告警] ${HOSTNAME} -> ${STATE}" "$MAILTO"
EOF
chmod +x /usr/local/bin/notify.sh

在主备节点上都执行:

Terminal window
sudo systemctl enable --now keepalived
# 允许 VRRP 协议通过防火墙
sudo firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'
sudo firewall-cmd --reload
Terminal window
# 查看 VIP 绑定情况
ip addr show eth0
# 在主节点上应该能看到虚拟 IP
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
# inet 192.168.1.10/24 ...
# inet 192.168.1.100/24 scope global secondary eth0
# 模拟故障:停止主节点的 keepalived
sudo systemctl stop keepalived
# 在备节点上验证 VIP 是否已漂移过来
ip addr show eth0

HAProxy 是高性能的 TCP/HTTP 负载均衡器,常与 Keepalived 搭配使用。

Terminal window
sudo dnf install haproxy -y
Terminal window
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
sudo tee /etc/haproxy/haproxy.cfg > /dev/null <<'EOF'
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# SSL 相关
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
# 统计页面
listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats admin if LOCALHOST
stats auth admin:YourStatsPassword
# HTTP 前端
frontend http_front
bind *:80
default_backend web_servers
# HTTPS 前端(可选)
frontend https_front
bind *:443 ssl crt /etc/haproxy/certs/site.pem
default_backend web_servers
# 后端服务器池
backend web_servers
balance roundrobin
option httpchk GET /health
http-check expect status 200
server web1 192.168.1.11:80 check inter 5s fall 3 rise 2
server web2 192.168.1.12:80 check inter 5s fall 3 rise 2
server web3 192.168.1.13:80 check inter 5s fall 3 rise 2 backup
EOF
balance roundrobin # 轮询(默认),按顺序分配
balance leastconn # 最少连接,优先分配给连接数最少的后端
balance source # 源地址哈希,同一客户端始终访问同一后端
balance uri # URI 哈希,相同 URI 访问同一后端(适合缓存场景)
Terminal window
# 检查配置文件语法
haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl enable --now haproxy
# 放行端口
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8404/tcp
sudo firewall-cmd --reload

访问 http://服务器IP:8404/stats 查看 HAProxy 统计页面。

典型的高可用负载均衡架构:

VIP: 192.168.1.100
┌─────────────────┐
│ Keepalived │
│ (VRRP 漂移) │
└────────┬────────┘
┌─────────────┴─────────────┐
┌──────┴──────┐ ┌──────┴──────┐
│ HAProxy 1 │ │ HAProxy 2 │
│ (MASTER) │ │ (BACKUP) │
└──────┬──────┘ └──────┬──────┘
│ │
┌──────────┼──────────┐ ┌──────────┼──────────┐
│ │ │ │ │ │
┌──┴──┐ ┌──┴──┐ ┌──┴──┐
│Web 1│ │Web 2│ │Web 3│
└─────┘ └─────┘ └─────┘

两台 HAProxy 服务器通过 Keepalived 共享 VIP,客户端始终访问 VIP。当主 HAProxy 故障时,VIP 漂移到备用节点,实现无感知切换。

Pacemaker/Corosync 是企业级的 HA 集群解决方案,适合管理复杂的多资源集群。

  • Corosync:提供集群通信和成员管理
  • Pacemaker:集群资源管理器,决定资源在哪个节点运行

在所有集群节点上执行:

Terminal window
sudo dnf install pacemaker corosync pcs -y
# pcs 是 Pacemaker/Corosync 的管理工具
Terminal window
# 在所有节点上设置 hacluster 用户密码(需要一致)
sudo passwd hacluster
# 启动 pcs 守护进程
sudo systemctl enable --now pcsd
# 放行防火墙
sudo firewall-cmd --permanent --add-service=high-availability
sudo firewall-cmd --reload

在其中一个节点上操作:

Terminal window
# 认证所有节点
sudo pcs host auth node1 node2 node3 -u hacluster -p YourPassword
# 创建集群
sudo pcs cluster setup mycluster node1 node2 node3
# 启动集群
sudo pcs cluster start --all
sudo pcs cluster enable --all
Terminal window
# 查看集群状态
sudo pcs status
# 禁用 STONITH(测试环境,生产环境必须配置 STONITH 设备)
sudo pcs property set stonith-enabled=false
# 设置当集群丢失法定票数时的策略
sudo pcs property set no-quorum-policy=ignore
# 添加虚拟 IP 资源
sudo pcs resource create VirtualIP ocf:heartbeat:IPaddr2 \
ip=192.168.1.100 \
cidr_netmask=24 \
op monitor interval=30s
# 添加 Nginx 服务资源
sudo pcs resource create WebServer systemd:nginx \
op monitor interval=10s timeout=20s
# 确保 VIP 和 WebServer 运行在同一节点
sudo pcs constraint colocation add WebServer with VirtualIP INFINITY
# 确保 VIP 先于 WebServer 启动
sudo pcs constraint order VirtualIP then WebServer
# 设置资源优先运行在 node1
sudo pcs constraint location WebServer prefers node1=100
Terminal window
# 查看集群详细状态
sudo pcs status --full
# 查看资源配置
sudo pcs resource config
# 查看约束
sudo pcs constraint show
# 手动迁移资源到其他节点
sudo pcs resource move WebServer node2
# 清除迁移约束(让集群恢复自动调度)
sudo pcs resource clear WebServer
# 将节点设为维护模式
sudo pcs node standby node1
# 恢复节点
sudo pcs node unstandby node1
# 清理资源错误状态
sudo pcs resource cleanup WebServer

在 HA 集群中,多个节点可能需要访问同一份数据,这就需要共享存储。

方案说明适用场景
NFS网络文件系统简单共享,非高 I/O 场景
GFS2全局文件系统需要多节点同时读写
DRBD分布式复制块设备主备模式的数据同步
Ceph分布式存储系统大规模集群,需要高可靠性
iSCSI网络块存储SAN 存储接入

NFS 服务器端:

Terminal window
sudo dnf install nfs-utils -y
# 创建共享目录
sudo mkdir -p /data/shared
sudo chown nobody:nobody /data/shared
# 配置导出
sudo tee /etc/exports > /dev/null <<'EOF'
/data/shared 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
EOF
sudo systemctl enable --now nfs-server
sudo exportfs -rav
# 防火墙
sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --permanent --add-service=mountd
sudo firewall-cmd --permanent --add-service=rpc-bind
sudo firewall-cmd --reload

NFS 客户端(集群节点):

Terminal window
sudo dnf install nfs-utils -y
# 挂载
sudo mkdir -p /mnt/shared
sudo mount -t nfs nfs-server:/data/shared /mnt/shared
# 写入 fstab 实现开机自动挂载
echo 'nfs-server:/data/shared /mnt/shared nfs defaults,_netdev 0 0' | \
sudo tee -a /etc/fstab

DRBD 在两台服务器之间实时同步块设备数据,相当于网络 RAID 1:

Terminal window
# 安装 DRBD(需要 ELRepo 源)
sudo dnf install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm -y
sudo dnf install drbd90-utils kmod-drbd90 -y
# 加载内核模块
sudo modprobe drbd

DRBD 的详细配置超出本文范围,但其基本工作模式如下:

┌──────────┐ ┌──────────┐
│ Node 1 │ 网络同步 │ Node 2 │
│ (Primary) │ ←──────→ │(Secondary)│
│ /dev/drbd0│ │/dev/drbd0│
└─────┬────┘ └─────┬────┘
│ │
/dev/sdb1 /dev/sdb1
(本地磁盘) (本地磁盘)
需求推荐方案
Web 服务器冗余Keepalived + Nginx/HAProxy
数据库高可用数据库自身的主从复制 + Keepalived
复杂多资源集群Pacemaker + Corosync
大规模负载均衡HAProxy + Keepalived
数据同步DRBD(两节点)/ Ceph(多节点)