服务网格多集群性能与容量:让信任、发现和分区恢复都有停止条件
一次区域演练中,集群 A 的 orders 被标记为不可用,流量却没有稳定切到集群 B,而是在本地空端点和远端网关之间来回摆动。控制面连接正常,远端 Service 也能在列表里看到,但两个集群复用了同一个集群名,观测标签把两边数据合并;更糟的是,重叠的 Pod CIDR 让一部分“跨集群直连”实际落到了错误节点。恢复本地端点后,积压的发现更新、连接重建和重试同时释放,第二次流量冲击比原故障更大。
另一次故障发生在证书轮换窗口。团队认为共享根信任已经完成,因为东西向网关的 TLS 握手成功,旧连接也一直可用;新建连接却持续失败。最后发现一个集群只更新了 trust bundle,另一个集群仍由旧中间 CA 签发,部分 sidecar 又因为控制面断连没有收到新链。istiod Ready、网关端口可达、旧连接不断都没有证明新身份可签发、双方可验证,也没有回答根信任泄露会同时影响多少集群。
多集群先回答四个问题,再选择插件
多集群网格把一个请求的依赖从“本地 Service 和本地代理”扩展为四条链:身份链决定谁能相互认证,寻址链决定数据包能否到达正确端点,发现链决定控制面何时发布或删除端点,故障链决定任一远端依赖失效时流量是否留在可控边界内。安装扩展组件只会创建这些链路,不会自动证明它们正确。
信任不是“复制一个 Secret”。要记录 trust domain、root/intermediate 的持有者、签发路径、bundle 分发、轮换重叠窗口和撤销方式。共享根能保留跨集群 workload identity,也会扩大根密钥泄露、错误签发和同名身份碰撞的影响域。独立根加 federation 缩小签发故障域,但每条 federation 关系都要有验证、授权和撤销责任。
寻址至少包括 Pod CIDR、Service CIDR、节点地址、东西向网关地址、DNS 后缀和 NAT。same-network 模式允许 Pod 直连,保留端点粒度并少一次网关转发,但要求地址不重叠且路由、防火墙和 MTU 一致;multi-network 通过网关跨越不可直连网络,暴露面更小,却把吞吐、连接数、TLS 和可用性集中到网关故障域。
发现要说明谁观察远端 API、哪些服务可导出、同名服务如何合并、端点删除多久传播以及 headless/StatefulSet 是否有额外语义。远端 Service 出现在本地 DNS 中只证明名称解析存在,不证明 endpoint 新鲜、策略已收敛或数据路径可达。
故障域必须分别覆盖远端 API、控制面、CA、DNS、东西向网关、Pod 网络和遥测聚合。每个故障都要问三个问题:既有连接怎样、新连接怎样、新端点和新策略能否发布。笼统的“控制面故障不影响数据面”只对仍持有有效配置、证书未到期且端点未变化的既有路径成立。
控制面拓扑和网络拓扑是两个独立决策,不能用“多集群已打通”把它们合并。multi-primary 让每个集群保有本地控制面和签发路径,区域隔离能力更强,但要维护共同根、跨集群发现和多套配置一致性;primary-remote 减少控制面数量,却会把远端集群的新配置、新身份签发和恢复能力绑定到 primary。same-network 追求 Pod 直连,要求地址、路由、MTU 和 NetworkPolicy 全部可证明;multi-network 通过东西向网关收敛入口,减少直连要求,也把跨区吞吐、新建连接和证书处理集中成共享瓶颈。
| 组合 | 正常路径 | 首要故障域 | 必须保留的恢复能力 |
|---|---|---|---|
| multi-primary + same-network | 本地控制面,跨集群 Pod 直连 | 路由泄漏、CIDR 冲突、共同根 | 每个集群独立签发;路由隔离后本地服务仍可用 |
| multi-primary + multi-network | 本地控制面,经远端东西向网关 | 网关容量、远端发现、共同根 | 每个网络至少跨故障域部署入口;远端归零不拖垮本地 |
| primary-remote + same-network | 共享 primary,Pod 直连 | primary API/CA 与跨集群路由 | primary 不可用期间证书与配置剩余寿命可量化 |
| primary-remote + multi-network | 共享 primary,经东西向网关 | primary 与网关形成串联依赖 | 控制面和数据面分别故障时都有本地降级路径 |
Istio 的 ambient 多集群不能被当成 sidecar 拓扑的等价替换。当前稳定文档把 multi-network multicluster 标为 Beta,并明确只支持 multi-primary、multi-network;waypoint 名称和配置需跨集群保持一致,service scope 也必须一致,远端网络负载还可能因连接复用而偏向单个 endpoint。只要其中任一限制与租户隔离、热点保护或控制面集中诉求冲突,就应停止采用 ambient 多集群,而不是用额外脚本掩盖产品边界。Ambient 多集群限制
用隔离的双集群建立可重复基线
下面用 Istio multi-primary、multi-network 作为实验参考,因为它能把两个本地控制面、共同信任、远端发现和东西向网关分开观察。开始前从 Istio 多集群安装矩阵 选择明确拓扑,再在 受支持发行线 固定同一 minor/patch 的 istioctl、chart 和镜像 digest。ambient 多集群不能直接套用 sidecar 的支持结论;采用 ambient 时应另查 ambient multicluster 的目标版本能力与限制。
准备两个可丢弃集群 mesh-a、mesh-b,各自使用独立 kubeconfig context。实验身份需要创建 CRD、ClusterRole、webhook、Gateway 和跨集群读取凭据;不要给应用流水线永久 cluster-admin。更稳妥的分工是:平台发布身份安装控制面和远端读取对象,安全身份管理 CA,应用团队只管理自己 namespace 的 Service、Deployment 与获准路由。先记录不会变化的输入;cluster-info、节点地址和后续配置转储都按内部拓扑资料进入受控证据库:
kubectl --context mesh-a version
kubectl --context mesh-b version
kubectl --context mesh-a get nodes -o wide
kubectl --context mesh-b get nodes -o wide
kubectl --context mesh-a cluster-info
kubectl --context mesh-b cluster-info
istioctl version --remote=false还要导出两个集群的 Pod/Service CIDR、主 CNI、MTU、节点间路由和防火墙矩阵。若网段重叠,不要尝试用 network 标签掩盖;选择东西向网关、NAT 或重新规划地址。若采用直连,至少从源 Pod 所在节点探测远端 Pod IP 和业务端口,并用抓包或 flow log 证明返回路径对称。
安装前创建 mesh-lab,部署 client 与 orders。集群 A 的 orders 返回 cluster-a,集群 B 返回 cluster-b;每个应用使用独立 ServiceAccount,镜像固定 digest。先在没有跨集群发现的情况下保存本地请求基线、EndpointSlice、应用计数和延迟分位数。这个基线用于区分“网格增加的成本”和 Kubernetes 本地服务本身的问题。
安装多主多网络时,每个字段都在改变故障语义
两个控制面应使用同一个 meshID,使用唯一 clusterName,并为各自网络设置不同 network。示意 IstioOperator 片段如下;实际字段和 profile 必须以目标版本安装文档为准:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
meshID: mesh-prod
multiCluster:
clusterName: mesh-a
network: network-a| 字段或对象 | 改变的行为 | 错误配置的现场证据 |
|---|---|---|
meshID | 控制面和遥测归属哪个逻辑 mesh | 服务合并缺失,策略与观测被拆成两个 mesh |
clusterName | 端点来源、集群标签和本地性判断 | 同名集群数据互相覆盖,指标无法区分来源 |
network | 端点可否直连,何时经东西向网关 | 代理尝试不可达 Pod IP,或本可直连流量被网关集中 |
| trust domain / root bundle | 对端身份的命名和验证边界 | 新连接 TLS verify 失败,或同名 SA 被意外视为同一身份 |
| remote secret | 本地控制面读取远端服务与端点的权限 | 控制面 Ready 但远端 endpoint 不更新,删除传播停滞 |
| east-west gateway 地址 | 跨网络数据面入口与容量边界 | DNS 正常、endpoint 存在,但连接超时或网关 reset |
共同根可以由离线根分别签发中间 CA,也可以按组织 PKI 对接。不要把根私钥作为 Kubernetes Secret 在两个集群之间复制;实验即便使用临时 CA,也应限制 Secret 读取、关闭 shell 回显,并在清理时撤销。验证时要读取双方 workload 证书的 URI SAN、issuer、有效期和 bundle,而不是公开证书正文:
istioctl --context mesh-a proxy-config secret deploy/client -n mesh-lab
istioctl --context mesh-b proxy-config secret deploy/orders -n mesh-lab为每个集群安装控制面和东西向网关后,按官方 multi-primary/multi-network 步骤交换远端发现凭据。远端 kubeconfig 是高价值 Secret:它应只读必要的 Service、EndpointSlice、Pod 或目标实现要求的资源,使用专用 ServiceAccount,记录 owner、轮换周期和撤销测试。命令输出、CI artifact 和诊断包不得包含 bearer token、API server 内网地址或 CA 私钥。
istioctl create-remote-secret --context=mesh-a --name=mesh-a \
| kubectl --context=mesh-b apply -f -
istioctl create-remote-secret --context=mesh-b --name=mesh-b \
| kubectl --context=mesh-a apply -f -create-remote-secret 的默认权限与资源格式会随版本变化,生产应先渲染并审查 RBAC,再由受控流水线应用。Secret 存在只证明凭据对象创建成功;后续必须观察控制面是否建立远端 watch、端点是否带正确 cluster/network 元数据,以及凭据撤销后连接是否终止。
远端读取身份建立后,用 API server 的授权判定核对它的实际权限,不通过读取 token 或展开 Secret 来证明凭据可用。下面的 ServiceAccount 名称必须从目标版本生成的对象中取得;auth can-i --list 的期望结果是只具备发现所需的读权限,不具备修改 workload、RBAC、Secret 或 admission 对象的能力:
: "${REMOTE_READER_NAMESPACE:?set the generated remote reader namespace}"
: "${REMOTE_READER_SERVICE_ACCOUNT:?set the generated remote reader ServiceAccount}"
kubectl --context mesh-a auth can-i \
--as="system:serviceaccount:${REMOTE_READER_NAMESPACE}:${REMOTE_READER_SERVICE_ACCOUNT}" \
--list --namespace mesh-lab
kubectl --context mesh-a auth can-i \
--as="system:serviceaccount:${REMOTE_READER_NAMESPACE}:${REMOTE_READER_SERVICE_ACCOUNT}" \
create deployments.apps --namespace mesh-lab
kubectl --context mesh-a auth can-i \
--as="system:serviceaccount:${REMOTE_READER_NAMESPACE}:${REMOTE_READER_SERVICE_ACCOUNT}" \
update clusterrolebindings.rbac.authorization.k8s.io后两条应返回 no;第一条保存的是权限矩阵,不含 bearer token。还要在反向集群执行同一检查,并在目标版本确实需要额外资源时把理由写入权限账本。
正向实验要证明“发现、身份、策略和请求”是同一条链
先只导出集群 B 的 orders,保持集群 A 本地 orders 不导出或缩容,以免本地成功掩盖远端失败。不同产品的导出标记不同;Istio 的跨集群服务合并通常依赖相同 namespace、Service 名和端口语义。执行前确认 ServiceAccount 和 namespace identity 不会因为同名而扩大授权。
istioctl --context mesh-a proxy-status
istioctl --context mesh-b proxy-status
istioctl --context mesh-a proxy-config endpoints deploy/client -n mesh-lab --cluster "outbound|8080||orders.mesh-lab.svc.cluster.local"
kubectl --context mesh-a -n mesh-lab exec deploy/client -c client -- \
curl -fsS -H 'x-request-id: mc-positive-001' http://orders:8080/预期证据不是一句 200,而是以下状态同时成立:集群 A 的 DNS 解析到稳定的 Service 语义;client 数据面观察到来自 mesh-b/network-b 的 endpoint 或网关;源身份与目标身份均来自预期 trust domain;授权命中允许规则;东西向网关和目标代理看到相同 request ID;目标应用响应 cluster-b;控制面版本与代理 observed 配置已收敛。任何一项缺失都只能证明部分链路。
再把集群 A 的本地 orders 恢复,连续发送足够样本,分别记录本地和远端命中、连接复用、p50/p90/p99、网关 CPU/RSS 与重试次数。默认负载均衡未必等价于“区域优先”或“50/50”;要获得本地优先、故障转移或显式权重,应使用目标产品支持的 locality/failover 机制,并用端点状态和请求样本证明。不要用十次请求判断权重。
四组反向实验暴露不同失效层
断开远端 API:发现停滞不等于数据面立刻中断
临时阻断集群 A 控制面访问集群 B API,或撤销测试 remote secret。预期是控制面远端 watch 报错,新端点和删除事件不再传播;已经下发的 endpoint 可能继续被使用,既有数据连接也可能存活。此时在 B 删除一个 orders Pod,如果 A 仍向旧地址发流量,访问日志中的 stale endpoint、reset 与控制面 watch 错误应能关联。恢复 API 后,判据是 observed endpoint 集合收敛到 B 的当前状态,而不是远端连接重新显示 Ready。
断开东西向网关:发现正常但真实路径失败
保持远端 API 和控制面连接正常,阻断 B 的 east-west gateway 端口。预期 endpoint 仍可见,配置仍可能 SYNCED,但 A 到 B 的新连接超时、reset 或在本地代理返回 503,B 应用没有对应请求。恢复网关时先限制重试与连接重建速率,观察 backlog 是否形成第二次冲击;若所有客户端同时解除熔断,应主动分批恢复流量。
制造信任不重叠:端口可达但新身份失败
在隔离环境替换一侧测试中间 CA 或移除对端 bundle,保留网关网络可达。预期新建 mTLS 连接出现明确的证书链、URI SAN 或 trust domain 验证失败;旧长连接可能继续工作。恢复时必须证明双方新签发证书、bundle 和新连接都收敛,再决定是否关闭旧根重叠窗口。禁止通过关闭证书校验或长期 PERMISSIVE 来“恢复”。
删除远端服务:验证负缓存和删除传播
先停止新请求,再删除 B 的导出标记或 Service。预期 A 的发现状态最终删除远端 endpoint,DNS、代理 endpoint 和镜像/全局 Service 不再残留。随后发请求应落到本地端点或按设计失败,不能继续命中旧 IP。记录从对象删除到数据面收敛的时间,这个时间进入变更等待窗口和灾备 RTO,而不是凭感觉设置 sleep。
在目标集群尚未执行这些动作时,延迟、错误率和恢复时间都应保持“待测”,而不是从官方示例或控制面状态推算。执行记录至少绑定集群代号、组件版本、配置摘要和相对时间线,才能与下一次分区演练比较。
项目接入要显式选择本地性和失败语义
业务接入不要直接把“同名 Service 自动合并”当成生产策略。为每条跨集群依赖登记 owner、源 namespace/ServiceAccount、目标身份、可访问端口、是否允许远端、是否本地优先、远端最大流量、总 deadline、重试预算和数据合规区域。状态写入或强一致调用通常不适合无条件跨区 failover;只读、幂等且能容忍 WAN 延迟的调用更容易纳入。
客户端 deadline 必须包含跨网络 RTT、网关排队、TLS 建连和上游处理。若本地超时 300ms、远端正常 RTT 已接近 200ms,再让 sidecar 重试两次只会放大容量。应用 SDK、sidecar、网关和目标服务的重试次数应合并成总尝试预算,并在 request ID 下统计真实 upstream attempts。
服务名冲突要在上线前处理。同一 mesh 中同 namespace、同 ServiceAccount 往往映射为相同工作负载身份;同名 Service 又可能合并端点。若两个集群属于不同租户或发布节奏,优先用独立 trust domain、明确 federation 和不同服务命名,而不是依赖集群标签在事后区分。授权策略要验证错误集群、错误 namespace 和错误 ServiceAccount 的反例。
容量预算分成数据面、控制面和遥测三本账
先把部署模型换算成资源所有权。sidecar 的固定成本随应用 Pod 数增长,扩容一个业务副本就增加一份代理资源;ambient 的 L4 固定成本主要随节点数增长,ztunnel 由节点上工作负载共享,启用 L7 后再按 waypoint 的作用域、流量和故障域增加 Envoy 副本。两者不能只比较“单代理内存”,应比较相同请求语义下的完整账单:
sidecar 数据面预算
= 应用 Pod 数 × 单 sidecar CPU/内存
+ ingress/egress/东西向 gateway 副本 × 单 gateway CPU/内存
ambient 数据面预算
= 纳管节点数 × 单 ztunnel CPU/内存
+ 各 waypoint 作用域的峰值流量所需副本 × 单 waypoint CPU/内存
+ ingress/egress/东西向 gateway 预算Istio 1.24 的官方实验在固定硬件、1 KB payload、1000 RPS 和 2 worker 条件下,报告单 sidecar 约 0.20 vCPU / 60 MB、单 waypoint 约 0.25 vCPU / 60 MB、单 ztunnel 约 0.06 vCPU / 12 MB。这些数字只用于检查预算量级和设计本地基线,不能乘以 Pod 或节点数后直接写进生产容量;连接数、配置规模、协议、遥测过滤器和 worker 数变化都会改变结果。Istio 性能与可扩展性
数据面:测每条真实路径,不测“网格平均开销”
建立至少四条基线:本地无网格、本地经数据面、远端 same-network 直连、远端经 gateway。固定版本、节点规格、payload、协议、连接复用、并发、RPS、mTLS、L7 policy、日志和 Trace 采样;预热后重复稳态样本,再加入故障恢复样本。观测客户端端到端 p50/p90/p99、应用处理时间、proxy/gateway CPU 与 RSS、活跃连接、连接建立、reset/drop、重试和网络字节。
容量不是用一次峰值除以实例数。对东西向网关至少分别计算吞吐、并发连接和新建连接率:
所需网关副本 = max(
峰值业务吞吐 / 单副本安全吞吐,
峰值并发连接 / 单副本安全连接数,
峰值新建连接率 / 单副本安全握手率
) × 故障域余量“安全”取发生可接受 p99、错误率和资源水位时的较低值,不取压到崩溃前的最大值。还要验证失去一个 zone/节点后的剩余副本能否承载流量,并把证书轮换、配置刷新和日志采集同时开启。官方 Istio 性能与可扩展性 的数字绑定特定版本、硬件、服务数、Pod 数和负载,只能作为方法入口,不能作为本项目容量承诺。
控制面:对象总量和变更率是两种压力
控制面稳态内存通常随可见 Service、endpoint、proxy、route、policy、cluster 和配置范围增长;CPU 与队列更受 Deployment rollout、endpoint churn、remote watch 重连和配置变更率影响。容量实验应分别增加对象总量和每秒变更量,记录 API QPS/限流、reconcile 或 xDS/KDS 延迟、push queue、代理 ACK/NACK、stale endpoint、CPU/RSS 和收敛时间。
多集群还要单独测“远端服务缓存”这一维。Istio 的 ambient 多集群基准曾在每集群 300 个服务、4000 个 endpoint、共 10 个集群的模型中观察到,每增加一个远端集群约增加 0.01 vCPU 与 180 MB 控制面资源;该实验同时指出,每个 multi-primary 控制面实例都维护完整远端服务缓存,因此仅横向增加副本不能摊薄这部分内存。正确动作是先缩小远端可见服务集,再为单实例做垂直容量和 OOM 余量,最后才用多副本解决可用性与配置传播吞吐。Ambient 多集群性能
先做配置作用域收敛,再扩控制面副本。让每个代理看见整个多集群所有服务,会把一次小变更变成大范围 push,并增加内存与泄露拓扑的风险。把 service export、discovery selector、Sidecar scope 或产品对应机制纳入项目模板,使默认可见集小于全集。
遥测:时序基数常常先于代理饱和
多集群会自然增加 source_cluster、destination_cluster、network、zone、revision 和身份标签。活动时序可粗略估算为“指标族 × 源维度组合 × 目标维度组合 × 状态码/协议/路由”,每增加一个高基数标签都可能乘法膨胀。不要把 request ID、完整 URL、用户或 Pod UID放进常驻 metrics label。
同时量测 active series、scrape 样本、ingest/query latency、日志字节、Trace spans、采样率、丢事件、保留存储和 Kiali/查询页面延迟。单个 Kiali 多集群视图依赖统一或聚合 metrics/trace store,并需要读取远端集群;remote kubeconfig、ServiceAccount 和 anonymous 模式的权限都应单独审计。观测后端变慢时,降低采样必须伴随“被丢弃/限流”指标,否则安静的面板可能只是证据消失。
分区恢复必须防止第二次流量冲击
网络恢复后,不要立即解除所有保护。推荐按以下顺序推进:先恢复控制面和远端 API,等待发现对象及证书收敛;再恢复网关健康但保持业务权重为零或极低;用探针验证新连接身份、策略和目标版本;逐步增加流量并限制连接建立与重试;最后恢复自动 failover。每一步都有停止条件:NACK 持续、endpoint 数量摆动、证书错误、网关 p99 超预算或上游重试放大时停止推进。
DNS TTL、代理 endpoint 缓存、连接池、熔断半开和负载均衡健康状态的恢复速度不同。远端 endpoint 刚恢复时,旧连接可能仍指向本地,新连接却大量涌向远端;如果基于短窗口错误率立即再次切换,就会产生来回摆动。恢复判据应使用持续窗口和最小驻留时间,并区分“控制面已收敛”和“业务容量已稳定”。
排障按第一处证据分层
| 现象 | 第一处证据 | 常见原因 | 修复后再验证 |
|---|---|---|---|
| 远端服务不存在 | remote watch、导出对象、Service/EndpointSlice | 凭据失效、未导出、命名不一致 | endpoint 删除与新增都能传播 |
| endpoint 存在但超时 | network 元数据、路由、防火墙、gateway health | CIDR 重叠、错误直连、端口未放行 | 真实请求到达目标代理与应用 |
| 仅新连接 TLS 失败 | 双方 SVID、bundle、时钟、SAN | 根不重叠、中间 CA 过期、trust domain 冲突 | 新旧方向均建立新连接 |
| 本地和远端流量摆动 | locality/failover 配置、健康窗口、重试 | 恢复阈值过短、端点反复发布 | 稳定窗口内权重和 p99 收敛 |
| 图上只有一个集群 | cluster labels、聚合 metrics/trace、查询范围 | 集群名重复、远端未采集、标签被裁剪 | request ID 可跨网关关联 |
| 控制面 CPU 突增 | 配置变更率、push queue、API throttling | 全局可见、rollout 风暴、remote watch 重连 | 变更停止后队列回落且无 stale 配置 |
诊断包包含服务名、集群名、内网地址、身份 URI、证书元数据、remote secret 和完整配置转储,应按敏感资产处理。共享给供应商前先删除 token、私钥、Cookie、业务 Header 和租户标识;保留 request ID、匿名集群代号、相对时间和必要 response flag 即可。
机制选型看故障域,不看“是否支持多集群”
Istio 提供 multi-primary/primary-remote 与 same/multi-network 组合,适合需要明确 xDS、共享身份和东西向网关的团队。primary-remote 会集中 API/CA 故障域;ambient 的多集群支持与迁移限制必须按版本另查。
Linkerd 有 hierarchical gateway、flat pod-to-pod 和 federated service。flat 要求 Pod 直连并保留身份,hierarchical 把跨集群容量集中到 gateway;service mirror、headless 和 federated service 的限制要逐项验证。Linkerd Multicluster
Cilium Cluster Mesh 要求一致 datapath、唯一 PodCIDR/Node IP 和跨集群可达;集群数量与本地 identity 空间存在编码取舍。连接状态不等于数据面成功,应运行目标版本的 multi-cluster connectivity test。Cilium Egress Gateway 与 Cluster Mesh 的官方不兼容边界不能拼接绕过。Cluster Mesh
Kuma multi-zone 用 global CP、zone CP、KDS、ZoneIngress/ZoneEgress 和 dataplane 分层,适合 Kubernetes 与 Universal 混合。global 断连、本地 zone CP 故障和 ZoneIngress 故障是三种不同演练。Kuma multi-zone
Consul 的 WAN federation 与 cluster peering 是不同模型。前者有 primary/secondary、权威配置和 CA 关系,后者面向独立控制面间资源共享;mesh gateway 仍需显式 ACL、SNI、网络和容量。Consul federation
如果团队只需要少量跨区域调用、已有成熟 API gateway 或专线服务发现,而且不能承担共享 CA、远端凭据和统一遥测的运维责任,显式跨区入口通常比把全部服务合并成一个 mesh 更容易治理。多集群不是默认成熟度升级,而是扩大状态空间后的责任选择。
回滚与清理按依赖逆序进行
退出实验或拆除一个集群时,先停止新服务导出,把业务权重切回本地或替代入口,并证明镜像/全局服务流量为零;再删除本地创建的远端发现对象,撤销 remote ServiceAccount 和 Secret,关闭东西向网关并核销 LoadBalancer、DNS 与防火墙;随后移除对端 trust bundle 或 federation,最后才卸载集群内控制面。
Istio 多 revision 环境不要直接执行 istioctl uninstall --purge,它会删除共享 cluster-scoped 资源。按 revision 定向卸载前,确认没有代理连接该控制面、没有 namespace revision 标签、没有远端 secret 引用它。Gateway API CRD 可能由其他 controller 共用,CRD 必须最后由明确 owner 决定是否删除。
实验 namespace 的清理示意如下;执行前先确认 context 和对象清单,生产集群不应照抄批量删除:
kubectl --context mesh-a -n mesh-lab delete deploy,svc --all
kubectl --context mesh-b -n mesh-lab delete deploy,svc --all
kubectl --context mesh-a delete namespace mesh-lab
kubectl --context mesh-b delete namespace mesh-lab最终核销清单应为零:远端镜像/全局 Service、remote Secret/ServiceAccount/RBAC、东西向 LoadBalancer 与 DNS、仅供该关系使用的旧根和中间 CA 信任、遗留 namespace 标签、控制面远端连接、聚合观测数据源、临时日志与云费用。共享 PKI 材料只能由 PKI owner 在确认没有其他信任关系引用后移除。清理完成的证据不是“插件已卸载”,而是本地请求路径正确、远端凭据已撤销、旧网关无流量、旧身份不再受信且资产账单不再增长。
