高可用配置:Raft 与 Consul 存储后端
说到 Vault 的高可用,我个人觉得最绕不开的就是存储后端的选择。Vault 本身不保存数据,所有加密信息都搁在后端存储里。高可用说白了就是让多个 Vault 实例共享同一个存储后端,并且能自动切主。我早年搭第一套生产环境时,选了 Consul,后来换成了 Raft,踩了不少坑。下面把我的经验掰开揉碎讲给你听。
Raft vs Consul:核心差异
这两个方案都支持高可用,但底子完全不同。
| 对比项 | Raft 集成存储(集成存储) | Consul 存储后端 |
|---|---|---|
| 依赖组件 | 无外部依赖,Vault 自带 Raft 一致性算法 | 需要独立部署 Consul 集群(至少 3 节点) |
| 数据持久化 | Vault 节点本地磁盘 | Consul 的 KV Store(内存+快照) |
| 一致性协议 | Raft | Raft(Consul 内部实现) |
| 故障转移方式 | 自动 Leader 选举,对客户端透明 | 自动 Leader 选举,但依赖 Consul 集群健康 |
| 运维复杂度 | 低,一个 Vault 进程搞定 | 中,需要额外维护 Consul 集群 |
| 性能 | 中等,写操作需半数以上节点确认 | 较高,但受 Consul 性能瓶颈影响 |
| 网络要求 | 节点间延迟低,推荐同一机房 | 同左,但 Consul 本身对网络抖动更敏感 |
搭建案例:Raft 模式集群
直接上命令,我习惯用 vault operator init 和 vault operator raft join 这条线。
1. 启动第一个节点(Leader)
vault server -config=/etc/vault/config.hcl
config.hcl 里必须启用 raft 存储:
storage "raft" {
path = "/opt/vault/data"
node_id = "node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = true
}
api_addr = "http://192.168.1.10:8200"
cluster_addr = "http://192.168.1.10:8201"
disable_mlock = true
ui = true
启动后初始化并解封:
export VAULT_ADDR='http://192.168.1.10:8200'
vault operator init -key-shares=5 -key-threshold=3
vault operator unseal # 输入3个key
2. 加入第二个、第三个节点
在节点2和节点3上执行:
vault server -config=/path/to/node2-config.hcl
然后从任意已初始化的节点执行加入命令:
vault operator raft join http://192.168.1.10:8200
重复解封流程。等节点都加入后,用 vault operator raft list-peers 确认集群状态。
搭建案例:Consul 后端模式
Consul 后端需要先建好 Consul 集群,这个我就不展开了。Vault 配置里写:
storage "consul" {
address = "127.0.0.1:8500"
path = "vault/"
service = "vault"
}
注意 Consul 的 ACL 开启时,Vault 需要具备读写 KV 的 。我踩过的坑:Consul 的 ACL 过期后,Vault 看似正常,但写入失败时会报 500。建议配置时加 health check。
故障转移机制
Raft 模式下,故障转移非常自然。Leader 挂了后,剩余节点重新选举,通常几秒内完成。客户端只要配置了多个 VAULT_ADDR 或使用负载均衡器指向所有节点,就能自动重试到新 Leader。
Consul 模式下,Vault 主节点实际上是一个 Consul 的 session,当主节点挂掉后,Consul 检测到 session 失效,其他 Vault 实例会抢夺锁,谁拿到谁成为新主。这个过程依赖 Consul 的健康检查间隔(默认 10 秒),所以故障切换可能比 Raft 慢一些。
raft_trailing_logs 和心跳间隔决定,我一般设置 retry_join 时心跳超时为 3 秒,切换基本在 5 秒内完成。
下面这张图直观对比两种架构的差距:
避坑指南
我之前在几个项目里攒了一些教训,列出来你参考:
- Raft 节点数量一定要是奇数。 3 或 5 个最佳。偶数节点(比如 4)容错能力不增反降,因为多数派还是要求超过半数,4 节点的多数派是 3,跟 3 节点一样只能坏 1 个,何必多花钱。
- Consul 后端千万别用单节点。 曾经有个同事图省事只用了一个 Consul,结果 Consul 挂了 Vault 直接变成只读。后来我们强制要求 Consul 至少 3 个节点,并且用 systemd 守护。
- Raft 的
retry_join要写对。 启动时retry_join指向 Leader 地址,如果你写的是 Follower,节点会一直重试直到 Leader 出现。但如果你写的是负载均衡器地址,最好确认负载均衡能指向当前 Leader(推荐用主动健康检查)。 - 网络分区:Raft 集群出现网络隔离时,被隔离的节点会变成 Candidate,不断发起选举,可能导致磁盘 IO 飙升。我在 AWS 遇到过一次跨可用区延迟过高导致频繁选举,后来把节点全放到同一个可用区解决了。
vault.raft.leader 和 vault.core.unsealed 指标。一旦发现 Leader 切换频繁,第一时间检查网络和磁盘延迟。我曾经因为一台机器磁盘 IO 打满,导致 Raft 心跳超时,集群反复切主,服务抖动了好几分钟。
好了,这就是我个人对 Vault 高可用的理解。两种方案没有的好坏,关键是匹配你的团队运维能力。如果你只有 3 台机器,我推荐 Raft;如果你已经有一个健康的 Consul 集群,复用它会减少额外运维负担。记住:生产环境永远先测试再上线,别像我当年那样直接对着业务集群搞实验。