实现容器内敏感凭证“无私钥落地”的动态注入,关键在于切断凭据写入磁盘路径并锚定硬件级可信根;vault agent 通过 tmpfs、unix socket 或 stdin 在内存中交付凭据,配合 kubernetes 的 serviceaccount 绑定、只读文件系统与安全策略强化信任链。

实现容器内敏感凭证“无私钥落地”的动态注入,关键不在容器编排本身,而在于切断凭据写入磁盘的路径,并将信任链锚定到硬件级可信根(如 Vault 的 HSM 支持或 Kubernetes 节点级 TPM 集成)。容器编排(如 Kubernetes)只负责调度与上下文传递,Vault 才是执行动态生成、内存驻留与安全分发的核心。真正可行的路径是:让凭证永远不以明文形式落盘,而是由 Vault Agent 在内存中解密/渲染后,通过 tmpfs、进程环境变量或 Unix socket 直接交付给应用。
用 Vault Agent + tmpfs 实现证书/密码“用完即焚”
这是最成熟、无需修改应用代码的落地方式。Vault Agent 边车容器启动后,自动完成身份认证、拉取加密凭据、解密并渲染模板,再将结果写入 /dev/shm(基于内存的 tmpfs 挂载点),而非常规 volume。
- Nginx 场景下,
ssl_password_file /dev/shm/nginx-ssl-pass指向该路径,文件生命周期与 Pod 一致,节点重启即清空 - 必须在 Pod spec 中显式挂载:
volumeMounts: [{name: shm, mountPath: /dev/shm, medium: Memory}] - 渲染模板需禁用缓存,且 Agent 配置启用
auto_auth和templated_secret,确保每次重载都重新获取最新凭据
绕过文件系统:用 Unix socket 或 stdin 直接喂给应用进程
对支持运行时输入的应用(如某些数据库客户端、自研服务),可跳过文件落地环节,改用更直接的通信方式:
- Vault Agent 启动时开启本地 listener(如
listener "unix" { path = "/vault/.socket" }),应用启动后通过 socket 连接,接收解密后的凭据流 - 或由 Agent 将凭据通过
stdin注入主容器进程(需 ENTRYPOINT 脚本配合,例如exec vault kv get -field=password secret/data/db | myapp --password-fd 0) - 此方式完全规避文件系统,连 tmpfs 都不依赖,但要求应用具备对应解析能力
硬件级信任加固:绑定节点 TPM 或 HSM 解封 Vault
“无私钥落地”的前提,是 Vault 自身的 root 密钥和操作令牌也不应以静态方式存在。生产环境应启用硬件信任链:
- 使用 Vault 的 HSM 模式(如 AWS CloudHSM、Thales Luna)存储 master key,所有解封、签名均在硬件模块内完成,密钥永不离开 HSM
- Kubernetes 节点启用 TPM 2.0 + Secure Boot,Vault server 容器启动时调用 tpm2-tools 校验内核与容器镜像完整性,仅当校验通过才允许加载 Vault 配置
- 结合
vault server -dev -hsm-config=...或 Raft 模式下配置seal "awskms",把解封密钥托管至云厂商硬件密钥服务
编排层必须做的三件事
Kubernetes 不是旁观者,它要为上述机制提供必要支撑:
- ServiceAccount 必须绑定 Vault Kubernetes auth role,且
bound_service_account_namespaces精确限定,避免跨命名空间越权 - PodSecurityPolicy 或 Pod Security Admission(PSA)需禁止
hostPath挂载敏感路径,强制readOnlyRootFilesystem: true,防止应用自行写盘 - 启用 Seccomp + AppArmor profile,限制容器调用
openat(AT_FDCWD, "/etc/secrets/", ...)类路径,从系统调用层堵住非授权落盘行为










