在Kubernetes中部署Vault使用Kubernetes Auth时遭遇403权限拒绝问题
环境信息
Kubernetes版本:v1.25.6
Vault版本:v1.12.1
问题1:Vault Agent登录阶段间歇性403,延迟数分钟/小时后成功
核心原因
初始化Raft集群时存在关键错误:给每个Vault节点单独执行了vault operator init,这会创建3个独立的Raft集群,而非统一的HA集群。当Vault Agent向未配置Kubernetes Auth、未绑定角色的节点发起请求时,会返回403;只有当请求路由到已完成配置的vault-0节点时,才能成功认证,这就是延迟成功的根本原因。
此外,Kubernetes Auth配置缺少必要的CA证书和Issuer校验,进一步加剧了验证失败的概率。
修复步骤
重建Raft集群
- 停止所有Vault节点:
kubectl scale statefulset vault -n vault --replicas=0 - 删除现有存储卷(注意:会丢失现有配置,需先备份重要数据):
kubectl delete pvc data-vault-0 data-vault-1 data-vault-2 -n vault - 恢复StatefulSet:
kubectl scale statefulset vault -n vault --replicas=3 - 仅在
vault-0节点执行初始化:kubectl exec -ti vault-0 -n vault -- vault operator init > keys.txt - 记录输出中的unseal key和初始root token,然后依次在所有节点执行unseal:
# 替换<unseal-key>为keys.txt中的密钥 kubectl exec -ti vault-0 -n vault -- vault operator unseal <unseal-key> kubectl exec -ti vault-1 -n vault -- vault operator unseal <unseal-key> kubectl exec -ti vault-2 -n vault -- vault operator unseal <unseal-key> - 将
vault-1和vault-2加入vault-0的集群:kubectl exec -ti vault-1 -n vault -- vault operator raft join http://vault-0.vault-internal.vault.svc:8200 kubectl exec -ti vault-2 -n vault -- vault operator raft join http://vault-0.vault-internal.vault.svc:8200 - 验证集群状态:
kubectl exec -ti vault-0 -n vault -- vault operator raft list-peers
- 停止所有Vault节点:
修正Kubernetes Auth配置
登录Vault后,重新配置Kubernetes Auth,添加CA证书和Issuer(适配K8s 1.21+的ServiceAccount Token规则):vault login <root-token> vault auth enable kubernetes vault write auth/kubernetes/config \ kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ issuer="https://kubernetes.default.svc.cluster.local"移除多余的ClusterRoleBinding
给myapp-sa绑定的system:auth-delegatorClusterRole是不必要的——这个权限是给Vault自身的ServiceAccount用来调用K8s TokenReview API的,你的Helm配置中已经开启了authDelegator: enabled: true,Helm会自动为Vault的ServiceAccount创建正确的绑定。执行以下命令删除多余绑定:kubectl delete clusterrolebinding myapp-sa-rbac
问题2:认证成功后读取KV密钥返回403
可能原因
- Raft集群分裂导致配置未同步:部分节点未同步到最新的Policy和Role配置。
- Policy路径或权限配置错误。
- ServiceAccount与Role的绑定规则不匹配。
修复步骤
确认集群配置一致性
在所有Vault节点上验证Policy和Role是否存在:# 在vault-0上检查 kubectl exec -ti vault-0 -n vault -- vault policy read myapp kubectl exec -ti vault-0 -n vault -- vault read auth/kubernetes/role/myapp # 在vault-1上检查 kubectl exec -ti vault-1 -n vault -- vault policy read myapp kubectl exec -ti vault-1 -n vault -- vault read auth/kubernetes/role/myapp如果某节点缺少配置,重建集群后重新创建Policy和Role:
vault policy write myapp - <<EOF path "myapp/data/postgres/config" { capabilities = ["read"] } EOF vault write auth/kubernetes/role/myapp \ bound_service_account_names=myapp-sa \ bound_service_account_namespaces=myapp \ policies=myapp \ ttl=3d验证Agent令牌权限
从应用Pod中取出Agent的令牌,手动验证权限:# 进入myapp Pod kubectl exec -ti myapp-<pod-id> -n myapp -- cat /home/vault/.vault-token # 用该令牌登录Vault vault login <agent-token> # 尝试读取密钥 vault kv get myapp/postgres/config如果仍返回403,检查Policy路径是否正确(KV-v2的路径格式为
<mount-path>/data/<secret-path>,你的配置是正确的),或确认Role绑定的ServiceAccount名称/命名空间与实际一致。修复应用启动命令
你的应用容器启动命令执行. /vault/secrets/database-config后会直接退出,导致容器反复重启。修改为持续运行的命令,例如:command: ["sh", "-c"] args: - . /vault/secrets/database-config && nginx -g 'daemon off;'
内容的提问来源于stack exchange,提问作者Suge

