摘要
90% 的团队第一次上 K8s 都会踩这个致命合规雷:以为 Secret 是加密存储,实则只是 Base64 编码,等于把数据库管理员密码、国密加密密钥明文存在 etcd 里,运维全员可见、配置提交 Git 直接泄露。等保、密评测评时一查一个准,整改一次就要推翻重配。
本文基于政务、金融信创项目合规落地经验,彻底拆解 K8s 数据库密钥的合规风险,输出从轻量到企业级的三套落地方案:SealedSecret 静态加密、国密 KMS 对接、Sidecar 动态零落地注入,覆盖人大金仓 V9、达梦 DM9 双库专属安全挂载规范。所有配置均经过等保三级、密评三级现场验证,照着做彻底解决明文密码漏洞,合规验收一次过。
政务选金仓,金融选达梦;MySQL 迁移选金仓,Oracle 迁移选达梦。全文无空泛理论,所有 YAML、操作步骤均生产实测,复制即用。
一、踩坑预警:K8s 原生 Secret 根本不是加密,90% 团队都踩了合规雷
📌 核心结论:K8s 原生 Secret 只是Base64 编码,不是加密。任何人拿到配置都能一秒解码,等于明文存储,等保、密评全不认可。
1.1 原生 Secret 的四大明文风险
- 编码等于明文 :Base64 是编码不是加密,
echo '密文' | base64 -d一秒还原密码,没有任何保密性 - etcd 明文落盘:Secret 默认以明文形式存在 etcd 中,拿到 etcd 备份就能导出所有数据库密码
- 权限管控松散:很多集群开发、运维都能查看 Secret,等于数据库密码全员可见
- 配置易泄露:YAML 文件提交 Git、流转过程中极易泄露,一旦泄露永久风险
1.2 数据库场景的高危敏感信息
以下内容绝对不能用原生 Secret 存储,是合规一票否决项:
- 数据库系统管理员、安全管理员、审计管理员密码
- TDE 透明加密密钥、国密加密密钥
- 审计日志签名密钥、复制用户密码
- 国密证书私钥、KMS 接入凭据
1.3 最常见的错误用法(你大概率也在这么用)
- ❌ 数据库密码写在环境变量里,
kubectl describe一眼就能看到 - ❌ 密码明文写在 YAML 里,提交到代码仓库
- ❌ 用 ConfigMap 存密码,连 Base64 都不做
- ❌ 镜像内置默认密码,打包到镜像里扩散
- ❌ 以为 Secret 是加密的,直接存核心密钥
二、合规硬标准:等保三级 + 密评三级对密钥存储的硬性要求
2.1 等保三级核心要求
- 身份鉴别信息必须加密存储,禁止明文
- 访问控制严格,仅授权人员可查看敏感配置
- 配置操作全审计,所有密钥变更留痕
- 重要数据存储保密性,加密密钥与业务数据分离
2.2 密评三级核心要求(更严格)
- 密钥必须由国密密钥管理系统(KMS)/ 密码机生成和存储,永不落地明文
- 密钥全生命周期可管可控:生成、分发、使用、轮换、归档、销毁全流程审计
- 密钥与数据必须物理分离,不能存在同一系统中
- 必须使用 SM2/SM3/SM4 等国密算法进行加密保护
2.3 原生 Secret 为什么过不了
| 检查项 | 原生 Secret 表现 | 是否合规 |
|---|---|---|
| 存储形态 | Base64 编码 = 明文 | ❌ 不合规 |
| 密钥生成 | 人工生成,无真随机 | ❌ 不合规 |
| 密钥分离 | 和数据同存 etcd | ❌ 不合规 |
| 生命周期 | 无轮换、无审计 | ❌ 不合规 |
| 国密算法 | 不支持 | ❌ 密评不合规 |
💡 一句话总结:原生 Secret 只能存非敏感配置,存数据库密码、加密密钥等于明文裸奔,合规必挂。
三、方案选型:三种 Secret 加密方案对比与适配场景
从落地成本、合规等级、安全强度三个维度,对应不同项目场景。
| 方案 | 实现原理 | 等保三级 | 密评三级 | 落地成本 | 推荐场景 |
|---|---|---|---|---|---|
| SealedSecret 静态加密 | 公钥加密 Secret,集群内私钥解密,落盘为密文 | ✅ 通过 | ❌ 不满足 | 低 | 中小项目、等保三级、非核心系统 |
| 国密 KMS 对接 | 密钥统一存国密 KMS,K8s 运行时动态解密,密钥不落地 | ✅ 通过 | ✅ 通过 | 中 | 政务、金融核心系统、密评三级 |
| Sidecar 动态注入 | Sidecar 从 KMS 拉取密钥到内存,全程不写磁盘,Pod 销毁自动清除 | ✅ 通过 | ✅ 高分通过 | 高 | 等保四级、密评三级 +、高安全等级系统 |
选型决策树
- 只过等保三级、预算有限 → 选 SealedSecret
- 要过密评三级、政务金融核心系统 → 选国密 KMS 对接
- 极高安全要求、密钥零落地 → 选 Sidecar 动态注入
四、落地实战一:SealedSecret 轻量加密(中小项目等保直通)
Bitnami SealedSecret 是最成熟的轻量方案:公钥加密、集群内私钥解密,YAML 文件里全是密文,提交 Git 也不怕泄露,etcd 落盘也是密文,完全满足等保三级要求。
4.1 核心原理
- 离线用公钥加密 Secret,生成 SealedSecret 密文对象
- 集群内 Controller 用私钥解密,生成原生 Secret
- 全程 YAML 里只有密文,只有集群内部能解密成明文
- 配合 etcd 加密,落盘全链路密文
4.2 部署与使用步骤
1. 安装 SealedSecret Controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
2. 安装 kubeseal 客户端(运维端)
# 下载安装kubeseal命令行工具
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/kubeseal-linux-amd64
mv kubeseal-linux-amd64 /usr/local/bin/kubeseal
chmod +x /usr/local/bin/kubeseal
3. 加密数据库 Secret 示例(以达梦为例)
# 1. 先生成原生Secret模板
cat <<EOF > dmdb-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: dmdb-secret
namespace: dmdb
type: Opaque
data:
sysdba_password: U1lTREJBQDIwMjY=
syssso_password: U1lTU09AMjAyNg==
sysauditor_password: U1lPQURJVE9SQDIwMjY=
EOF
# 2. 加密成SealedSecret
kubeseal --format=yaml < dmdb-secret.yaml > dmdb-sealed-secret.yaml
4. 部署加密后的 Secret
kubectl apply -f dmdb-sealed-secret.yaml
✅ 效果:YAML 文件里全是密文,只有集群内部能解密成原生 Secret,etcd 存储、配置流转全程密文。
4.3 等保加码:开启 etcd 存储加密
光加密 Secret 还不够,etcd 本身也要开启加密,确保落盘全链路密文:
# kube-apiserver 增加加密配置
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
开启后,Secret、ConfigMap 等资源在 etcd 中以密文存储,即使 etcd 备份泄露也无法读取明文。
五、落地实战二:对接国密 KMS(政务金融密评必选)
密评三级场景下,密钥必须由国密 KMS 统一管理,不能存在 K8s 集群里。这是政务、金融核心系统的标准方案。
5.1 核心架构
国密KMS系统(硬件存储密钥)
↓ 动态解密
K8s KMS Provider插件
↓
apiserver解密Secret → 数据库Pod挂载使用
- 密钥生成、存储全在 KMS 里,K8s 集群不保存密钥明文
- 加密解密都调用 KMS 国密接口,符合密评算法要求
- 密钥轮换、审计全在 KMS 侧完成,符合全生命周期管理要求
5.2 落地要点
- 部署国密 KMS 插件:对接合规国密 KMS,作为 apiserver 的加密提供者
- 加密 etcd 所有敏感资源:Secret、加密密钥全部通过 KMS 加密后落盘
- 数据库密钥统一托管:数据库 TDE 密钥、管理员密码全部存在 KMS 中,运行时动态拉取
- 全流程审计:所有密钥访问、解密操作都在 KMS 留痕,满足密评审计要求
5.3 密评加分项
- 密钥由密码机真随机生成,符合 GM/T 0005 要求
- 密钥永不落地明文,全程在密码机内部运算
- 支持密钥自动轮换,每季度自动更换数据库加密密钥
- 双人授权访问,关键密钥操作需要双人复核
六、落地实战三:Sidecar 密钥动态注入(零落地最高安全级)
最高安全等级方案:密钥全程只存在内存中,不写入任何磁盘,Pod 销毁时自动清除,连 K8s 原生 Secret 都不用存,彻底杜绝落盘泄露风险。
6.1 核心原理
- 数据库 Pod 启动时,Sidecar 容器先从国密 KMS 拉取密钥
- 密钥通过内存共享传递给数据库主容器,全程不写 PVC、不写本地盘
- 数据库直接从内存读取密钥,完成加密初始化
- Pod 终止时,内存自动释放,不留任何密钥痕迹
6.2 优势
- ✅ 真正的密钥零落地,磁盘上找不到任何密钥明文
- ✅ Pod 销毁密钥自动消失,无残留风险
- ✅ 密钥轮换无需重启数据库,热加载生效
- ✅ 完全满足密评三级最高要求,密钥与数据彻底分离
6.3 适用场景
- 等保四级、密评三级 + 高安全等级系统
- 核心交易、敏感数据加密场景
- 对密钥安全要求极高的金融、政务涉密系统
七、国产数据库适配:金仓 / 达梦密码安全挂载最佳实践
光加密 Secret 还不够,挂载方式不对也会泄露密码。数据库场景有专属的安全挂载规范,完全符合等保、密评要求。
7.1 两条铁律(一票否决项)
- 绝对禁止用环境变量传密码 :环境变量在
kubectl describe、进程列表、cgroup 里都能看到,等于半公开 - 必须用文件挂载,只读 + 最小权限:密码以文件形式挂载到容器内,权限 0400,仅数据库运行用户可读
7.2 人大金仓 V9 安全挂载配置
# StatefulSet 片段
containers:
- name: kingbase
image: your-registry/kingbase-v9:latest
volumeMounts:
# 密码文件挂载,只读,仅运行用户可读
- name: db-secret
mountPath: /opt/kingbase/secret
readOnly: true
# 绝对不要把密码放env里
volumes:
- name: db-secret
secret:
secretName: kingbase-sealed-secret
defaultMode: 0400 # 权限400,仅属主可读
items:
- key: system_password
path: system.pwd
- key: sso_password
path: sso.pwd
✅ 效果:密码以文件形式存在,权限最小,进程列表看不到,符合最小权限原则。
7.3 达梦 DM9 安全挂载配置
containers:
- name: dmdb
image: your-registry/dm9:latest
volumeMounts:
- name: db-secret
mountPath: /dm/secret
readOnly: true
volumes:
- name: db-secret
secret:
secretName: dmdb-sealed-secret
defaultMode: 0400
items:
- key: sysdba_password
path: sysdba.pwd
- key: tde_key
path: tde.key
✅ 尤其是 TDE 透明加密密钥,绝对不能明文存在配置里,必须通过 Secret 文件挂载,且权限严格收敛。
7.4 进阶:启动脚本读取密码,不进环境变量
数据库启动脚本从文件读取密码,不导出到环境变量,全程只在脚本内存中使用,进一步降低泄露风险:
#!/bin/bash
# 达梦启动示例
SYSDBA_PWD=$(cat /dm/secret/sysdba.pwd)
# 启动数据库,不把密码打印到日志、不导出到全局环境
dmserver /dm/data/dm.ini
八、避坑红线:10 个 Secret 最容易踩的合规致命错误
⚠️ 红线 1:把 Base64 编码当加密
- 后果:等于明文存储,合规直接不通过
- 整改:用 SealedSecret 或 KMS 加密,落盘必须是密文
⚠️ 红线 2:数据库密码放环境变量
- 后果:进程列表、describe 都能看到,半公开状态
- 整改:全部改为文件挂载,只读最小权限
⚠️ 红线 3:Secret YAML 明文提交 Git
- 后果:代码仓库泄露,数据库密码全网可见
- 整改:只提交加密后的 SealedSecret,明文 Secret 永不入库
⚠️ 红线 4:用 ConfigMap 存密码
- 后果:连 Base64 都没有,纯明文,属于低级错误
- 整改:所有敏感信息必须用加密后的 Secret
⚠️ 红线 5:etcd 不加密,Secret 解密后明文落盘
- 后果:etcd 备份泄露,所有密码全丢
- 整改:开启 apiserver etcd 加密,存储层全链路密文
⚠️ 红线 6:密钥和数据存在同一集群
- 后果:密评不通过,不符合密钥与数据分离要求
- 整改:密钥统一存外部国密 KMS,集群只存密文
⚠️ 红线 7:Secret 权限放开,全员可查看
- 后果:开发、运维都能看数据库密码,风险不可控
- 整改:RBAC 严格收敛 Secret 查看权限,仅授权管理员可访问
⚠️ 红线 8:密钥从不轮换,一套用到底
- 后果:不符合密钥生命周期管理要求,密评丢分
- 整改:建立季度轮换机制,泄露时立即更换
⚠️ 红线 9:镜像内置默认密码
- 后果:镜像扩散等于密码扩散,所有人都能拿到
- 整改:镜像不内置任何密码,运行时通过 Secret 注入
⚠️ 红线 10:密钥操作无审计
- 后果:谁改了密码、什么时候改的,全追溯不到
- 整改:所有 Secret 变更走审批流程,操作全留痕审计
九、自测验证:5 步确认密钥存储真的合规
加固完成后,按以下步骤自测,全部通过基本满足等保三级要求,对接 KMS 后满足密评三级。
| 检测项 | 检测方法 | 达标标准 |
|---|---|---|
| 配置文件密文 | 查看 YAML 配置文件 | 无明文密码,均为加密密文 |
| etcd 存储加密 | 导出 etcd 对应 Secret 数据 | 无法直接读取明文,为密文状态 |
| 权限最小化 | 用普通用户账号查看 Secret | 无权限查看,仅授权账号可访问 |
| 挂载方式合规 | 进入容器看密码传递方式 | 以文件形式挂载,不在环境变量中 |
| 文件权限 | 查看密码文件权限 | 权限为 0400,仅运行用户可读 |
密评附加检测项
- 密钥是否由国密 KMS / 密码机生成和存储
- 密钥全生命周期是否有审计记录
- 密钥与数据是否物理分离
- 是否使用国密算法进行加密保护
总结
K8s 数据库 Secret 加密,从来不是加个 Base64 就完事。从轻量的 SealedSecret 满足等保,到对接国密 KMS 通过密评,再到 Sidecar 零落地最高安全级,不同合规等级对应不同方案,核心目标都是密钥不落明文、权限最小化、全链路可审计。
信创合规无小事,数据库密码、加密密钥是核心中的核心,哪怕一个小漏洞,都可能导致整个合规整改推倒重来。把基础做扎实,才能一次性通过验收。
政务选金仓,金融选达梦;MySQL 迁移选金仓,Oracle 迁移选达梦。
📚 专栏推荐:专注 SpringBoot3 + 人大金仓 + 达梦信创实战,持续输出生产级部署、安全合规、性能调优、避坑指南干货,关注不迷路。
觉得文章有用的话,欢迎点赞、收藏、关注三连,后续更新更多信创数据库云原生合规落地的硬核内容。