如何使用客户提供密钥加密GKE Secrets(不使用Cloud KMS)
无Cloud KMS场景下GKE集群Secrets自定义密钥加密操作指南
GKE托管模式下官方内置的应用层Secrets加密能力强制依赖Cloud KMS,如果你明确不使用Cloud KMS服务,可通过以下自定义密钥方案实现Secrets全生命周期加密防护,不需要依赖云厂商托管密钥服务:
前置准备
- 先确认集群版本在1.20及以上,支持KMS v2插件配置,执行
kubectl version --short核对控制面版本,版本过低先完成集群升级 - 提前规划业务维护窗口,配置修改、API Server重启、存量数据加密过程会有短暂的API抖动,不要在业务高峰期操作
- 提前备份所有存量Secrets数据,导出后离线存储,避免配置失误导致数据丢失
步骤1:生成自定义加密密钥
- 在离线、无公网访问的安全设备上生成32字节长度的AES-256加密密钥,不要手动拼接字符串生成弱密钥,直接执行以下命令生成:
head -c 32 /dev/urandom | base64 - 生成的密钥至少做2份离线冷备,存储在加密的离线存储介质中,严格限制密钥访问权限,禁止将密钥明文上传到代码仓库、云存储、集群配置项中。密钥一旦丢失,所有用该密钥加密的Secrets将永久无法解密。
步骤2:部署自托管KMS加密插件
因为无法直接登录GKE托管控制面节点修改原生EncryptionConfiguration配置,需要部署自托管KMS插件实现自定义密钥加密:
- 选择稳定版本的开源KMS v2兼容插件部署在集群的系统节点池,将之前生成的自定义密钥以只读tmpfs卷的方式挂载到插件实例中,不要将密钥写入插件容器镜像或者节点磁盘
- 配置NetworkPolicy限制插件的访问来源,仅允许集群API Server所在网段访问插件的gRPC服务端口,禁止其他业务工作负载调用插件的加密、解密接口
- 修改集群API Server启动参数,注册自托管KMS插件为第一优先级的加密提供者,加密资源范围包含
secrets,将identity(明文提供者)放在加密提供者列表的最后一位,保证存量明文Secrets可以被正常解密 - 滚动重启控制面组件让配置生效,GKE标准集群可通过节点池滚动更新触发控制面配置重载,不要手动强制终止控制面实例。
步骤3:完成存量Secrets加密
- 配置生效后,所有新创建的Secrets会自动通过自托管KMS插件用自定义密钥加密后写入etcd,存量的明文Secrets需要执行批量重写操作完成加密:
kubectl get secrets -A -o json | kubectl replace -f - - 重写完成后验证加密效果:通过etcd客户端直接读取etcd中存储的Secrets键值,确认返回内容为密文格式,无法直接识别明文敏感信息。验证完成后,从加密提供者列表中移除
identity明文提供者,再次重启控制面组件,禁止明文Secrets写入etcd。
步骤4:配套安全加固
- 配置RBAC权限遵循最小权限原则,仅给需要访问Secrets的工作负载、运维账号绑定对应资源的最小操作权限,禁止给普通用户授予Secrets的全量list、get权限
- 定期轮换自定义加密密钥,轮换周期建议不超过90天,新密钥生效后重新执行存量Secrets重写操作,用新密钥重新加密所有Secrets,旧密钥至少保留1个轮换周期用于解密历史备份数据
- 节点操作系统盘配置LUKS本地磁盘加密,用自定义密钥挂载系统盘和数据盘,避免节点物理磁盘被窃取后泄露落盘的Secrets缓存数据
- 工作负载优先采用tmpfs类型卷挂载Secrets,禁止通过环境变量方式传递Secrets,减少Secrets在节点磁盘上的落盘残留
- 开启GKE审计日志,监控所有Secrets资源的访问、修改、删除操作,异常高频访问、非授权IP访问等行为及时触发告警。
注意:自托管KMS插件和自定义密钥的运维责任完全由集群所有者承担,需要定期检查插件运行状态、密钥备份有效性,避免插件故障、密钥丢失导致Secrets不可用影响业务。
内容的提问来源于stack exchange,提问作者Cyber Warrior
相关产品推荐
相关产品推荐

