系统设计面试:如何迁移 Kubernetes KMS v2 并证明 Secret 已加密?
题干与适用场景
平台团队需要保护 etcd 中的 Secret。集群有多个 kube-apiserver、外部 KMS 插件和大量历史对象,且不能在迁移时停止发布。请设计配置变更、密钥轮换、存量重写、验证、监控和回滚。
面试官考察点
- 是否理解 KMS v2 的信封加密边界和 DEK/KEK 关系。
- 是否区分“新写入加密”与“历史对象已经重写”。
- 是否能处理多 apiserver、KMS 不可用、轮换和并发更新。
- 是否用 etcd 取证与 API 回读证明结果,而非只看配置文件。
回答前需要澄清的问题
- 当前 Kubernetes 版本、KMS 插件版本和高可用拓扑是什么?
- 需要保护哪些资源,是否包含自定义资源和审计日志?
- 外部 KMS 的可用性、延迟、密钥轮换与灾备承诺是什么?
- 允许的控制面发布窗口、回滚期限和合规证据格式是什么?
30 秒回答框架
先在非生产集群验证 KMS v2 插件和权限,再把 KMS 作为首选 provider、保留旧 provider 作为读取回退,滚动更新每个 kube-apiserver。新写入会加密,但历史对象必须逐个无操作更新或用存储版本迁移重写。验证包括 API 读回、etcd 前缀取证、KMS 指标、故障演练和审计记录。确认所有对象完成重写后再移除旧 provider,并保留可审计的回滚窗口。
分步骤深入解答
1. 明确加密模型
Kubernetes 使用信封加密:数据加密密钥(DEK)加密资源,密钥加密密钥(KEK)由外部 KMS 保护。KMS v2 通过服务端缓存和每个 API server 的 DEK 设计降低请求开销,但不等于 etcd 自动重写所有旧数据。
2. 先验证插件和权限
在隔离集群测试 socket、身份、超时、重启和 KMS 不可用行为。确认 kube-apiserver 能解密旧 provider 写入的对象,也能用新 provider 写入新 Secret。记录延迟、错误、缓存命中和 KMS 调用量。
providers:
- kms:
apiVersion: v2
name: external-kms
endpoint: unix:///var/run/kms/plugin.sock
- aescbc:
keys:
- name: old-key
secret: <base64-secret>3. 高可用滚动切换
先把新 KMS provider 放在配置首位,保留旧 provider 读取回退,再逐个重启 kube-apiserver。每一步确认 API 读写、leader 无关的并发请求和审计输出,避免同时重启全部控制面。配置文件和插件版本必须可回滚。
4. 重写存量对象
只切换 provider 只影响后续写入。对 Secret 及其他受保护资源执行分批无操作更新,或使用存储版本迁移工具触发重写;遇到冲突要重试。按命名空间分片、限速并记录对象版本,防止一次性更新压垮 API server、etcd 或 KMS。
5. 验证加密证据
创建新 Secret 后从 etcd 读取原始字节,确认以 KMS v2 加密前缀存储;再通过 API 读取并比较明文。抽样旧对象和每类资源,统计尚未重写数量。API 读回成功不能单独证明磁盘上的值已加密。
6. 轮换、故障和回滚
轮换 KEK 后保持旧 KEK 可解密,逐批重写并监控失败。演练 KMS 超时、socket 断开、单个 apiserver 回滚和插件升级。若错误率超阈值,暂停重写,恢复旧配置读取数据;只有确认新 provider 稳定和存量完成后才移除旧 provider。
高质量示范回答
我会先在隔离集群验证 KMS v2 插件、权限、延迟和故障行为。生产配置把 KMS v2 放在首位,短期保留旧 provider 作为读取回退,逐个滚动重启 kube-apiserver。新写入加密后,再按资源和命名空间分批无操作更新,记录进度、冲突和重试。验证既包含 API 回读,也包含 etcd 前缀和抽样对象取证;确认历史对象完成重写后才移除旧 provider。KEK 轮换和 KMS 故障都要有演练、阈值和局部回滚方案。
常见错误
- 只改配置不重写旧对象 → 历史明文仍在 etcd → 分批更新并统计完成度。
- 同时重启所有 apiserver → 控制面中断 → 逐个滚动并观察健康指标。
- 只看 API 读回 → 无法证明底层存储加密 → 做 etcd 原始字节取证。
- 立即删除旧 provider → 旧数据无法解密 → 等迁移完成并保留回滚窗。
- 忽略 KMS 延迟和缓存 → 高峰时 API 请求雪崩 → 压测、限速和监控调用量。
追问及应对
配置 KMS v2 后,新 Secret 是否全部安全?
新写入会按首选 provider 加密,但旧对象不会自动变更。必须执行存量重写,并以 etcd 证据确认。
KMS 暂时不可用时能否继续写入?
取决于插件缓存和配置,不能假设一定可用。应预先定义超时、拒绝写入、告警和恢复后的重试策略,并演练控制面行为。
为什么保留旧 provider 是风险而不是永久方案?
它在迁移窗口内提供可回滚的解密能力,但扩大了密钥和配置边界。存量确认完成后应移除,并保留轮换与恢复证据。