一句话总结
K8s 原生 Secret 只是 base64 编码, 不是加密, 任何有权限的人或被攻破的 Pod 都能直接读取明文.
生产环境的 Secret 管理需要外部加密存储(Vault)+ 自动同步(External Secrets Operator)+ 最小权限访问控制.
K8s Secret 的局限
K8s 06 篇配置管理中讲过 Secret 基础. 从安全视角看, 原生 Secret 有严重局限:
| 局限 | 风险 |
|---|---|
| base64 ≠ 加密 | kubectl get secret -o yaml 直接看到明文 |
| etcd 默认不加密 | 拿到 etcd 备份 = 拿到所有 Secret |
| RBAC 粒度不够 | 能读 Secret 就能读 Namespace 下所有 Secret |
| 无审计轮换 | Secret 创建后永远不变, 密钥泄露后无感知 |
| 存在 Git 仓库 | YAML 提交到 Git = 密钥永远留在历史记录中 |
绝不要把 Secret YAML 提交到 Git
即使 .gitignore 排除了, 如果曾经 commit 过一次, 密钥永远在 git history 中. 攻击者 clone 仓库 + git log --all -p 就能找到所有历史密钥.
etcd 静态加密
最低要求: 开启 etcd 的静态加密(Encryption at Rest), 确保 Secret 在磁盘上是密文:
|
局限: 这只保护 etcd 磁盘上的数据. 通过 API 访问(kubectl get secret)仍然返回明文, RBAC 是唯一的防线.
HashiCorp Vault
Vault 是企业级 Secret 管理的事实标准. 核心能力:
| 能力 | K8s Secret | Vault |
|---|---|---|
| 加密存储 | 需要额外配置 etcd 加密 | 内置 AES-256 加密 |
| 访问控制 | RBAC(Namespace 粒度) | 细粒度 Policy(按 path/操作) |
| 审计日志 | K8s audit log(有限) | 完整的读写审计 |
| 自动轮换 | 不支持 | Dynamic Secrets(自动生成临时凭证) |
| 租约管理 | 无 | Secret 有 TTL, 过期自动撤销 |
| 多后端 | 只有 K8s etcd | 数据库密码, 云凭证, PKI 证书等 |
Vault + K8s 认证
Pod 使用自己的 ServiceAccount Token 向 Vault 认证, 获取授权的 Secret:
|
Dynamic Secrets
Vault 最强大的能力, 不是存储静态密码, 而是按需生成临时凭证:
- 数据库: 每个 Pod 获得唯一的短期数据库用户名/密码(TTL=1h), 过期自动删除
- AWS: 按需生成临时 IAM 凭证, 过期自动撤销
- PKI: 按需签发短期 TLS 证书
好处: 没有共享密码. 每个 Pod 有自己的凭证, 泄露只影响一个实例, 且会自动过期.
External Secrets Operator(ESO)
ESO 自动将外部 Secret 存储(Vault / AWS Secrets Manager / GCP Secret Manager)同步为 K8s Secret, 让应用代码不需要感知 Vault:
|
ESO 的价值
应用代码仍然通过标准的 K8s Secret(环境变量/文件挂载)读取密钥, 零改造. 密钥的真实来源是 Vault, ESO 负责同步.
这让我们获得 Vault 的安全能力(加密, 审计, 轮换), 同时保持 K8s 原生的使用方式.
Sealed Secrets
解决"Secret YAML 不能提交到 Git"的问题. Sealed Secrets 将 Secret 加密后可以安全地提交到 Git:
|
|
方案对比与选型
| 方案 | 适用场景 | 复杂度 |
|---|---|---|
| K8s Secret + etcd 加密 | 最低要求, 小团队起步 | 低 |
| Sealed Secrets | GitOps 流程, 需要 Secret 入 Git | 低 |
| ESO + 云 Secret Manager | 云原生环境, 已有 AWS/GCP | 中 |
| ESO + Vault | 多云/混合云, 需要高级能力 | 高 |
| Vault Agent Sidecar | 需要 Dynamic Secrets / 短期凭证 | 高 |
渐进路径
起步: K8s Secret + etcd 加密 + Sealed Secrets(满足 GitOps).
进阶: ESO + 云 Secret Manager 或 Vault(统一管理 + 审计).
高阶: Vault Dynamic Secrets(每个 Pod 唯一临时凭证).
快速回顾
- K8s Secret 不是加密: base64 编码 + etcd 默认明文存储
- etcd 加密是最低要求(EncryptionConfiguration)
- Vault: 加密存储 + 细粒度策略 + 审计 + Dynamic Secrets + 自动轮换
- ESO: 将 Vault/云密钥管理器同步为 K8s Secret, 应用零改造
- Sealed Secrets: 解决 Secret 入 Git 的问题
- 永远不要把 Secret YAML 提交到 Git(用 Sealed Secrets 或 ESO 替代)
动手练习
- 检查 etcd 加密状态: 检查集群是否开启了 etcd 加密,
kubectl get secret -n kube-system -o yaml看数据是否是密文 - Sealed Secrets 实践: 安装 Sealed Secrets Controller, 用
kubeseal加密一个 Secret 并提交到 Git, 验证 Controller 自动解密生成真实 Secret - Vault 集成: 用 Docker Compose 部署 Vault dev server, 配置 K8s auth backend, 从 Pod 内使用 SA Token 获取 Vault 中的密钥
- ESO 同步: 安装 External Secrets Operator, 创建 ExternalSecret 从 Vault 同步密钥到 K8s Secret