MongoDB 无法直连 Vault 获取动态凭据,因其不支持调用 Vault 的 database/creds 接口,无内置 Vault SDK、不感知租约变更,仅接受静态配置(如 mongod.conf 或 Kubernetes Secret),所有凭据获取、缓存、注入及续期均需应用层自行实现。

不能让 MongoDB 自己去 Vault 拉凭据 —— 它压根不支持调用 Vault 的 database/creds 接口。动态凭据必须由应用层主动获取、缓存、注入连接字符串,并自行处理租约续期。
为什么 MongoDB 进程无法直连 Vault 获取动态凭据
MongoDB 服务启动时只认静态配置:比如 mongod.conf 里的 security.authorization 和硬编码的用户密码,或 Kubernetes 中挂载的 Secret。它没有内置 Vault SDK,也不监听 Vault 的 lease 变更事件。哪怕你把 Vault token 写进环境变量,MongoDB 也不会自动用它去请求 /v1/database/creds/my-role。
- 官方 Operator(v1.26)明确禁用 Vault 动态凭据注入,只接受
spec.credentials.secretRef.name这类静态引用 - 副本集内部认证用的
keyFile、TLS 证书等文件类密钥,Vault 也无法直接挂载到容器里 - 所有“自动刷新”“租约续期”“吊销响应”都得靠业务代码自己实现,MongoDB 不感知
应用层调用 Vault API 获取凭据的最小可行路径
核心是:启动时拉一次 → 缓存在内存 → 构造连接字符串 → 定期续期(建议在 lease_duration * 0.8 时触发)。不要依赖连接池自动重连来“换凭据”,那会漏掉已建立的长连接。
- 用 Vault 官方 SDK(如
@hashicorp/vault-javascript或vault-go)调用POST /v1/database/creds/my-role - 响应体含
data.username、data.password、lease_duration、lease_id,必须保存lease_id用于后续PUT /v1/sys/leases/renew - 构造连接字符串时,把拿到的用户名密码拼进去:
mongodb://{{username}}:{{password}}@host:27017/db,别硬编码 - Node.js 示例中,避免在
connectionString里写死凭证;改用MongoClient初始化时传auth选项对象
Telegraf 能做什么、不能做什么
Telegraf 是目前最轻量的 Vault + MongoDB 集成入口,但它干的是指标采集,不是数据库身份代理。
- ✅ 支持
hashicorp_vault输入插件读取 KV v2(路径如secret/data/mongodb/app),配合mongodb输出插件写指标 - ❌ 不支持读取
database/creds/xxx动态路径 —— 这类 secret 返回的是带租约的临时凭证,Telegraf 没有续期逻辑 - ❌ 不能把 Vault 凭据“透传”给 MongoDB 进程本身;它只是个中间搬运工,不是凭据注入器
- ⚠️ 若 Vault 启用了 TLS,必须在 Telegraf 配置里显式加
tls_ca、tls_cert等字段,否则http://127.0.0.1:8200默认地址会连不上
容易被忽略的租约管理细节
动态凭据不是一劳永逸的。Vault 返回的 lease_duration 通常很短(比如 1 小时),且多数 KMS 后端(如 AWS RDS、PostgreSQL)不支持无限续期。应用必须自己记下 lease_id 并轮询续期,否则连接会在某次查询时突然报 MongoServerError: Authentication failed。
- 续期失败时,应降级为重新调用
/v1/database/creds/my-role拿新凭据,而不是卡住或 panic - 别把
lease_id存在 MongoDB 里 —— 那会造成循环依赖;推荐存在内存或本地 Redis - 如果你用的是 Atlas,注意它的
database/creds引擎后端是托管的,续期行为受 Atlas 控制,和自建 Vault 不完全一致

















