已关闭
【证书生成】EnsureCerts 阶段 lookupRegularCert 缺少重试机制,Informer cache 同步延迟导致 "certs need generate again" 错误 #185
ZYH-ang创建于 8月13日关闭于 9月11日
8月13日 添加了label:sig/sig-Installation
openFuyao-bot
8月13日 评论:
8月13日 评论:
欢迎来到 openFuyao 社区
Hey @ZYH-ang , 感谢你对社区的贡献.
机器人使用手册
有关指令的使用,可以点击 此处 查看详情。开发人员可以在每个PR或Issue下方评论特定指令来触发机器人任务。
联系指引
有疑问可以联系 SIG: sig-Installation ,
维护者是: @foxbit, @javadoors, @regandy, @xuyouhong, @zqw1 ,
审核者是: @piamposer-li .


8月13日 删除了label:sig/sig-Installation
8月13日 关联了看板:openFuyao - v26.09问题单
8月13日 关联了里程碑:v26.09
8月13日 关联了pull request:fix(certs): add retry mechanism to lookupRegularCert for Informer cache sync delay
8月13日 关联了pull request:fix(certs): add retry mechanism to lookupRegularCert for Informer cache sync delay
8月13日 issue优先级由 无优先级 改变为 不重要
8月31日 issue状态由 开启 改变为 待测试
9月11日 issue状态由 待测试 改变为 已完成
9月11日 关闭了 issue
9月11日 将 ZYH-ang 设为负责人
环境信息/ Environment
问题简述/ Brief Description
EnsureCerts 阶段中,
LookUpOrGenerate()创建证书 secret 后立即调用NeedGenerate()检查,由于lookupRegularCert()没有重试机制,Informer cache 同步延迟导致client.Get()返回 NotFound,误判证书不存在,返回certs need generate again错误,集群进入 InitializationFailed 状态。该问题在本地单用例执行时不触发(环境干净、API server 负载低),仅在流水线中前序批次执行后(API server 负载较高)才暴露。问题详情&复现步骤 / Details & Reproduction Steps
installation.post-init批次测试后,继续执行installation兜底批次LookUpOrGenerate()成功创建证书 secret(写入 API Server / etcd)NeedGenerate()调用lookupRegularCert()通过client.Get()读取 Informer cacheclient.Get()返回 NotFoundlookupRegularCert()直接返回false(无重试),NeedGenerate()返回trueExecute()返回错误"certs need generate again"关键日志:
注意:
the object has been modified是附带错误(状态更新时的并发冲突),certs need generate again才是触发错误。复现命令:
# 本地单用例执行通常不会触发(环境干净) ginkgo --label-filter="install-chart-from-https-repo" ./e2e/installation/ # 需要在流水线环境中复现:先执行前序批次(pre-init、post-init、mgmt),再执行 installation 兜底批次期望结果/ Expected Results
EnsureCerts 阶段应能正确处理 Informer cache 同步延迟,在
LookUpOrGenerate()创建 secret 后,NeedGenerate()检查时应能正确读取到已创建的 secret,集群正常进入下一阶段。实际结果/Actual Results
lookupRegularCert()通过 controller-runtime 的client.Get()读取 Informer cache,由于 cache 异步更新,Create 后立即 Get 可能返回 NotFound。lookupRegularCert()没有重试机制,一次 Get 不到就认为"不存在",导致NeedGenerate()返回 true,触发certs need generate again错误。可疑源码模块:
pkg/certs/generator.go—lookupRegularCert()函数(L354-364)pkg/phaseframe/phases/ensure_certs.go—Execute()函数(L55-69)建议排查方向:
根因分析: controller-runtime 的
client对读写操作走不同路径:client.Create()(写)→ Direct client → 直接写入 API Server / etcdclient.Get()(读)→ Cached client → 读 Informer Cache(本地缓存)代码对比:
lookupKubeConfigCert()(L367-414)已有重试机制(kubeConfigMaxRetries次重试 +kubeConfigRetryDelay间隔),但lookupRegularCert()(L354-364)完全没有重试,NotFound 直接返回 false。修复方案建议:
lookupRegularCert添加重试机制,与lookupKubeConfigCert保持一致Execute()中NeedGenerate()返回 true 时,不直接返回 error,而是返回ctrl.Result{RequeueAfter: 2*time.Second},利用 controller-runtime 的 reconcile 循环天然重试能力LookUpOrGenerate()和NeedGenerate()之间增加短暂等待,确保 cache 同步完成为什么本地通过、流水线失败: 本地环境干净,API server 负载低,Informer cache 同步快,Create→Get 之间 cache 已同步。流水线中前序批次(pre-init、post-init、mgmt)执行后,API server 中有更多资源在 watch,informer 同步压力更大,cache 同步窗口被拉长,更容易触发此问题。
附件:
e2e-artifacts/installation/installation_test_1799argo/e2e-test/e2e-test.yaml