From 7d82c08bbf0d2f8d34a986a71615ff1df8cb2209 Mon Sep 17 00:00:00 2001 From: Wei Cao Date: Mon, 18 May 2026 23:29:31 +0800 Subject: [PATCH] docs(agent-collab): add sideload tag aliasing trap section to patch image handoff guide When sideloading a patch container image into a node where the same image already had another tag (typically a base tag), the runtime keeps both tags pointing at the same digest. kubelet may report any of those tags on pod status.Image, not necessarily the tag in PodSpec. With a chart that references the image by tag, this causes InstanceSet controller's strict tag string comparison in isImageMatched to fail, and the InstanceSet does not mark ready, even though the running image data is correct. Document the trap and the two operational exits: 1. Drop the base/old tag alias from the runtime so the patch tag is the only tag kubelet can surface (e.g. ctr -n k8s.io image rm ). 2. Pin the chart image reference to a digest. InstanceSet controller's main-branch isImageMatched already consults status.ImageID as the canonical digest source for digest-pinned specs. Either exit closes via the existing pod imageID equals build sha verification rule, not via 'pod is up'. --- ...addon-patch-image-build-handoff-roles-guide.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/agent-collab/addon-patch-image-build-handoff-roles-guide.md b/docs/agent-collab/addon-patch-image-build-handoff-roles-guide.md index 79514d1..201f244 100644 --- a/docs/agent-collab/addon-patch-image-build-handoff-roles-guide.md +++ b/docs/agent-collab/addon-patch-image-build-handoff-roles-guide.md @@ -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 `;docker `docker image rm `。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-*` 前缀。