Vault HA集群手动unseal报错:no expected answer for server id
Vault Raft HA集群手动部署故障排查
环境与操作流程
- 3台部署Docker的VM,每台运行1个Vault 1.15.2实例
- 采用手动配置、非自动加入/Unseal模式
- 操作步骤:
- 机器1(IP:10.20.110.50)启动Vault容器,完成初始化并Unseal,作为集群Leader
- 机器2(10.20.110.100)、机器3(10.20.110.150)执行
vault operator join http://10.20.110.50:8200,返回joined: true - 集群状态可见,但机器2、3为非投票跟随者
报错信息
尝试用Leader的初始化密钥手动Unseal跟随者时,触发以下错误:
Error unsealing: Error making API request. URL: PUT http://127.0.0.1:8200/v1/sys/unseal Code: 500. Errors: * Error making API request. URL: PUT http://10.20.110.50:8200/v1/sys/storage/raft/bootstrap/answer Code: 400. Errors: * no expected answer for the server id provided
Leader节点日志异常
Leader持续输出Raft连接拒绝错误:
2024-01-16T10:18:21.563Z [ERROR] storage.raft: failed to appendEntries to: peer="{Nonvoter 0bff0048-5c43-c93c-b8a3-443ce621bf2c 10.20.110.150:8201}" error="dial tcp 10.20.110.150:8201: connect: connection refused"
网络排查结果
- 节点间Ping互通正常
- 所有节点8200端口可跨机器访问
- 仅Leader的8201端口可外部连接,跟随者未Unseal时8201端口拒绝外部连接(容器内本地可正常访问)
- 无防火墙规则限制
配置文件
vault.json
{ "storage": { "raft": { "path": "/opt/vault/data/raft" } }, "listener": { "tcp": { "address": "0.0.0.0:8200", "cluster_address": "0.0.0.0:8201", "tls_disable": true } }, "telemetry": { "unauthenticated_metrics_access": true }, "cluster_name": "vc", "api_addr": "http://{{HOST}}:8200", "cluster_addr": "https://{{HOST}}:8201", "ui": true, "disable_mlock": true, "log_level": "debug", "default_lease_ttl": "168h", "max_lease_ttl": "0h" }
docker-compose.yaml
version: '3.8' services: vault: image: hashicorp/vault:1.15.2 container_name: vault hostname: vault entrypoint: [ "vault", "server", "-config=/vault/config/vault.json" ] volumes: - vault-data:/opt/vault/data/raft - /home/root/vault/vault.json:/vault/config/vault.json:ro environment: - VAULT_ADDR=http://127.0.0.1:8200 networks: - vault-network ports: - 8200:8200 - 8201:8201 healthcheck: test: ["CMD", "wget", "--no-verbose", "--spider", "--tries=1", "http://127.0.0.1:8200"] interval: 5s timeout: 5s retries: 10 start_period: 5s cap_add: - IPC_LOCK networks: vault-network: name: vault-network volumes: vault-data: name: vault-data driver: local
解决方案
1. 修正配置文件中的协议与地址错误
- 替换占位符IP:将所有节点
vault.json中的{{HOST}}替换为当前节点的实际集群IP(如机器2替换为10.20.110.100,机器3替换为10.20.110.150),避免Leader无法解析节点的集群通信地址 - 统一通信协议:将
cluster_addr的协议从https://改为http://,因为listener已配置tls_disable: true,Raft集群通信必须使用HTTP,否则会因协议不匹配导致连接失败
修正后的api_addr和cluster_addr示例(机器2):
"api_addr": "http://10.20.110.100:8200", "cluster_addr": "http://10.20.110.100:8201"
2. 重新部署并同步集群状态
- 停止所有节点的Vault容器,清理旧数据卷(若节点状态异常):
docker-compose down -v - 重新启动所有节点容器
- Leader节点重新初始化并Unseal
- 跟随者节点重新执行
vault operator join http://<Leader-IP>:8200
3. 正确执行Unseal与节点提升
- 跟随者加入集群后,使用Leader的Unseal密钥执行Unseal操作,此时应能正常完成(配置修正后不会再出现
no expected answer错误) - 将非投票节点提升为投票节点:
- 在Leader节点执行
vault operator raft peer list获取跟随者的节点ID - 执行
vault operator raft promote <node-id>完成节点角色提升
- 在Leader节点执行
4. 验证集群通信
Unseal所有节点后,检查Leader日志是否再出现connection refused错误,同时执行vault operator raft list-peers确认所有节点状态为voter。
内容的提问来源于stack exchange,提问作者gbos
相关产品推荐
相关产品推荐

