Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/agent-collab/addon-patch-image-build-handoff-roles-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ Build 方不负责选择 PR,也不要复用旧 tag 覆盖不同镜像。
3. patch controller Deployment 的 image。
4. 重建 pod 后读取 `imageID`,确认它等于本次 build 的镜像。

## Sideload + tag 别名陷阱

sideload 把镜像写进节点后,container runtime 上的同一个镜像可能同时挂着多个 tag。例如先用 base tag 拉过一次 base 镜像,又把 patch 镜像 sideload 进同一仓库时,runtime 会把 base tag 也指向 patch 镜像。kubelet 报到 pod 的 `status.containerStatuses[*].Image` 时,可能选其中**任意**一个 tag,并不保证用的是你 spec 里写的 patch tag。

如果 chart 用 tag 引用镜像,spec.Image 里是 patch tag,但 `status.Image` 显示成 base tag,KubeBlocks InstanceSet controller 现在还是用严格 tag 字符串比较来判 ready:tag 不一致 → 控制器认为 image 没匹配 → InstanceSet 不会标为 ready。

KubeBlocks 主分支的 InstanceSet controller 已经把 digest-pinned 场景接到 `status.ImageID` 兜底,但 tag-only 场景仍按严格 tag 比较,因为 controller 没法在运行时把 spec tag 解析回 digest 来分辨「同 digest 多 tag 别名」和「正常 image upgrade 待生效」这两个外观完全相同的情况。

所以 sideload 场景要么走出口 1,要么走出口 2:

1. **删 base / 旧 tag 别名**:sideload patch 镜像后,把 runtime 上指向同一 digest 的 base / 旧 tag 删干净,只保留 patch tag。例:containerd `ctr -n k8s.io image rm <old-tag>`;docker `docker image rm <old-tag>`。tag 唯一以后 kubelet 报给 status 的就是 patch tag,InstanceSet 能正常 ready。
2. **chart 改成 digest pin**:把 chart 里的 image 引用从 `repo:tag` 改成 `repo@sha256:...`。controller 拿到 digest pin 后,即使 `status.Image` 用 tag 形式不带 digest,也会用 `status.ImageID` 的 digest 兜底比较,能直接接受 sideload 镜像,不再依赖 tag 唯一性。

不论走哪条,最后都按一般规则核对 pod `imageID` 等于本次 build sha 作为收口,不要靠"pod 起来了"代替。

## 反模式

- 临时分支用 `release-*` 前缀。
Expand Down