4. 第4节 高可用架构概述

高可用PKI集群不是单纯堆机器。我见过太多项目,买了四台服务器,结果一台挂了整个CA就断了。说白了,高可用是设计出来的,不是买来的。这节我把常见的几个架构模式拆开讲,每个模式都有坑,也有应对方法。

4.1 主从复制

主从复制是最经典的模式。一台主节点处理所有签名请求,数据实时或准实时同步到从节点。从节点平时只读,主节点挂了才切换。

主从复制的核心在于同步延迟。我曾经在金融客户现场遇到过一次:主节点刚签完一张证书,数据还没同步到从节点,主节点硬盘就挂了。从节点拿不到最后那条记录,导致证书编号断档,审计差点过不去。

我习惯的做法:主从之间用半同步复制,保证至少一台从节点确认收到事务日志,主节点才返回客户端成功。PostgreSQL的synchronous_standby_names配合synchronous_commit可以做到。

配置示例(PostgreSQL):

# postgresql.conf
synchronous_commit = remote_write
synchronous_standby_names = 'standby1, standby2'>

优缺点对比:

维度优势风险
一致性强一致性可配置同步模式影响写入性能
成本只需多一台服务器从节点资源浪费(只读)
切换手动或自动切换成熟脑裂需要额外仲裁

4.2 多活架构

多活又称主动-主动。所有节点都能签发证书,互相同步。你想想看,如果业务分布在全国,每个区域一个CA节点直接处理本地请求,延迟能降不少。

但多活有个大前提:证书序列号和密钥必须全局无冲突。我见过一个坑——两个节点用同一个序列号池,结果签发了两张不同公钥、相同序列号的证书。CRL查吊销时直接错乱。

多活架构下,序列号生成必须用“区间分配”或“雪花算法带节点ID”。不要用简单的自增。

我个人更倾向“双活+主从混合”。比如两节点双活,每节点再挂一个从节点做灾备。这样既有低延迟,又有高冗余。当然,运维复杂度翻倍,看业务承受能力。

4.3 负载均衡

负载均衡是把客户端请求分发到多个后端节点。PKI场景下要特别注意会话保持:同一个证书申请流程(从CSR到颁发)需要落到同一节点,否则中间状态丢失。

我建议用Nginx做七层负载均衡,配置如下:

upstream pki_cluster {
    least_conn;
    server 10.0.1.10:8443 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:8443 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:8443 backup;  # 备用节点
}
server {
    listen 443 ssl;
    ssl_certificate /etc/pki/tls/certs/lb.crt;
    ssl_certificate_key /etc/pki/tls/private/lb.key;
    location / {
        proxy_pass https://pki_cluster;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

注意:如果后端有HSM,负载均衡无法直接感知HSM健康。我通常会在处理节点上跑一个健康检查脚本,检测HSM连接和证书服务端口,把结果上报给负载均衡。

4.4 共享存储

共享存储让所有节点访问同一份证书文件、CRL和私钥。这在传统PKI里很常见,但也是故障率最高的环节之一。

文件共享(NFS/GFS)容易出权限问题。我记得有一次用户升级NFS版本,挂载选项漏了no_root_squash,结果CA程序写文件失败,整站停了几小时。

块存储(SAN/iSCSI)性能好,但需要集群文件系统(如OCFS2/GFS2),配置复杂。我踩过的坑是OCFS2心跳超时导致节点被踢出集群,文件锁定释放不了,签书服务挂起。

共享存储的终极建议:能不用就别用。现代PKI更倾向“主从复制+分布式存储”(如etcd+HAProxy)的组合,避免单点存储瓶颈。

4.5 故障转移策略

不管用哪种架构,最终都要面对“节点挂了怎么办”的问题。故障转移不是简单的重启服务,而是一套完整的策略闭环:

  1. 健康检查:定期探测服务端口、HSM状态、磁盘空间、时间偏差。检查周期一般5~15秒,超时3次标记为故障。
  2. 自动切换:主节点失联后,从节点或VIP管理工具(如Keepalived/Patroni)触发升级。切换前要确认“旧主真的挂了”,避免双主写入。
  3. 回切与防抖:旧主恢复后,不要立刻切回去。我习惯等它作为从节点同步完整再手动评估,或者设置回切窗口(比如凌晨3点)。

一个典型的故障转移策略对比表:

策略适用场景切换时间数据一致性
VIP+Keepalived主从复制3~10秒依赖同步延迟
Patroni+etcdPostgreSQL主从<30秒强一致
DNS轮询+Ttl短多活30~60秒最终一致
硬件负载均衡器任意秒级无感知

我个人最推崇Patroni + etcd的组合。它能自动仲裁、防止脑裂,而且PostgreSQL本身就是很好的CA数据库。我已经在三个生产环境用了这套方案,最稳。

高可用PKI集群逻辑架构 客户端请求 负载均衡器 (Nginx/HAProxy) PKI主节点 (签发) HSM + 数据库写 PKI从节点 (只读) 同步 + 读请求 共享存储 (NFS/SAN) 故障转移控制器 (Patroni/etcd) 说明:虚线表示控制/监控路径,实线表示数据路径。故障转移控制器通过健康检查驱动切换,共享存储建议仅在少数场景下使用。

这五块拼在一起,才是一个完整的高可用PKI集群。你在设计时不要只看单个模式,而是根据业务SLA、预算、运维团队水平去组合。我见过最成功的项目,就是老老实实从“主从复制 + 负载均衡”起步,半年后逐步迭代成“多活 + 自动故障转移”。步子太大,容易扯着。