6.15 Linux 高可用集群——Keepalived 与 etcd

预计阅读时间:18 分钟

📖 目录

学习目标

读完本章后,你将能够:

  • 理解高可用的核心指标与关键组件
  • 配置 Keepalived + VRRP 实现 VIP 主备漂移
  • 搭建 etcd 三节点集群并掌握 Raft 共识原理
  • 使用 DRBD 配置块设备级数据同步复制
  • 认识 Pacemaker/Corosync 集群资源管理器体系
  • 识别并防范脑裂(split-brain)场景

核心知识

概念一句话定义典型工具
高可用(HA)通过冗余消除单点故障,故障时业务自动接管Keepalived / Pacemaker
VRRP虚拟路由冗余协议,多台路由器共享一个虚拟 IPKeepalived
VIP 漂移虚拟 IP 在主备节点间自动迁移Keepalived + VRRP
Raft 共识通过领导者选举和日志复制实现分布式一致性etcd
DRBD块设备级别的实时数据同步("网络 RAID-1")drbd-utils
脑裂集群节点同时认为自己是主,各自持有资源仲裁 / STONITH
资源编排集群中服务/存储/IP 等资源的生命周期管理Pacemaker + Corosync
Fencing隔离故障节点,防止其干扰集群STONITH / IPMI

知识关联

原理讲解

为什么高可用需要脑裂防护

脑裂(Split-brain)是高可用集群最危险的故障模式。当心跳链路中断(网络分区、交换机故障)时,分区两侧的节点都认为对方已死,各自升主并持有同一 VIP 或资源。对于无状态服务(如 Web 负载均衡器),脑裂可能导致客户端流量被分散到两个节点,但不会造成数据损坏。对于有状态服务(如数据库),脑裂可能导致双写——两个节点同时接受写入,数据不一致,恢复时必须人工解决冲突,甚至丢失数据。因此,脑裂防护是高可用设计中不可或缺的一环:冗余心跳降低误判概率、仲裁机制确保只有一个分区能获得 quorum、Fencing 强制隔离故障节点。

Raft 共识算法如何工作

Raft 是 etcd 使用的分布式一致性算法,设计目标是"易于理解"(相比 Paxos)。Raft 将节点分为三种角色:Leader(处理所有写入,将日志复制到 Follower)、Follower(被动接收日志复制,投票选举 Leader)、Candidate(选举超时后发起新一轮选举)。核心机制是"多数派(Quorum)"——任何决策需要超过半数节点同意。例如 3 节点集群需要 2 票,5 节点集群需要 3 票。Leader 选举流程:Follower 在选举超时后变为 Candidate,递增 Term(任期号),向所有节点发送 RequestVote RPC;获得多数票的 Candidate 成为新 Leader。日志复制流程:Leader 将客户端请求追加到本地日志,然后并行发送 AppendEntries RPC 给所有 Follower;多数节点确认后 Leader 提交日志并应用状态机,Follower 随后提交。这种"日志复制 + 多数派确认"确保了强一致性——只要多数节点存活,集群就能正常服务。

Keepalived vs Pacemaker 选型决策

Keepalived 和 Pacemaker 代表了两种不同复杂度的高可用方案。Keepalived 基于 VRRP 协议,设计目标是"简单、可靠、秒级切换"——两节点通过共享 VIP 实现主备,track_script 监控服务健康状态,脚本失败触发 VIP 漂移。其优势是配置简单(一个 conf 文件)、切换快(秒级)、无外部依赖。Pacemaker + Corosync 是完整的集群资源管理器,支持多节点、资源组、约束体系(共置/顺序/位置)、Fencing 隔离——适合数据库等有状态服务的高可用。其优势是功能完整、支持复杂依赖关系、可扩展到数十节点。选型原则:无状态服务主备用 Keepalived,有状态服务或多资源编排用 Pacemaker。

VRRP 协议与 VIP 漂移

VRRP 将多台物理路由器组成一个虚拟路由器组,共享一个虚拟 IP(VIP)和一个虚拟 MAC。组内选举 MASTER 负责响应 VIP 的流量,BACKUP 节点监听 MASTER 的 advertisement 报文。若连续 advert_int × 3 秒未收到 MASTER 的心跳,BACKUP 自动升为 MASTER 并接管 VIP——整个过程对客户端透明。

Keepalived 在 VRRP 之上增加了健康检查脚本(track_script):脚本失败时本节点优先级降低,触发 VIP 重选。这意味着即使节点存活但服务已死,VIP 也会漂移——这是"高可用"而非"高存活"的关键区别。

Raft 共识算法

etcd 基于 Raft 算法在分布式节点间达成一致。Raft 将节点角色分为三种:

  • Leader(领导者):处理所有客户端写入,将日志复制到 Follower
  • Follower(追随者):被动接收 Leader 的日志复制,投票选举 Leader
  • Candidate(候选者):选举超时后发起新一轮领导者选举

Raft 使用多数派(quorum)原则:只要集群中超过半数的节点可用,集群就能正常服务。3 节点集群容忍 1 台故障,5 节点集群容忍 2 台故障。

DRBD 同步原理

DRBD 在 Linux 块设备层实现实时复制。主节点(Primary)的每次块写入通过 TCP 发送到备节点(Secondary),备节点写入本地磁盘后才向主节点返回确认(同步模式)。应用层完全感知不到底层是远程存储——对 /dev/drbd0mkfs、挂载、读写,感觉就像操作本地磁盘。

脑裂的成因与仲裁机制

脑裂发生的根本原因是心跳链路中断(网络分区、交换机故障、内核 hang)。分区两侧的节点都认为对方已死,各自升主并持有同一 VIP 或资源。后果包括数据不一致、服务冲突、甚至双写导致数据损坏。

解决方案分三个层次:

  1. 冗余心跳:同时使用独立网卡 + 串口线,降低误判概率
  2. 仲裁(Quorum):引入第三方见证节点(如 etcd、SCSI-3 持久预留 PR)
  3. Fencing:故障节点被强制隔离(STONITH — 通过 IPMI 远程关机或断开存储)

Pacemaker / Corosync 体系

Keepalived 适合简单主备场景。当集群规模超过 2 节点、或需要管理复杂的资源依赖关系(如 VIP → 文件系统 → 数据库服务)时,Pacemaker + Corosync 是业界标准方案。Corosync 负责集群成员关系和可靠消息传递,Pacemaker 负责资源编排和故障决策。

Keepalived 状态机与抢占模式

Keepalived 的 VRRP 实例有 MASTER / BACKUP / FAULT 三种状态,切换路径:BACKUP → MASTER(选举超时),MASTER → BACKUP(收到更高优先级通告),任意状态 → FAULT(脚本失败或接口故障)。默认行为是抢占式(preempt)——优先级更高的节点恢复后立即夺回 VIP。对主备切换敏感的数据库业务,应关闭抢占避免频繁抖动:

# 关闭抢占:原主恢复后不自动夺回,减少切换抖动
vrrp_instance VI_WEB {
    state BACKUP
    priority 100
    nopreempt          # 关闭抢占(两节点都配置 nopreempt 才生效)
    preempt_delay 300  # 或延迟 300 秒再抢占,等业务稳定
}

另外注意:state 只是启动时的初始角色,真正决定谁当 MASTER 的是 priority。两节点 priority 相同会引发振荡,务必错开数值(如 200/100)。

Pacemaker 资源类型与约束

Pacemaker 把一切可管理的东西抽象为资源,理解三种基础类型与三类约束是使用它的前提:

资源类型含义示例
primitive(基本)单实例资源,运行在某一个节点VIP、systemd 服务、DRBD 提升
group(组)一组按顺序共置的资源,必须同节点同顺序VIP + 文件系统 + 数据库服务
clone(克隆)在每个节点各运行一份DRBD 的 DataSync、ping 心跳监控
约束类型作用示例
colocation(共置)资源必须(或禁止)运行在同一节点VIP 与数据库必须同节点:INFINITY
order(顺序)资源启停的先后顺序先挂载文件系统再启动数据库
location(位置)资源倾向运行在哪些节点数据库优先 node1,带分数偏好

约束是分值的:INFINITY 表示硬性要求,有限分值(如 100)表示软性偏好。Pacemaker 通过计算所有约束的总分决策资源落在哪里——这是它比 Keepalived 的"优先级"模型强大得多的地方。

示例代码

Keepalived 主备配置

# /etc/keepalived/keepalived.conf — 主节点
global_defs {
    router_id HA_MASTER
    notification_email {
        ops@example.com
    }
    notification_email_from keepalived@example.com
    smtp_server localhost
}

vrrp_script check_nginx {
    script "/usr/bin/killall -0 nginx"
    interval 2
    fall 2
    rise 2
}

vrrp_instance VI_WEB {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 42abcdef
    }
    virtual_ipaddress {
        192.168.1.200/24 dev eth0
    }
    track_script {
        check_nginx
    }
    notify_master "/usr/local/bin/switch-master.sh"
    notify_backup "/usr/local/bin/switch-backup.sh"
    notify_fault "/usr/local/bin/switch-fault.sh"
}
# 备节点(仅 state 和 priority 不同)
vrrp_instance VI_WEB {
    state BACKUP
    priority 100
}

systemctl enable --now keepalived

# 验证
ip addr show dev eth0 | grep 192.168.1.200
systemctl status keepalived

# 日志
journalctl -u keepalived -f

etcd 三节点集群

# 节点 1(10.0.0.1)启动 etcd
# --name: 集群内唯一节点名,用于 Raft 日志中的身份标识
# --initial-advertise-peer-urls: 其他节点用来连接本节点的地址(集群内部通信)
# --advertise-client-urls: 客户端连接地址(etcdctl/API 调用)
# --initial-cluster: 所有节点的初始列表(新集群启动时必须完整列出)
# --initial-cluster-state=new: 表示这是全新集群(非成员变更)
etcd --name=node1 \
  --initial-advertise-peer-urls=http://10.0.0.1:2380 \
  --listen-peer-urls=http://0.0.0.0:2380 \
  --advertise-client-urls=http://10.0.0.1:2379 \
  --listen-client-urls=http://0.0.0.0:2379 \
  --initial-cluster-token=etcd-cluster-1 \
  --initial-cluster=node1=http://10.0.0.1:2380,node2=http://10.0.0.2:2380,node3=http://10.0.0.3:2380 \
  --initial-cluster-state=new \
  --data-dir=/var/lib/etcd

# 验证集群健康状态
etcdctl --endpoints=http://10.0.0.1:2379 member list    # 列出所有成员及 ID
etcdctl endpoint health --cluster                        # 检查每个端点是否健康
etcdctl endpoint status --cluster -w table               # 查看 Leader、DB 大小等
# 输出:
# +----------------+------------------+---------+---------+-----------+...
# |    ENDPOINT    |        ID        | VERSION | DB SIZE | IS LEADER |...
# +----------------+------------------+---------+---------+-----------+...
# | 10.0.0.1:2379  | 1111111111111111 |   3.5.9 |  25 kB |      true |...
# | 10.0.0.2:2379  | 2222222222222222 |   3.5.9 |  25 kB |     false |...
# | 10.0.0.3:2379  | 3333333333333333 |   3.5.9 |  25 kB |     false |...
# 键值操作
etcdctl put /config/database/url "postgres://db.internal:5432/app"
etcdctl get /config/database/url
etcdctl get / --prefix --keys-only

# 备份与恢复
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-$(date +%Y%m%d).db
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot-20260729.db \
  --data-dir=/var/lib/etcd-restored

DRBD 块设备同步

# 安装 DRBD 用户空间工具
apt install -y drbd-utils

# /etc/drbd.d/r0.res — DRBD 资源配置
# DRBD 在块设备层做实时同步(类似网络 RAID-1),对上层文件系统透明
resource r0 {
    on node1 {
        device    /dev/drbd0;       # 逻辑设备路径(上层 mkfs/mount 用这个)
        disk      /dev/sdb1;        # 底层物理分区(必须大小一致)
        address   10.0.0.1:7788;    # 同步数据传输端口
        meta-disk internal;         # 元数据存在磁盘末尾(vs 外部元数据设备)
    }
    on node2 {
        device    /dev/drbd0;
        disk      /dev/sdb1;
        address   10.0.0.2:7788;
        meta-disk internal;
    }
}

# 初始化并启动 DRBD
drbdadm create-md r0                # 创建元数据
drbdadm up r0                       # 加载 DRBD 模块并启动资源
drbdadm primary --force r0          # 强制提升为 Primary(首次同步必须)
mkfs.ext4 /dev/drbd0                # 在 DRBD 设备上创建文件系统
mount /dev/drbd0 /mnt/data          # 挂载使用

# 查看同步状态(关键字段:cs=连接状态, ro=角色, ds=磁盘状态)
cat /proc/drbd
# 输出:
# version: 8.4.11 (api:1/proto:86-101)
#  0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
#     ns:1024 nr:0 dw:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
# cs:Connected = 节点已连接
# ro:Primary/Secondary = 本节点是 Primary,对端是 Secondary
# ds:UpToDate/UpToDate = 两端数据完全同步

Pacemaker + Corosync 快速起步

# 安装(两个节点相同操作)
apt install -y pacemaker corosync pcs   # pcs = Pacemaker Configuration System CLI

# 设置 hacluster 用户密码(集群认证用,两个节点密码必须一致)
passwd hacluster

# 在节点 1 上认证并创建集群
pcs host auth node1 node2 -u hacluster   # 用 hacluster 用户认证两个节点
pcs cluster setup my-cluster node1 node2  # 创建名为 my-cluster 的集群
pcs cluster start --all                   # 启动所有节点的集群服务

# 配置资源:VIP + nginx 服务
# ocf:heartbeat:IPaddr2 是 Pacemaker 内置的 IP 资源代理
pcs resource create vip ocf:heartbeat:IPaddr2 \
  ip=192.168.1.200 cidr_netmask=24 op monitor interval=10s
# systemd:nginx 是 systemd 服务资源代理
pcs resource create nginx systemd:nginx op monitor interval=5s

# 约束:VIP 和 nginx 必须在同一节点(共置约束)
pcs constraint colocation add vip nginx INFINITY  # INFINITY = 硬性要求
# 顺序约束:先启动 nginx 再绑定 VIP(避免 VIP 流量到未就绪的服务)
pcs constraint order nginx then vip

# 查看集群状态
pcs status
# 输出:
# Cluster name: my-cluster
# Stack: corosync
# Current DC: node1 (version 2.1.6) - partition with quorum
# 2 nodes configured
# 2 resource instances configured
# Online: [ node1 node2 ]
# Full list of resources:
#  vip      (ocf:heartbeat:IPaddr2):  Started node1
#  nginx    (systemd:nginx):          Started node1

Keepalived 双主互备(两台机器互为主备)

# 思路:两台机器各自持有一个 VIP,互为对方的备份
# 每台机器定义一个自己的 MASTER 实例 + 一个对方的 BACKUP 实例

# 节点 A(10.0.0.1):vip-web 主 + vip-api 备
vrrp_instance VI_WEB {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 200
    advert_int 1
    authentication { auth_type PASS; auth_pass web@2026 }
    virtual_ipaddress { 192.168.1.200/24 dev eth0 }
    track_script { check_haproxy }
}

vrrp_instance VI_API {
    state BACKUP
    interface eth0
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication { auth_type PASS; auth_pass api@2026 }
    virtual_ipaddress { 192.168.1.201/24 dev eth0 }
    track_script { check_haproxy }
}

# 节点 B(10.0.0.2):vip-web 备 + vip-api 主(priority 对调)
# VI_WEB: state BACKUP priority 100
# VI_API: state MASTER priority 200

# 效果:两台机器同时承载流量,单机故障时另一台接管全部 VIP
# 资源利用率翻倍,适合无状态或主从复制的服务

Pacemaker 资源组与 Fencing

# 场景:VIP + 文件系统 + MySQL 服务组成资源组,整体同进同退
# 资源组内的资源按顺序启动、逆序停止,且必须运行在同一节点

# 资源 1:VIP(集群入口 IP)
pcs resource create mysql_ip ocf:heartbeat:IPaddr2 \
  ip=192.168.1.210 cidr_netmask=24 op monitor interval=5s

# 资源 2:文件系统(挂载 DRBD 设备到 MySQL 数据目录)
pcs resource create mysql_fs ocf:heartbeat:Filesystem \
  device=/dev/drbd0 directory=/var/lib/mysql fstype=ext4 \
  op monitor interval=10s

# 资源 3:MySQL 服务(systemd 管理的服务)
pcs resource create mysql_srv systemd:mysqld op monitor interval=10s

# 创建资源组:按顺序启动(ip → fs → srv),停止时逆序(srv → fs → ip)
pcs resource group add mysql_group mysql_ip mysql_fs mysql_srv
pcs constraint order mysql_ip then mysql_fs then mysql_srv

# 位置约束:整个组优先跑 node1(分数 100 = 软偏好,非强制)
pcs constraint location mysql_group prefers node1=100

# 配置 Fencing(生产必配!防止脑裂时故障节点干扰集群)
# STONITH = Shoot The Other Node In The Head
# fence_ipmilan 通过 IPMI 远程控制故障节点关机/重启
pcs stonith create ipmi-fence fence_ipmilan \
  pcmk_host_list="node1 node2" \      # 可被 fence 的节点列表
  ipaddr=10.0.0.250 lanplus=1 \       # IPMI 管理网 IP
  login=admin passwd=secret \          # IPMI 登录凭证
  op monitor interval=60s             # 每 60 秒检测 fence 设备是否正常

# 验证 fence 设备状态
pcs stonith show ipmi-fence
pcs status resources

常见错误

错误后果解决
VRRP 认证密码不一致备节点无法加入 VRRP 组,VIP 不漂移主备 auth_pass 必须完全一致
etcd 节点数为偶数网络分区时可能出现 quorum 死锁始终使用奇数节点(3/5/7)
DRBD 同步模式设为异步主节点故障时可能丢数据生产使用 Protocol C(同步确认)
脑裂后手动干预不当数据丢失或双写冲突先停止一侧 I/O,确认差异后手动解决
Pacemaker 未配 STONITH故障节点无法被隔离,资源卡住配置 fence 设备或设置 stonith-enabled=false(仅测试环境)
Keepalived 防火墙未放行 VRRPadvertisement 被丢弃,频繁切换iptables 放行 proto 112vrrp
etcd 数据目录放在系统盘磁盘满导致 etcd 集群不可用单独挂载 SSD 给 /var/lib/etcd
双主配置后两个 VIP 都漂到同一台track_script 同一脚本失败时,两实例同时降级两个 VRRP 实例分别用独立检查脚本;或检查 auth_pass 是否互串
nopreempt 配置后主备不切换nopreempt 必须两端同时配置才生效,单端配置行为不确定两台节点统一配置;需要强制切换时手动 systemctl stop keepalived
Pacemaker 资源组启动一半卡住顺序约束与共置约束冲突,或某资源依赖的外部条件缺失pcs resource debug-start 逐个调试;先不加约束跑通再叠加
STONITH 误杀正常节点fence 设备参数错误(IPMI 密码/通道),探测失败即触发先在测试环境验证 fence 命令可用;生产配置 pcmk_reboot_action 等保护

最佳实践

  • 奇数 etcd 集群:始终部署 3 或 5 节点,避免偶数节点在分区时 quorum 均分
  • 专用心跳网络:VRRP advertisement、Corosync 心跳、DRBD 同步全部走独立网卡/交换机,与业务网络物理隔离
  • 冗余心跳链路:至少两条心跳路径(以太网 + 串口线),防止单链路故障引发脑裂
  • 健康检查脚本:Keepalived 的 track_script 不仅要检测进程存活,还应检测服务端口响应(如 curl -f http://localhost:80
  • etcd 定期备份:用 etcdctl snapshot save 定期备份,备份文件异地存储
  • DRBD 配合文件系统检测:Keepalived 中 track_script 检查 DRBD 状态(cat /proc/drbd 中的 ro: 是否为 Primary)
  • Pacemaker 测试前关 STONITH:实验室环境 pcs property set stonith-enabled=false,生产环境务必配置 fence 设备
  • 主备切换演练:定期手动触发故障转移(关服务、拔网线),验证切换时间和数据一致性
  • 日志集中采集:集群节点日志发送到集中日志平台,脑裂发生后能回溯时间线

方案选型对比

需求场景推荐组合理由
无状态服务(Web/负载均衡器)主备Keepalived + VRRP配置简单,VIP 漂移秒级完成
有状态数据库双机热备Keepalived + DRBD(Protocol C)块级同步 + 脚本化切换,成本最低
3 节点以上、多资源编排Pacemaker + Corosync(+ DRBD 或共享存储)约束体系完整,支持 clone/fencing
强一致配置存储 / 服务发现etcd 3/5 节点集群Raft 共识,K8s 同款底座
云原生应用层高可用Kubernetes(ReplicaSet + Service)容器场景天然滚动重建,无需手工 VIP

选型要点:状态化程度决定方案——无状态服务用 VIP 漂移即可;有状态服务必须回答"数据谁写、怎么同步、坏了怎么仲裁"三个问题,答案通常指向 DRBD 或共享存储 + Pacemaker。

练习题

  1. 部署一个 Keepalived 主备对,VIP 为 192.168.1.200,nginx 进程异常时触发漂移
  2. 搭建 etcd 三节点集群,写入一条配置后停止 Leader 节点,观察新的 Leader 如何产生
  3. 配置 DRBD 资源 r0/dev/sdb1 在两节点间实时同步,挂载后创建一个文件验证同步
  4. iptables -A INPUT -p vrrp -j DROP 模拟心跳中断,观察 Keepalived 脑裂现象并手动恢复
  5. 使用 Pacemaker + Corosync 部署一组 VIP + nginx 资源组,执行 pcs cluster stop node1 观察自动迁移
  6. 画出 5 节点 etcd 集群中某一节点宕机后的选主流程图(含 Term 递增、投票过程)
点击查看答案
  1. keepalived.conf 配置 vrrp_instance, virtual_ipaddress, track_script 检测 nginx 进程。systemctl stop nginx 后 VIP 漂移到备机。
  2. 三节点启动后 etcdctl endpoint status --cluster -w table 显示 Leader。停 Leader 后 etcd 触发选举,约 1-2 秒产生新 Leader。
  3. DRBD 配置 resource r0 { device /dev/drbd0; disk /dev/sdb1; net { allow-two-primaries; } }。primary 上格式化挂载写文件,secondary 变为 primary 后可读。
  4. iptables 丢弃 VRRP 通告后主备互不知晓,备机升主。此时 VIP 在两台均存在——脑裂。恢复:清除 iptables 规则后重启 keepalived。
  5. pcs 命令创建资源组,pcs cluster stop node1 后资源迁移到 node2。pcs status 显示切换过程。
  6. Node3 宕机 → Leader(假设 Node1)检测 lease 超时 → 发起新 Term(Term+1)→ 发送 RequestVote RPC → Node2 和 Node4/Node5 投票 → Node1 获多数派(5 节点中 4 存活,需 ≥3 票,实际已获足够票数)→ Node1 当选新 Leader,集群继续服务。关键:Raft 用多数派(quorum)保证一致性,5 节点容忍最多 2 台同时故障。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释高可用集群的脑裂问题和仲裁机制尝试向他人讲解
命令操作能不查文档完成 Pacemaker/Corosync 集群搭建和资源管理在终端实际执行
原理掌握能说出高可用集群的故障检测和资源漂移原理画出流程图
故障排查能独立排查集群脑裂或资源无法启动的问题模拟故障并修复
最佳实践能说明为什么需要配置 STONITH/隔离设备防止脑裂对比不同方案

本章总结

速查表

工具核心机制适用场景
KeepalivedVRRP VIP 漂移 + 健康检查主备高可用,无状态服务
etcdRaft 共识算法,强一致性 KV配置存储、服务发现
DRBD块设备级实时同步复制共享存储高可用
Pacemaker+Corosync集群资源编排 + 成员管理复杂多资源集群

Linux 高可用集群的核心在于"冗余 + 检测 + 切换"三环:

  1. Keepalived + VRRP:最简单实用的主备 VIP 切换方案,适用于无状态服务或配合主从复制的有状态服务
  2. etcd + Raft:分布式共识层,适合需要强一致性的配置存储和服务发现(也是 Kubernetes 的基础组件)
  3. DRBD:块设备级别的实时同步,是共享存储高可用的底层方案
  4. Pacemaker + Corosync:多节点、多资源的复杂集群编排,适合数据库等高要求场景

无论使用哪种方案,防脑裂是设计集群时永远不能忽略的一环——冗余心跳 + 仲裁 + fencing 缺一不可。

延伸阅读

常见问题

etcd 集群节点数为什么推荐奇数?
etcd 使用 Raft 共识算法,需要多数派(quorum)同意才能执行操作。3 节点 quorum=2(容忍 1 节点故障),5 节点 quorum=3(容忍 2 节点故障)。奇数节点在同等容错能力下减少节点数:5 节点 vs 4 节点都能容忍 2 台故障,但 5 节点更安全(网络分区时更容易形成多数派)。最小生产配置:3 节点。
DRBD 和分布式存储有什么区别?
DRBD(Distributed Replicated Block Device)是内核级块设备同步复制,在两台服务器间镜像整块磁盘。部署简单、延迟低,但只能做 2 节点主备,扩展性有限。分布式存储(Ceph、GlusterFS)支持多节点多副本、自动故障恢复、无限扩展。DRBD 适合双机 HA 场景(数据库主备),分布式存储适合大容量和弹性场景。
脑裂问题怎么检测和恢复?
检测:Keepalived 监控脚本定期检查对端节点的 VRRP 状态;STONITH(Shoot The Other Node In The Head)是 Pacemaker 集群的标准脑裂防护机制。恢复:如果发生脑裂,停止一台节点的集群服务,手工同步数据差异,确认一致后重新加入集群。自动化方案:使用 etcd 或 ZooKeeper 做仲裁节点(tie-breaker)。
↑ 回到顶部