只开 requiresRepublish 没用?Secrets Store CSI 自动轮换还得加这个参数
Secrets Store CSI Driver 实现自动轮换需同时满足驱动版本不低于 v1.6.0、CSIDriver 开启 requiresRepublish 字段,且 DaemonSet 显式启用 –enable-secret-rotation=true 参数。
只把 CSIDriver 的 requiresRepublish 设为 true,你的集群依然无法实现自动轮换。很多管理员以为开启了这个机制,驱动就会自动去拉取新密钥,结果发现控制器更新了状态,应用里的数据却还停留在旧版本。这就像给车装了油门(感知变化),却没踩下离合器(执行更新)。
为什么单靠 requiresRepublish 不够?
仅设置 requiresRepublish 字段只能让驱动感知外部变化,若未显式开启旋转开关,轮询功能默认关闭,导致驱动通知状态变更却不执行实际拉取新数据动作。
自 v1.6.0 版本起,Secrets Store CSI Driver 确实依赖 RequiresRepublish 机制来感知外部变化[1]。但这只是告诉驱动“有东西变了”,它本身并不包含主动去 Provider 拉取新数据的开关。如果缺少显式配置,轮询功能默认处于关闭状态,驱动只会通知状态变更,而不会执行实际的更新动作。
你必须手动在 DaemonSet 或 Deployment 的启动参数中,添加 --enable-secret-rotation=true。这一步是强制性的,没有它,驱动就不知道要开启从外部源获取新机密的逻辑。若遗漏了第二个参数,即使控制器层面显示更新成功,应用进程读取挂载文件或环境变量时,依然拿不到新值。这种“假生效”往往是因为默认配置下轮询功能未激活,导致驱动只负责通知,不负责拉取。
配置合格的三个判断标准
- 版本检查:确认驱动版本不低于 v1.6.0,否则不支持该机制。
- 参数核对:在容器启动命令中明确看到
--enable-secret-rotation=true。 - 对象验证:
CSIDriver资源中spec.podInfoOnMount.requiresRepublish已设为true。
如何检查并配置 CSI 驱动以支持自动轮换
配置 Secrets Store CSI Driver 支持自动轮换必须确保运行在 v1.6.0 及以上版本,并同步检查 CSIDriver 对象标签与 DaemonSet 启动参数是否包含显式旋转开关。
只给 CSIDriver 对象打上 requiresRepublish 标签,应用依然拿不到更新后的密钥。Secrets Store CSI Driver 必须显式开启旋转开关,且运行在 v1.6.0 或更高版本上,这一步做不对,后续所有操作都是空转[1]。别猜环境是否就绪,直接动手核查这三项核心指标。
三步验证驱动配置是否正确
确认 CSIDriver 状态 执行
kubectl get csidriver secrets-store.csi.k8s.io -o yaml。在输出中查找spec.republish字段,确保其值为true。如果该字段缺失或为false,驱动不会触发重新发布流程[1]。核对驱动版本与启动参数 这是最容易被忽略的环节。进入部署驱动的 DaemonSet 或 Deployment 命名空间,查看容器定义。
- 版本门槛:确认镜像标签对应 v1.6.0+。旧版本根本不支持此功能。
- 关键参数:在
args列表中必须包含--enable-secret-rotation=true。仅设置requiresRepublish而不加此参数,控制器更新不等于应用生效[1]。
审查轮询日志 重启 Pod 后,通过
kubectl logs <driver-pod-name>查看实时日志。搜索关键词 “polling” 或 “rotation”。若看到周期性刷新记录,说明轮询机制已激活;若日志静默无声,说明配置未生效。
| 检查项 | 合格标准 | 常见错误配置 |
|---|---|---|
| CSIDriver spec | republish: true |
字段缺失或设为 false |
| 容器镜像版本 | v1.6.0 及以上 | v1.5.x 或更低版本 |
| 启动参数 args | 含 --enable-secret-rotation=true |
缺少该参数或未设为 true |
| 日志行为 | 出现周期性轮询记录 | 无相关刷新日志 |
修改完 DaemonSet 或 Deployment 配置后,必须执行滚动重启让新参数生效。对 DaemonSet 而言,删除旧 Pod 即可触发重建;对 Deployment,执行 kubectl rollout restart deployment/<name>。只有完成重启,新的挂载文件才能被应用进程读取,环境变量也才会更新[1]。
新手最容易在这里栽跟头:很多人以为改完 DaemonSet 配置就能立刻生效,忽略了 Kubernetes 的滚动策略可能导致旧 Pod 长时间存活。 如果你使用的是默认的滚动更新策略(RollingUpdate),且设置了较长的 maxUnavailable 或 minReadySeconds,新参数的 DaemonSet Pod 可能已经启动了,但旧的、未加载新参数的 Pod 依然在承担流量。此时,你观察到的“日志静默”其实是旧 Pod 的行为,而非新配置无效。正确的做法是在修改配置前,先临时将 maxUnavailable 调高至 100%(即 --set rollingUpdate.maxUnavailable=100%),或者直接使用 kubectl delete pod -l app=<driver-label> 强制立即重建所有驱动实例,确保所有节点上的驱动都立即使用新的 --enable-secret-rotation=true 参数运行,然后再恢复正常的滚动策略。这样能彻底避免新旧配置混用导致的“半吊子”轮换现象。
轮换生效后的验收标准:从挂载文件到环境变量
轮换生效的验收标准不仅依赖挂载文件的 resourceVersion 更新,更需验证应用进程是否真正读取并使用了从 Provider 获取的最新凭证内容。
Secrets Store CSI Driver 更新了挂载内容,并不代表你的应用立刻拿到了新密钥。很多团队误以为只要 Secret 的 resourceVersion 变了就万事大吉,结果业务还在用旧凭证。真正的验收必须盯着应用怎么“吃”这些机密。
如何判断应用真正读取到了新机密?
首先区分你的应用是读文件还是读环境变量,两者的刷新逻辑完全不同。
对于文件挂载类应用
驱动会把新文件写进 Pod 的挂载目录,但进程不会自动感知。如果你的应用像 Nginx 或 Java 服务那样依赖配置文件,必须确认它具备热加载能力。检查手段很简单:在轮换触发后,观察应用日志是否有“重新加载配置”的记录,或者通过 kill -HUP 信号验证配置是否实时生效。如果应用没有热重载机制,哪怕文件变了,它依然在跑旧数据[1]。
对于环境变量类应用 环境变量的注入发生在容器启动瞬间。一旦 Pod 运行起来,里面的变量就是定值。这意味着无论驱动怎么更新底层的 Kubernetes Secret,正在跑的容器根本看不到变化。要拿到新值,Pod 必须经历滚动升级或完全重启。这时候光看 Secret 变了没用,得盯着 K8s 的滚动策略和就绪探针(Readiness Probe)的配合情况,确保重启窗口内流量被正确切断,且新版本容器顺利接管[1]。
验收的核心不是资源版本 不要只盯着 Secret 对象的元数据变化做结论。真正的“轮换无中断”判定依据是一个综合框架:
- 业务监控:确认认证失败率、解密错误等关键指标未因轮换波动。
- 就绪探针:确保旧实例在完全停止前已不再接收流量。
- 实例冗余:保证滚动期间集群有足够副本支撑负载。
只有当上述环节全部跑通,才能证明应用真正读取到了新机密且服务未中断。否则,所谓的自动轮换只是后台的一场无效数据更新[1]。
FAQ: 关于 CSI 自动轮换的常见问题
Q: 我设置了 --enable-secret-rotation=true,但日志里还是没有轮询记录?
A: 请再次确认驱动版本是否为 v1.6.0 以上,并且检查 CSIDriver 资源中的 republish 字段是否已正确设置为 true。这两个条件缺一不可。
Q: 环境变量里的密钥真的不能动态更新吗? A: 是的,Kubernetes 的环境变量在容器启动时注入,运行时是静态的。即使底层 Secret 更新了,正在运行的容器也不会感知。必须重启 Pod 才能获取新值。
Q: 为什么我的应用没有报错,但密钥还是旧的? A: 这通常是因为应用缺乏“热加载”机制。文件被驱动更新了,但应用进程没有收到信号去重新读取文件内容,导致它继续使用内存中的旧缓存。