服务网格 28:Sidecar 迁移 Ambient 如何验证与回退
给 namespace 换标签,为什么不足以宣布迁移完成
第 04 篇描述随业务 Pod 部署的代理,第 26 篇将四层移到 ztunnel,第 27 篇讨论七层 waypoint。三者覆盖点不同:**标签声明意图,Pod 是否仍有 sidecar、流量经哪个代理及安全策略在哪里执行,必须分别取证。**对于已有 sidecar 的 Pod,仅改 namespace 标签不能让其就地消失;混合阶段须按冻结的 Istio 版本核验代理优先级、滚动重建和路由结果。
迁移不是换一个部署模式名称,而是给每个已有能力重新确定执行位置。以累计应用为例,orders → inventory 的身份与四层保护可以通过 ztunnel 重新验收;请求头灰度到 v2、对 POST /reserve 的方法级拒绝要核对 waypoint 的附着及七层策略。sidecar 的 VirtualService/DestinationRule subset 不能原样假定可作为 ambient 中 HTTPRoute 的版本后端;要按目标发布版支持范围,用实际可用的 v1/v2 Service 和 endpoint 验证。请求返回正确库存版本是必要证据,不是足够证据:仍可能绕过授权点。
先盘点能力,再转换策略
| 迁移前的观察 | ambient 目标执行点 | 必须重跑的反例 |
|---|---|---|
| sidecar 对等身份与传输保护 | ztunnel L4 与 HBONE 相关连接段 | 错误 ServiceAccount、未入网格来源 |
| 以请求头分流 v1/v2 | 已绑定 waypoint 的 HTTPRoute | 错误头、空后端、直达 Pod IP |
| 方法/路径级写入拒绝 | waypoint 附着的七层授权 | POST /reserve 后查看账本是否仍新增 |
| 应用账本与重试 | 应用自己的去重与可追溯日志 | 响应丢失后重复操作 ID |
表中 L4 身份和 L7 来源不可以替换着读:当请求经过 waypoint 时,目标 ztunnel 看到的对等身份可能是 waypoint;sidecar 来源与网格外来源是否走 waypoint 又取决于实际拓扑。若过早把目标端四层策略收紧为“只许 waypoint”,未迁移的合法 sidecar 调用可能被拒绝;若为避免误拒而把策略全放开,旁路却可能绕过七层拒绝。顺序应该是先确认每种来源的实际路径,再在隔离流量中验证强制约束。
逐批转换和回退的实验入口
只在 examples/service-mesh/ 先对具名隔离 context 运行无副作用检查:
1 | |
具备相容的 Kubernetes/Istio/ztunnel 版本及镜像后,保存同一份验收输入:只读 sku=paper、带/不带 canary 头、预期和错误 ServiceAccount、POST /reserve 的唯一操作 ID;每次尝试生成单独 X-Request-ID。先跑 sidecar 基线,取 Pod 容器列表、代理活跃 route/cluster、证书公开元数据及账本。再部署 waypoint、绑定目标并先验证“创建未绑定时规则不生效”的负例;逐批调整入网并重建应用 Pod,从容器列表核对 sidecar 是否仍在,从 ztunnel/waypoint 记录核对真实路径。每批对比响应版本、拒绝位置及账本条数,差异超出预先门禁就返回非零并停止扩散。
回退同样要求真实请求验收:恢复前一版本的选择标签与策略、按批准的批次重建 Pod,检查 sidecar 确实回来、旧长连接处理方式符合预期,再重跑正反用例。只“kubectl 回写标签”不保证已有连接重选路径;只看到健康检查 200 也不能替代七层拒绝恢复。任何故障只对隔离合成服务注入,先保存快照再回滚,不清理其他环境。
尚未建立 sidecar/ambient 混合集群,全套迁移、回退、旁路和新旧连接对照均 NOT_RUN。本机进程成功和文章中的矩阵是待执行的验收设计,不是已迁移结果。
迁移整组调用链,而不只重建库存
mainline/28/switch.sh 在本系列专用 namespace 中切换五个 Deployment:frontend、orders、inventory-v1/v2、external-stub,并重建 mesh-probe 与 wrong-probe。namespace 标签影响其中全部工作负载,不能移除 ambient 纳管后只为库存注入 sidecar,否则原 ambient 调用方失去身份,无法访问 STRICT 库存。此脚本要求该 namespace 只有这组实验应用与本章 waypoint;其他业务应使用各自独立的迁移批次。
实验采用装有 ambient profile 的独立集群,先确认可用的 sidecar 注入服务、Istio CNI 与 ztunnel。先暂停实验请求并保存 Deployment、namespace 标签与策略,再在同一个集群切换。以下命令先构造完整 sidecar 基线:
1 | |
sidecar 分支取消库存 waypoint 绑定、移除 namespace 的 ambient 标签并开启注入。它保留 STRICT,应用 sidecar-l7.yaml 允许 orders 的 GET /quote,删除更宽的 L4 ALLOW,并用第 34 篇 VirtualService/DestinationRule 提供 v1/v2 header 路由。随后重建全部五个 Deployment 和两个探针;验收须确认调用方和目标均含 istio-proxy、证书身份正确,再发送正负请求。标签或 rollout 成功不能代替这些检查。
迁入 ambient 时,先创建 waypoint 和 HTTPRoute,但暂不绑定。ambient 分支取消旧绑定、移除 sidecar L7 策略与 VirtualService,恢复第 26 篇 STRICT/L4 策略,切 namespace 标签,然后重建整组工作负载。确认所有业务 Pod 和探针都不再含 sidecar,且 ztunnel 已收录其地址与身份后,才把库存绑定到 waypoint:
1 | |
bind 先为目标安装允许 orders 与 waypoint 两种来源身份的过渡 L4 策略,再设置 Service 绑定。先重跑第 27 篇的 v1/v2、POST 拒绝请求,确认 L7 行为与 waypoint 活动配置;此时直连尚未封闭。通过后运行 enforce,仅保留 waypoint 到库存的 L4 允许项,再测试 Pod IP 绕行被拒绝。
1 | |
脚本按维护窗口执行,不承诺零中断或策略跨对象原子更新。短暂混合阶段不作功能完成判定;特别是旧 sidecar 来源不能仅凭目的 Service 标签就被假设经过 waypoint。生产灰度需要按独立 namespace/明确标签批次设计共存,本例不把整组重建称为不停机灰度。
故障注入选择取消 Service 的 waypoint 绑定;启用 waypoint-only 后,允许身份的正例也应被拒绝。恢复绑定需重新经过过渡策略、正例验证和 enforce,最终重新验证直连被拒。回退到 sidecar 时同样暂停实验输入,执行整组重建,不只重建库存:
1 | |
cleanup 恢复第 26 篇 L4 基线并删除 waypoint;最后一次 sidecar 操作重新收紧到 sidecar L7 策略。复跑同一组版本、方法与错误身份用例,检查调用方身份与库存执行位置。当前迁移和回退均为 NOT_RUN;原则是让标签作用域、重建范围和调用链身份一起变化。Istio 1.27 固定版本源码 是策略生成与 sidecar/waypoint 差异的核对入口。
练习与参考解答
- 入网标签已变更,如何证伪“所有工作负载已经无 sidecar”?参考解答:列出变更前后的真实 Pod 容器及创建时间、代理资源和 ztunnel/waypoint 请求日志;保留尚未重建的旧 Pod 作为反例,再分别测服务调用。标签不能替旧 Pod 卸载代理,也不说明请求已改走 ambient。
- 迁移后 canary v2 成功、正常 GET 200,但旁路
POST /reserve也可写入,应判定迁移成功吗?参考解答:不能。安全门禁失败,账本显示预期拒绝点未生效;定位来源路径与 Service/Pod IP 附着,核对目标 ztunnel 对 waypoint 身份的四层限制,在隔离环境修正后重测合法请求与旁路负例,不通过就回退。
官方参考与系列导航
- Istio ambient migration 与 policy migration:sidecar/ambient 混合、四层与七层迁移的边界。
- Enable ambient mode 与 waypoint:分批变更与目标附着;实际命令必须按冻结版核对。
- Kubernetes Deployment rolling updates:重建与回退对已有 Pod 的影响;不替代网格路径验证。
系列导航:26 ambient 四层 → 27 waypoint → 28 sidecar 迁移与回退(本文)→ 29 控制面不可用。
