HashiCorp Vault 进阶实战:基于 Raft 的 3 节点高可用集群部署指南

前言
自 Vault 1.4+ 起,Integrated Storage (Raft) 成为官方推荐的存储后端,彻底告别对 Consul 的依赖。本文聚焦 3 节点 Raft HA 集群(生产最小可用单元),提供从开发验证到生产落地的完整进阶指南。
结合上篇《Raft 集群高可用部署进阶实践》,你将掌握 Vault 特有的 HA 机制(Active/Standby、Performance Standby、企业版特性)与运维要点。

一、Vault Raft HA 架构核心

Vault 使用 Raft 实现数据复制与领导者选举:

  • 1 个 Active(Leader)节点:处理所有写操作(secrets 写入、策略更新等)
  • 2 个 Standby 节点:实时复制数据,可处理读请求(通过请求转发)
  • 客户端通过 Load Balancer 访问,LB 指向 Active 节点(或所有节点,Vault 会重定向)

故障容忍:3 节点集群可容忍 1 个节点故障(仍保持 Quorum)。
官方推荐生产使用 5 节点跨 3 AZ 以获得更好维护窗口与容错能力。

图:3 节点 Vault Raft HA 集群架构(Active 处理写,Standby 实时同步)

Vault Raft 集成存储参考架构(含 Transit Auto-unseal 示例)

二、快速验证:Docker Compose 3 节点集群

适合本地/测试环境快速上手。

docker-compose.yml 示例

version: '3.8'
services:
  vault1:
    image: hashicorp/vault:1.18
    container_name: vault1
    environment:
      - VAULT_ADDR=http://127.0.0.1:8200
    ports:
      - "8200:8200"
      - "8201:8201"
    volumes:
      - ./vault1:/vault/config
      - vault1-data:/vault/data
    command: server -config=/vault/config/vault.hcl
    cap_add:
      - IPC_LOCK

  vault2:
    image: hashicorp/vault:1.18
    container_name: vault2
    ports:
      - "8202:8200"
      - "8203:8201"
    volumes:
      - ./vault2:/vault/config
      - vault2-data:/vault/data
    command: server -config=/vault/config/vault.hcl
    cap_add:
      - IPC_LOCK
    depends_on:
      - vault1

  vault3:
    image: hashicorp/vault:1.18
    container_name: vault3
    ports:
      - "8204:8200"
      - "8205:8201"
    volumes:
      - ./vault3:/vault/config
      - vault3-data:/vault/data
    command: server -config=/vault/config/vault.hcl
    cap_add:
      - IPC_LOCK
    depends_on:
      - vault1
volumes:
  vault1-data:
  vault2-data:
  vault3-data:

各节点 vault.hcl 配置(关键差异在 node_id)

vault1/config/vault.hcl(第一个节点):

ui = true
disable_mlock = true   # 开发环境,生产建议 false + 调大 ulimit

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = true   # 生产必须开启 TLS!
}

storage "raft" {
  path    = "/vault/data"
  node_id = "vault1"
}

api_addr     = "http://vault1:8200"
cluster_addr = "http://vault1:8201"

vault2/config/vault.hcl

# ... listener 同上,端口映射已处理
storage "raft" {
  path    = "/vault/data"
  node_id = "vault2"
}
api_addr     = "http://vault2:8200"
cluster_addr = "http://vault2:8201"

vault3 同理,node_id = “vault3”。

启动与初始化流程

# 1. 启动集群
docker compose up -d

# 2. 初始化(仅在 vault1 执行一次)
docker exec -it vault1 vault operator init \
  -key-shares=5 -key-threshold=3

# 保存输出的 5 个 unseal keys 和 root token(生产用 PGP 或云 KMS 管理)

# 3. 解封 vault1(需要 3 个 key)
docker exec -it vault1 vault operator unseal   # 重复输入 3 个 key

# 4. vault2、vault3 加入集群
docker exec -it vault2 vault operator raft join http://vault1:8200
docker exec -it vault3 vault operator raft join http://vault1:8200

# 5. 分别解封 vault2、vault3
docker exec -it vault2 vault operator unseal
docker exec -it vault3 vault operator unseal

# 6. 验证集群状态
docker exec -it vault1 vault operator raft list-peers
docker exec -it vault1 vault status   # 显示 HA 模式 + Active/Standby

验证成功标志raft list-peers 显示 3 个节点,vault statusHA Enabled: true 且有一个 Active。

三、生产级部署:Kubernetes + Helm Chart(推荐)

官方 hashicorp/vault Helm Chart 是生产最佳实践。

1. 准备 values.yaml(3 节点 Raft HA + 推荐配置)

# vault-values.yaml
global:
  enabled: true
  tlsDisable: false   # 生产强烈建议开启 TLS + cert-manager

injector:
  enabled: true
  replicas: 1

server:
  # 高可用配置
  ha:
    enabled: true
    replicas: 3
    raft:
      enabled: true
      setNodeId: true
      config: |
        ui = true
        listener "tcp" {
          address = "0.0.0.0:8200"
          cluster_address = "0.0.0.0:8201"
          tls_disable = false
          tls_cert_file = "/vault/userconfig/vault-tls/tls.crt"
          tls_key_file  = "/vault/userconfig/vault-tls/tls.key"
        }

        storage "raft" {
          path = "/vault/data"
          # node_id 由 Helm 自动注入
        }

        seal "awskms" {          # 推荐 Auto-unseal(生产必备)
          region     = "ap-southeast-1"
          kms_key_id = "alias/vault-auto-unseal"
        }

        api_addr     = "https://vault.example.com:8200"
        cluster_addr = "https://{{ .Release.Name }}-{{ .Release.Namespace }}.svc.cluster.local:8201"

  # 资源限制(生产关键)
  resources:
    requests:
      memory: "512Mi"
      cpu: "500m"
    limits:
      memory: "1Gi"
      cpu: "1"

  # 数据持久化(使用高性能 StorageClass)
  dataStorage:
    enabled: true
    size: 10Gi
    storageClass: fast-ssd   # 推荐本地 SSD 或高 IOPS 云盘

  # 审计日志(生产必开)
  auditStorage:
    enabled: true
    size: 5Gi

  # 额外配置
  extraEnvironmentVars:
    VAULT_LOG_LEVEL: info

  # Pod 反亲和 + 拓扑分布(跨 AZ/节点)
  affinity: |
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app.kubernetes.io/name
              operator: In
              values:
              - vault
          topologyKey: kubernetes.io/hostname

  topologySpreadConstraints:
    - maxSkew: 1
      topologyKey: topology.kubernetes.io/zone
      whenUnsatisfiable: DoNotSchedule
      labelSelector:
        matchLabels:
          app.kubernetes.io/name: vault

2. 部署命令

helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update

helm install vault hashicorp/vault \
  --namespace vault \
  --create-namespace \
  -f vault-values.yaml

# 查看 Pod
kubectl get pods -n vault -l app.kubernetes.io/name=vault -w

3. 初始化与加入(与 Docker 类似,但用 kubectl exec)

# 初始化(在第一个 Pod 执行)
kubectl exec -it vault-0 -n vault -- vault operator init ...

# 解封 vault-0
kubectl exec -it vault-0 -n vault -- vault operator unseal ...

# 其他 Pod 自动加入(Helm 会处理部分),或手动:
kubectl exec -it vault-1 -n vault -- vault operator raft join https://vault-0.vault-internal:8200
# 然后解封

生产加固建议

  • 使用 cert-manager + Ingress 为 Vault 签发真实证书
  • Auto-unseal 使用 AWS KMS / GCP KMS / Azure Key Vault / Transit 引擎
  • 开启审计日志到文件或 Syslog
  • 配置 PodDisruptionBudget 保证至少 2 个节点可用

四、关键生产运维实践

1. 监控与告警

Vault 暴露 Prometheus 指标:

# 需要 root token 或有权限的 token
curl -H "X-Vault-Token: $TOKEN" \
  https://vault.example.com/v1/sys/metrics?format=prometheus

关键指标:

  • vault_core_active(1=Active)
  • vault_raft_leader
  • vault_raft_peer_count
  • vault_barrier_put / get 延迟
  • vault_audit_log_request 失败率

推荐 Grafana Dashboard:搜索 “Vault” 或使用官方/社区仪表盘。

2. 备份与恢复(Raft Snapshot)

# 定期快照(推荐每天 + 保留 30 天)
vault operator raft snapshot save /backup/vault-snapshot-$(date +%F).snap

# 恢复(新建集群或替换数据目录后)
vault operator raft snapshot restore /backup/vault-snapshot-xxx.snap

自动化:使用 CronJob + Velero,或 Vault Enterprise 的 Snapshot 功能。

3. 性能与资源

  • 磁盘:必须高性能 SSD/NVMe(Raft WAL + 状态机对 fsync 敏感)
  • 内存:生产建议 1Gi+ 请求,视 secrets 数量调整
  • 网络:低延迟,Cluster 端口(8201)与 API 端口分离
  • Auto-unseal:强烈推荐,消除人工解封风险

4. 安全加固 checklist

  • 生产必须启用 TLS(listener + cluster)
  • 启用 mlock(disable_mlock = false)+ 适当 ulimit
  • 最小权限 root token,日常使用 AppRole / Kubernetes Auth
  • 开启 Audit Device
  • 定期轮换 unseal keys / root token
  • 网络隔离(仅允许必要来源访问 8200/8201)

五、常见陷阱与解决方案

问题可能原因解决方案
raft join 失败cluster_addr / api_addr 配置错误确保 cluster_addr 使用内部可达地址
频繁 Leader 选举网络抖动或 election timeout 过小调大 cluster 心跳间隔,检查网络
解封后仍 Standby未正确 join 或未解封检查 raft list-peers + 重新 unseal
性能差 / 高延迟磁盘 IOPS 不足更换高性能存储,监控 fsync 延迟
K8s Pod 不断重启资源不足或 anti-affinity 冲突增加资源 + 调整 topology constraints
无法写入(只读模式)失 Quorum检查节点健康,恢复多数派节点

六、进阶扩展方向

  • Performance Standby(Enterprise):Standby 节点也可处理读请求,大幅提升吞吐
  • DR Replication(Enterprise):跨 Region 灾难恢复复制
  • Namespaces + Sentinel 策略:多租户精细控制
  • Transit Auto-unseal:用另一个 Vault 集群解封(上图示例)
  • 与上篇 Raft 文章结合:理解底层 Quorum、snapshot、成员变更机制

总结

3 节点 Raft 集群是 HashiCorp Vault 最经典且可靠的 HA 部署方式。掌握 初始化 → 加入 → 解封 → 验证 流程 + Helm + Auto-unseal + 监控备份 组合,即可构建企业级 Secrets 管理平台。

官方参考(强烈建议阅读):


本文由 Grok 基于最新 Vault 实践生成,可直接发布到 Hugo 站点。
需要配套的完整 Docker Compose 项目、cert-manager + TLS 配置示例、Prometheus rules、或 Terraform 模块?随时告诉我,我继续补充!

让你的 Vault 集群永远 Active,数据永不丢失!🔐


This completes the article creation.