Skip to content

fix: exclude status-only API v2 resources from readiness gating#2745

Open
yangkaa wants to merge 2 commits intoapache:masterfrom
yangkaa:fix/readiness-ignore-status-only-apiv2-resources
Open

fix: exclude status-only API v2 resources from readiness gating#2745
yangkaa wants to merge 2 commits intoapache:masterfrom
yangkaa:fix/readiness-ignore-status-only-apiv2-resources

Conversation

@yangkaa
Copy link
Copy Markdown

@yangkaa yangkaa commented Apr 12, 2026

背景

这个改动用于修复 apisix-ingress-controller 在启动阶段的 readiness 等待逻辑问题。

在当前实现中,controller 在启动后不会立刻开始第一次全量同步,而是会先等待一批资源完成初始 reconcile。只有当这些资源都被标记为 ready 后,provider 才会进入:

starting provider, waiting for readiness

然后继续进入:

Ready detected, starting sync loop

问题现象

当前 API v2 readiness 注册集合中包含:

  • Ingress
  • ApisixRoute
  • ApisixGlobalRule
  • ApisixPluginConfig
  • ApisixTls
  • ApisixConsumer
  • ApisixUpstream

但是在 v2.0.1 中:

  • ApisixUpstreamReconciler
  • ApisixPluginConfigReconciler

都只是状态更新型 controller,本身不会调用 Readier.Done(...)

这意味着:

  1. 这两个资源会在启动时被 readiness manager 注册为“待完成”对象。
  2. 但它们并不会在 reconcile 完成后主动从 readiness 集合中移除。
  3. 一旦这类对象在 controller 启动前已经存在,provider 就可能一直卡在 startup readiness 阶段。
  4. 最终只能等 5 分钟超时后,provider 才开始第一次全量同步。

根因分析

这里的问题不是偶发性的“done 丢失”,而是 readiness 注册集合本身就包含了不应该参与 startup gating 的资源。

从职责上看:

  • ApisixUpstream / ApisixPluginConfig 在当前版本中并不直接驱动 dataplane 配置下发。
  • 真正把这些对象纳入翻译流程的是 ApisixRoute controller。
  • ApisixRouteReconciler 已经会 watch 这两类对象变化,并且它自身会调用 Readier.Done(...)

因此,把 ApisixUpstreamApisixPluginConfig 作为 startup readiness 的硬性等待条件,既没有必要,也会造成启动阻塞。

修复方式

本 PR 的修复策略是:

  • ApisixUpstream 从 API v2 readiness 注册集合中移除
  • ApisixPluginConfig 从 API v2 readiness 注册集合中移除

保留真正参与 provider 同步、并且已有 Done() 调用的资源:

  • Ingress
  • ApisixRoute
  • ApisixGlobalRule
  • ApisixTls
  • ApisixConsumer

另外补充了一个单元测试,用于约束 readiness 注册列表,避免后续回归。

验证结果

包级测试

执行:

env GOPROXY=https://goproxy.cn,direct GOSUMDB=sum.golang.google.cn \
go test ./internal/manager/... ./internal/controller/... ./internal/provider/apisix/...

测试通过。

现场验证

在实际环境中验证了如下场景:

  • buildpack-upstream 在 controller 启动前已存在
  • 使用原版 2.0.1 时:
    • readiness 会注册 ApisixUpstream
    • provider 卡在 waiting for readiness
    • 首次全量同步延后约 5 分钟
  • 使用补丁后:
    • startup readiness 不再注册 ApisixUpstream
    • Ready detected, starting sync loop 在启动后秒级出现
    • 第一次全量同步立即发生
    • 原先受影响的 TCP 路由(如 7070)不再出现 5 分钟不可用窗口

这样修复的原因

这个修复没有选择去给 ApisixUpstreamReconcilerApisixPluginConfigReconciler 强行补 Done(),原因是:

  1. 这两个 controller 在当前版本中本来就只是状态更新型 controller。
  2. 它们不应该成为 startup first sync 的 gating 条件。
  3. 真正负责把它们翻译到 provider 配置中的是 ApisixRoute controller,而后者已经有完整的 readiness 生命周期。

所以从语义上讲,缩小 readiness 注册范围,比给状态型 controller 添加额外同步语义更稳妥。

Issue 关联

关联以下 issue:

@Baoyuantop
Copy link
Copy Markdown
Contributor

Hi @yangkaa, please fix failed CI

@yangkaa
Copy link
Copy Markdown
Author

yangkaa commented Apr 14, 2026

Hi @yangkaa, please fix failed CI

I fixed the missing license header in the new test file.

For the remaining failed CI jobs, they look unrelated to this PR. The E2E jobs are failing before the test suite starts, in the existing workflow step
that extracts ADC from ghcr.io/api7/adc:dev:

docker cp adc-temp:main.js adc.js

with:

Could not find the file main.js in container adc-temp

So the current failures seem to come from the CI workflow / ADC dev image layout rather than from the readiness-gating change in this PR.

@Baoyuantop Baoyuantop requested a review from AlinsRan April 15, 2026 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants