服务网格 30:控制面和数据面升级怎样验证回退
回退 revision 标签,是否就回到原版本
不是。第 29 篇把已有代理、新工作负载和控制面分开;升级时也要区分“哪个版本生成配置、哪个版本代理正在运行、共享的 CRD 与现有长连接在哪里”。Istio sidecar 可通过 revision 将新控制面接到受控工作负载,再通过滚动重建切换注入版本;已经运行的 Pod 不会仅因为 namespace 的 revision 标签修改就自动换代理。回退标签也不自动恢复此前升级过的 CRD schema 或新版本写入的资源语义。
本篇不提供通用的“跨多少个版本都能混跑”承诺:先选实际仍受支持的 Istio 两个发布版本、Kubernetes 版本及升级路径,查官方版本偏差/兼容表;保存控制面和数据面镜像 digest、网格配置、CRD 修改前后快照。控制面连通、xDS 对新资源 ACK、代理健康只是中间层;最终以带请求 ID 的 orders → inventory-v1/v2 请求和库存应用账本为准。升级事件与坏版本的回滚都须按时间线判断,不能引用别的集群截图作为本实验结果。
Sidecar 与 ambient 的批次不同
Sidecar 的 canary revision 可让一部分 Pod 在重新注入后使用新代理,同时保留上一版控制面服务于旧 Pod;混合期要验证新旧代理都能理解当前路由/安全资源。Ambient 的 istio-cni、ztunnel 通常按节点升级,waypoint 则按共享七层代理升级:一次节点级变更可能影响同节点多个实验工作负载,与单 Pod 注入滚动节奏不同。不能把 sidecar “只迁 5% Pod”机械等价成“只迁 5% 节点流量”;两种模式都要明确 endpoint 撤离、旧 TCP/HTTP2 连接排空及恢复后首次新连接。
| 状态 | 记录的资源版本 | 正例 | 需要构造的失败边界 |
|---|---|---|---|
| 基线 | CRD、控制面、代理、应用镜像 | v1 与外部 stub 可达,拒绝策略生效 | 错误身份或后端不可达按预期失败 |
| 小批升级 | 新旧 revision、实际 Pod/节点代理 | 同请求头走对 v1/v2,长请求完成 | 不兼容字段、拒绝位置变化、连接被重置 |
| 回退后 | 标签、实际重新注入/节点镜像、CRD | 同一正反用例复原 | 遗留 CRD/策略仍使旧代理异常 |
安全的复跑顺序
首先在 examples/service-mesh/ 做只读前置检查,未确认具名合成 context 时不执行升级/回退:
1 | |
具备隔离集群、资源与已冻结版本后,先锁定业务输入 sku=paper、请求 ID、长请求时长与正确/错误身份;记录旧控制面下路由、授权、实际响应与账本。再创建新 revision,检查旧新代理分别从哪个控制面取配置,分批重建单个实验 Pod;每批核对 Pod 容器镜像 digest、控制器配置、代理当前配置、实际新旧连接以及应用响应。引入受控不兼容策略或长连接边界作为负例时,失败断言必须非零;只要出现预期拒绝变放行、未知的重复账本副作用或无法收敛,就停止扩批。恢复时按支持的官方步骤切回事先保留的旧控制面与受支持 CRD,重新创建目标 Pod,重放同一输入,确认响应与拒绝行为,而不是只看 revision 标签值。对 ambient 还需分别测 ztunnel 节点升级与 waypoint 升级/回退后的流量路径。
尚未安装本篇需要的 Kubernetes/Istio 实验环境。双 revision、CRD 兼容、节点 ztunnel 与长连接均 NOT_RUN;本篇表格是待验收矩阵。只在具名隔离实验 context 执行升级,不自动清理共享 CRD。
在默认控制面旁安装一个明确 revision
本例只演练 Istio 1.27.0 到 1.27.1 的 patch revision 切换。它是用于复现实验的版本组合,不是当前生产升级推荐;实际升级还应按目标版本重新检查支持周期和安全公告。基础集群是 kind-service-mesh-sidecar,旧控制面采用默认 revision,新控制面命名 lab-1271,下载的两个 istioctl 应分开保存并校验发行包。 1.27.1 官方发布说明列出该 patch 的具体修复。
1 | |
脚本验证新客户端实际返回 1.27.1,先保存 CRD,再安装 minimal profile。revision 隔离控制面部署与注入选择,但不使 CRD、集群级 webhook 或其他共享资源变成互不影响的两份。安装成功后应比较 CRD schema 与 webhook 匹配规则;这一步不是业务切换。
切换使用 namespace 标签。旧 istio-injection=enabled 优先于 revision 注入标签,因此必须先去掉旧标签再设 istio.io/rev=lab-1271。标签不会重写现有 Pod;脚本仅重建 inventory-v2,以便对照 v1 旧代理与 v2 新代理。
1 | |
这个灰度边界有一个实际限制:namespace 中任何此后重新创建的其他 Pod 也会使用新 revision。若要求只有一组服务迁移,应分独立 namespace 或显式管理 Pod 注入标签,不能依赖“本次只重启了 v2”保证长期隔离。保存 v1/v2 实际 proxy 镜像、控制面连接和业务版本;仅检查 namespace 标签不足以证明代理升级。
请求验收沿用第 34 篇 header 路由:普通请求去 v1,x-canary: yes 去 v2,检查两者的报价与错误身份拒绝。可用实验性错误路由模拟发布判据触发,但不要把路由错误归因于新二进制。记录新旧代理活动配置差异,先区分配置下发、连接与应用故障。
1 | |
回退恢复默认注入选择并重建 v2;旧 Pod 没有被重建时,切标签并不会把已运行的新代理降级。回退后再次确认所有预期工作负载连接旧控制面且正负请求契约仍成立。只有不再有工作负载依赖 lab-1271 才能卸载该 revision:
1 | |
不要使用 --purge 完成本例清理,它会影响共享安装。当前真实 revision 切换为 NOT_RUN。原则是把安装、注入选择、Pod 重建、流量验证与旧版本回收分别安排门禁。固定版本官方 canary upgrade 文档 说明 namespace 注入标签优先级与存量代理行为。
练习与参考解答
- 把 namespace revision 标签从新版本改回旧版本,但没有重建 Pod。能宣布 sidecar 已回退吗?参考解答:不能。先检查实际 Pod 内代理镜像和启动时间、代理连接到哪个控制面及当前配置,再发相同请求/负例;只有标签变化不说明已有代理二进制改变。
- 新版 CRD 允许一个字段,旧版控制面不认识;回退了工作负载 revision 后出现路由异常,怎样设计不破坏他人资源的对照?参考解答:只在隔离 namespace 保留旧版基线和新字段实验资源,保存 CRD 与资源快照,按支持矩阵比对旧新代理当前配置及带 ID 的请求;必要时在审批后的隔离集群用兼容格式重写实验资源,而不是直接删共享 CRD。回退需以客户端与库存结果重新验收。
官方参考与系列导航
- Istio canary upgrade 与 支持版本:revision 选择与版本偏差核验入口。
- Istio ambient upgrade:ztunnel/CNI、waypoint 与节点范围的升级顺序须与固定版本一致。
- Kubernetes CRD versioning:共享 schema 与回退语义;不能把 revision 标签当作 CRD 回滚。
