B 集群的库存能接 A 集群的请求吗

在 32 多集群 的 sidecar 基线之外,假设 A 集群运行 orders 与 inventory-v1,B 集群运行 inventory-v2。当 A 本地 v1 不可用,希望 A 的读请求经 B 的 v2 得到报价;如果路由跨越网络却绕过身份检查,返回 200 不是合格恢复。两套库存副本的 POST /reserve 合成账本不会自动同步,读路径恢复也不保证订单一致性。

双集群订单经源 ztunnel 与 ambient 东西向网关至目标端,L7 条件依赖 waypoint

本文冻结 Istio 1.27.0 文档设计拓扑:当时 ambient 多集群为 alpha,官方不同网络安装指南支持的是 multi-primary;不是任意单主/双网络组合都已支持。图里 A/B 分别有控制面和网络,专用 ambient 东西向网关必须互通;源节点 ztunnel 承担入网和 HBONE L4 身份/加密,目标侧路径经远端网关与 ztunnel 到达工作负载。若想按 HTTP 路径作授权,需要目标 Service/workload 正确绑定 waypoint,并核对该版本跨集群时的实际适用范围;ztunnel 本身不解析 /quote。控制面下发可见端点不是跨网关转发的证明。

迁移前后分别守住哪道边界

以下分叉只描述待验证的调用路径,不是双集群抓包:

1
A/orders → ztunnel A → 东西向网关 → [waypoint B:仅已绑定时] → ztunnel B → B/inventory-v2
条件 目标端预期 不能省略的证据
正确来源、两侧互信 B 的 v2 返回报价 双侧代理/网关与 B 应用相同 ID
错误来源身份 入口或目标侧拒绝 拒绝位置和 B 应用无同 ID
网关不可达 新连接失败或按规则走本地 网络故障窗口与恢复后响应

按 1.27 安装指南先分别固定 cluster ID、network ID、gateway 地址、双向 API 发现以及服务的 global/local 发现作用域。服务发现若只发布本地端点,A 不会自然选 B;gateway 若不可达,则即使 EDS 出现远端地址也不能完成新连接。源/目标信任域或证书根不兼容时,即使网关接通也可能认证失败;临时增加信任根或别名之前,明确授权策略究竟匹配哪些旧/新身份及最终回收时间,不把扩大信任当成无成本回滚。按 26 ztunnel 和 27 waypoint 分开审查 L4/L7 执行点。

请求集合固定:A 的 orders 身份到 B 的 v2 成功;错误来源跨集群被拒;只切断合成实验的 A→B 网关链路,确认本地 v1 或显式失败的真实去向,再恢复并观察新连接。信任域迁移改变 SPIFFE URI 的域名和授权匹配,CA 轮换改变签发及信任链,两者分别设计实验。记录两边公开证书元数据与拒绝位置,不提交私钥。旧连接与新连接、waypoint 创建与实际绑定也要分别取证。两个 namespace 不能冒充跨集群,但可以用于单集群信任域迁移验证。

当前 kubectl 不存在,两个独立的实验 context 无法通过 check-32.sh 的前置检查;多集群、跨集群授权、信任域迁移和恢复均 NOT_RUN。复跑前从 examples/service-mesh/ 执行单行命令 SM_CONTEXT_A=service-mesh-lab-a SM_CONTEXT_B=service-mesh-lab-b SM_NAMESPACE=service-mesh-lab bash scripts/check-32.sh,只允许两个 UID 不同、自己持有的隔离集群;该只读检查即使退出 0 也不是 ambient 实验通过。

按 1.27 安装双主、不同网络

examples/service-mesh/electives/E07/ 包含集群安装模板、HBONE Gateway 模板、L4 授权策略与信任域迁移覆盖配置。基线使用发行包自带的 helloworld v1/v2 和 curl,以响应中的版本识别后端;这一步验证跨集群机制,不把 /hello 当累计工程 /quote 已经验收。迁入 inventory 时应保持 Service 名称、端口、服务账户与请求日志可追踪。

准备两个自己的隔离集群,context 为 service-mesh-lab-a、service-mesh-lab-b。每个集群需要可用的 LoadBalancer,两侧可访问对方 API Server 和网关 15008。ambient 东西向网关只负责 HBONE,不替 API Server 提供通用 TCP 隧道。check-32.sh 用 kube-system UID 排除两个 context 实际指向同一集群。

两侧使用 old.mesh trust domain,共享根 CA,各有中间 CA。用发行包证书 Makefile 在仓库外创建实验 CA:

1
2
3
4
5
6
umask 077
mkdir -p "$E07_WORK_DIR/certs"
cd "$E07_WORK_DIR/certs"
make -f "$ISTIO_DIR/tools/certs/Makefile.selfsigned.mk" root-ca
make -f "$ISTIO_DIR/tools/certs/Makefile.selfsigned.mk" cluster1-cacerts
make -f "$ISTIO_DIR/tools/certs/Makefile.selfsigned.mk" cluster2-cacerts

创建两侧 istio-system namespace,把 cluster1 的四个文件放进 A 的 cacerts,cluster2 的四个文件放进 B。命令以 A 为例:

1
2
kubectl --context service-mesh-lab-a create namespace istio-system
kubectl --context service-mesh-lab-a -n istio-system create secret generic cacerts --from-file="$E07_WORK_DIR/certs/cluster1/ca-cert.pem" --from-file="$E07_WORK_DIR/certs/cluster1/ca-key.pem" --from-file="$E07_WORK_DIR/certs/cluster1/root-cert.pem" --from-file="$E07_WORK_DIR/certs/cluster1/cert-chain.pem"

B 使用 service-mesh-lab-b 与 cluster2。只把公开证书摘要放进证据;ca-key.pem 和 remote secret 不进入仓库。两个独立自签根不会仅因 meshID 一致就互信。

两侧安装 Gateway API v1.3.0 standard CRD,与累计安装基线保持一致,保存实际版本和下载文件哈希;不要随意用 latest 替代。

1
2
3
4
curl -fL https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml -o /tmp/mesh-gateway-api-v1.3.0.yaml
shasum -a 256 /tmp/mesh-gateway-api-v1.3.0.yaml
kubectl --context "$SM_CONTEXT_A" apply -f /tmp/mesh-gateway-api-v1.3.0.yaml
kubectl --context "$SM_CONTEXT_B" apply -f /tmp/mesh-gateway-api-v1.3.0.yaml

回到累计工程目录执行安装脚本,要求 envsubst 可用:

1
SM_CONTEXT_A=service-mesh-lab-a SM_CONTEXT_B=service-mesh-lab-b SM_NAMESPACE=service-mesh-lab ISTIO_DIR=/opt/istio-1.27.0 E07_WORK_DIR=/secure/e07 bash electives/E07/install.sh

脚本分别写入 cluster1/network1 与 cluster2/network2,安装 ambient 控制面、CNI、ztunnel,并设置 AMBIENT_ENABLE_MULTI_NETWORK=true。官方页面某份模板曾有 insall.istio.io 拼写,工程使用正确的 install.istio.io/v1alpha1。

网关使用 gatewayClassName: istio-east-west、15008、HBONE、Terminate 与 ISTIO_MUTUAL。这是该 alpha 实现的双层 HBONE 接入,与 sidecar 的 15443 AUTO_PASSTHROUGH 不是同一模板。远端 API 凭据通过两次 create-remote-secret 双向交换;输出直接进入 kubectl,不保存到日志。

全局服务与 L4 授权

两侧同 namespace 部署同名 Service,保证本地 DNS 能解析,并设置 istio.io/global=true。A 只部署 v1,B 只部署 v2,namespace 均标注 ambient。若只有远端 endpoint 而没有本地 Service,应用可能在 DNS 阶段失败,根本未到网关。

授权策略选择 app=helloworld,仅允许 old.mesh/ns/sample/sa/curl。这是 L4 principal 匹配,不配置 HTTP path;ztunnel 不解析 /hello。HTTP 方法和路径条件需要 Service 绑定 waypoint,并使用适合 waypoint 的策略附着方式,不能在 L4 策略中假装执行。

1
SM_CONTEXT_A=service-mesh-lab-a SM_CONTEXT_B=service-mesh-lab-b SM_NAMESPACE=service-mesh-lab bash scripts/run-E07.sh

脚本保存 remote-clusters、ztunnel workload 视图、Gateway/Service/策略、两侧请求与应用日志。synced 只证明发现通信;请求要实际出现 v1/v2,再以 Pod 所属集群确定后端。官方 helloworld 未必输出 x-request-id,其默认日志不能冒充按 ID 的完整追踪;迁入累计 inventory 后再补 ID 闭环。

使用第二个 service account 创建 curl Pod,应被 L4 拒绝。拒绝可能表现为连接关闭,不一定是 HTTP 403,应读 ztunnel 的 RBAC 日志。先将 A 的 v1 缩容为零并等待端点收敛,确认允许身份只能访问 B,再临时缩容 B 的专用网关 Deployment,新请求应失败。恢复网关原副本数并等待就绪,验证 v2 恢复,最后恢复 A 的 v1。这样可以避免本地回退掩盖跨网关故障。

身份域迁移与 CA 轮换分开验证

spiffe://old.mesh/ns/sample/sa/curl 到 spiffe://new.mesh/ns/sample/sa/curl 是身份名称变化,根 CA 可以不变。相反,替换签发密钥和信任 bundle 可以保持 SPIFFE URI 不变。“旧根→双根→新根”是 CA 轮换流程,不能证明授权规则已兼容新域。

迁移实验保持 CA 不动,保存旧身份允许/拒绝结果,再应用 trust-domain-migration.yaml,设置 trustDomain: new.mesh 与 trustDomainAliases: [old.mesh]。安装时叠加原 cluster 配置,避免丢失网络及多集群开关:

1
2
istioctl --context service-mesh-lab-a install -f "$E07_WORK_DIR/cluster1.yaml" -f electives/E07/trust-domain-migration.yaml -y
istioctl --context service-mesh-lab-b install -f "$E07_WORK_DIR/cluster2.yaml" -f electives/E07/trust-domain-migration.yaml -y

等待控制面更新,再按隔离实验的维护顺序重启相关 ztunnel 与工作负载,读取证书 URI SAN 确认 new.mesh;重启本身不证明证书刷新。保留旧 principal 策略,重测允许和错误 service account 拒绝。aliases 提供授权身份兼容,不会让陌生根 CA 自动可信。该版本 ambient 的策略编译与执行仍需真实请求验证,不能拿 sidecar 文档示例当 ambient 实测。

所有身份迁移完成后,把策略 principal 更新为新域、移除 alias,复跑同一集合。只删 alias 而保留旧 principal,可能把合法来源一起拒绝。CA 轮换另开实验,记录公开 bundle、证书链与新连接握手;不要同时更改 trust domain,否则失败原因难以区分。

需求关键词 可迁移原则 必须观察的变化
跨集群可达 分开发现、网络与身份验证 端点、网关连接、真实后端
身份域改名 名称兼容与信任根分离 URI SAN 与授权匹配
CA 轮换 签发链与验证链同步过渡 bundle、证书链、新连接

练习与参考解答

  1. A 已发现 B 的库存端点,但请求超时。画出至少两个独立失败位置。参考解答:A ztunnel/东西向网关网络不可达,或 B 接入后证书身份不可信;依次查可见端点、跨网关连接、双方握手和 B 后端请求 ID,而非直接改路由权重。
  2. 信任域迁移是否必须准备两个集群?参考解答:不需要。一个集群也能更改 trust domain、刷新身份并验证旧/新 principal 与 aliases;两个 namespace 本身不构成迁移。双集群是本文跨网络验证的前提,不是 SPIFFE 信任域迁移的定义条件。

资料与系列导航

Istio 1.27 ambient 多集群指南、alpha 特性介绍;源码入口 Istio 1.27.0 pilot。研究记录 writing-plans/service-mesh/research/E07.md。

系列导航:E06 全局配额 → E07 Ambient 多集群(本文) → E08 教学 xDS。