土法炼钢兴趣小组的算法知识备份

【Istio 控制面】Ambient:ztunnel 与 waypoint 作为两类 xDS 客户端

文章导航

分类入口
networkkubernetes
标签入口
#istio#ambient#ztunnel#waypoint#hbone#xds#node-type

目录

前几篇讨论的推送机制默认了一个前提:连接到 istiod 的是一个 Envoy sidecar,按 Sidecar 作用域订阅一整棵 LDS/RDS/CDS/EDS 资源树。Ambient 模式打破了这个前提——同一个 istiod 现在要服务两种订阅形状完全不同的客户端:ztunnel(每节点一个,只处理 L4,甚至不走标准 Envoy 资源树),以及 waypoint(每命名空间/服务账号一个,是货真价实的 Envoy,但订阅范围按”挂载关系”而不是 Sidecar CR 决定)。

本文只回答控制面视角的问题:istiod 如何区分这两类客户端;它们各自订阅什么资源类型;推送过滤逻辑在 ambient 下有哪些还没做完的地方。Ambient 的税与形态图见 architecture/76,本文不重复;eBPF L4 数据面的对照见 k8s-network/13,本文只在必要处提一句边界,不展开。

本文是「Istio 控制面内核」系列第 13 篇(共 16 篇)。→ 系列目录

版本锚定:Istio 1.30.3;官方 Ambient 文档 istio.io/latest/docs/ambient/


一、istiod 眼中的四种代理身份

pilot/pkg/model/context.go 里代理类型是一个封闭集合:

// pilot/pkg/model/context.go(Istio 1.30.3,节选)
var NodeTypes = [...]NodeType{SidecarProxy, Router, Waypoint, Ztunnel}

Router 对应网关(含东西向网关),SidecarProxy 是传统 sidecar,WaypointZtunnel 是 Ambient 引入的两种新身份。这不是文档层面的分类,而是每次推送决策都要判的类型字段——pilot/pkg/xds/xdsgen.goxdsNeedsPush 第一行就是:

// pilot/pkg/xds/xdsgen.go(Istio 1.30.3,节选)
func xdsNeedsPush(req *model.PushRequest, proxy *model.Proxy) (needsPush, definitive bool) {
    if proxy.Type == model.Ztunnel {
        // Not supported for ztunnel
        return false, true
    }
    ...
}

Waypoint/Ztunnel 走的不是给 sidecar 用的通用”是否需要推”判断——它们的资源类型体系本身就不一样,用同一套判断逻辑没有意义。


二、ztunnel:L4、per-node、不进 CDS/LDS/RDS 体系

官方 Ambient 概览的定位很直接:ztunnel 是用 Rust 写的、按节点部署(DaemonSet)的专用代理,职责严格限定在 L3/L4:mTLS、身份认证、L4 授权、L4 遥测;不终止工作负载的 HTTP 流量,不解析 HTTP 头。传输层用 HBONE(HTTP CONNECT 隧道,mTLS 加密,复用 HTTP/2,标准端口 15008)把流量安全地转发给目标工作负载、其他 ztunnel,或 waypoint。

对应到 istiod 的资源生成侧,ztunnel 消费的不是 Cluster/Listener/Route,而是 pilot/pkg/xds/workload.go 里的 WorkloadGenerator(生成 v3.AddressType 资源,即工作负载/服务地址信息)与 WorkloadRBACGenerator(生成 WorkloadAuthorizationType 资源,L4 授权策略):

// pilot/pkg/xds/workload.go(Istio 1.30.3,节选,appendAddress 内 case 分支)
case v3.AddressType:
    // 工作负载 / 服务地址信息,ztunnel 用它决定往哪转发、期望的对端身份是什么

也就是说,ztunnel 完全没有 sidecar 意义上的”资源树”(LDS/RDS/CDS/EDS 依赖关系,见 Envoy 第 9 篇):它只有地址 + 身份 + L4 授权三类信息,没有 HTTP 路由表、没有 Listener 上的 Filter Chain 概念。这是”per-node L4”在控制面订阅形状上的直接体现——ztunnel 的故障域是该节点上所有工作负载共享:ztunnel 挂了,节点上所有 Pod 同时失去 mTLS 身份与 L4 遥测,这与 sidecar”故障域=单个 Pod”是完全不同的爆炸半径模型,机制原因在于订阅关系从”每工作负载一个客户端”变成了”每节点一个客户端服务该节点全部工作负载”。


三、waypoint:Envoy 内核,但作用域按”挂载关系”划定

官方文档明确 waypoint 就是 Envoy 代理的一次部署——与 sidecar 用的是同一套引擎,只是运行位置和触发条件不同:它作为独立 Deployment 运行在基础设施里,按命名空间或服务账号共享,只有工作负载需要 L7 策略(重试、超时、Header 路由、L7 鉴权等)时才需要部署。

waypoint 消费的资源类型与 sidecar 一样是 CDS/LDS/RDS/EDS,但订阅范围的判定机制不同pilot/pkg/xds/xdsgen.gowaypointNeedsPush 注释写得很清楚:

// pilot/pkg/xds/xdsgen.go(Istio 1.30.3,节选)
// waypointNeedsPush checks if a push is needed for a waypoint proxy on incremental kind.Address changes.
// Waypoint listeners, clusters, and routes are built from the services and workloads attached to the
// waypoint (e.g. the main_internal listener matches attached service VIPs and attached workload IPs),
// and attachment is only surfaced through kind.Address updates (use-waypoint changes, VIP or pod IP
// changes of attached resources).
func waypointNeedsPush(req *model.PushRequest, proxy *model.Proxy) bool {
    if !model.HasConfigsOfKind(req.ConfigsUpdated, kind.Address) {
        return false
    }
    ...
}

sidecar 的作用域由 Sidecar CR / 命名空间可见性决定(SidecarScope,见系列第 9 篇);waypoint 的作用域由哪些 Service/Workload”挂载”到了它决定,而这个挂载关系本身是通过 kind.Address 类型的配置更新体现的——VIP 变化、Pod IP 变化、use-waypoint 标签变化都会触发这条判断。同一个 istiod 内部,两种 Envoy 客户端(sidecar 与 waypoint)用完全不同的规则决定”这次变更是否与我有关”,这是理解 waypoint 排障时”为什么这个 Service 的策略没生效”要先查什么的关键——先查它是否真的挂载到了目标 waypoint,而不是先查 CDS/RDS 内容本身。

waypoint 的故障域对应”挂载到它的所有 Service/Workload 的 L7 处理”:一个 waypoint 通常按命名空间或服务账号共享,故障半径介于”per-pod sidecar”与”per-node ztunnel”之间。


四、推送优化的诚实边界:ambient 路径上一个明写的 TODO

pilot/pkg/xds/proxy_dependencies.goDefaultProxyNeedsPush 是所有代理(除个别特化路径)判断”这次配置变更是否需要推给我”的入口,其中对 ambient 代理的处理是显式跳过优化:

// pilot/pkg/xds/proxy_dependencies.go(Istio 1.30.3,节选)
func DefaultProxyNeedsPush(proxy *model.Proxy, req *model.PushRequest) (*model.PushRequest, bool) {
    if req.Forced {
        return req, true
    }
    if proxy.IsWaypointProxy() || proxy.IsZTunnel() || proxy.IsAgentgateway() {
        // Optimizations do not apply since scoping uses different mechanism
        // TODO: implement ambient aware scoping
        return req, true
    }
    req = filterRelevantUpdates(proxy, req)
    return req, len(req.ConfigsUpdated) > 0
}

对 sidecar,filterRelevantUpdates 会先按 Sidecar 作用域过滤,只有确实与该代理相关的变更才会触发真正的推送计算。对 waypoint/ztunnel/agentgateway,这一步直接跳过,注释原话是”scoping uses different mechanism”,并留了一句 TODO: implement ambient aware scoping

这不是道听途说的”ambient 还不够成熟”,而是源码里当前版本明确写着尚未做的优化:在大规模集群里,任意一次配置变更都会让所有 ambient 代理进入完整的推送判断路径,而不是先用轻量的作用域过滤器排除掉明显无关的连接。sidecar 已经有的这一层优化,ambient 代理目前没有。这是评估”能不能把整个大集群迁到 ambient”时需要纳入考量的具体机制,而不是抽象的”新技术不够稳”。

flowchart TD
  change["Config change (PushRequest)"] --> check{"proxy.Type?"}
  check -->|"SidecarProxy"| filter["filterRelevantUpdates<br/>(Sidecar scope filter)"]
  check -->|"Waypoint / Ztunnel / Agentgateway"| skip["Skip filter — TODO: ambient aware scoping"]
  filter --> maybe1["Push only if ConfigsUpdated relevant"]
  skip --> maybe2["Enter full push evaluation regardless"]

五、争论与开放问题

争论 A B
ztunnel 完全不做 L7 攻击面小、per-node 资源可预测,适合作为强制基线 需要 L7 策略的工作负载必须额外部署 waypoint,多一跳、多一个组件
waypoint 复用 Envoy 引擎 复用现有 Filter/可观测生态,运维经验可迁移 waypoint 是共享组件,单点故障半径覆盖挂载在它上面的所有 Service
ambient 推送暂不做 scoping 优化 实现简单,行为可预测 大规模集群下 ambient 代理的推送计算开销高于对应规模的 sidecar 部署,是当前版本的已知差距

开放问题(呼应 architecture/76 的 Ambient 成熟度判断):DefaultProxyNeedsPush 里的 ambient scoping TODO 何时补上,补上之后的收益需要在真实规模下量化——本篇不编造尚未实现的优化效果。另一个开放问题是多集群 + ambient 组合下的东西向路径:官方文档提到跨集群 ambient 流量经东西向网关时使用”double HBONE”(外层 mTLS 隧道由网关终止,内层 mTLS 隧道穿透到目标),这个双层隧道相对单集群 HBONE 的开销,目前没有本站可引用的一手实测数据。


六、参考资料

规范 / 官方文档(A)

源码(A)

站内对照

实验台账


七、小结

  1. istiod 用一个封闭的 NodeType 集合区分四种代理身份;Waypoint/Ztunnel 从推送判断的第一行代码起就走不同路径。
  2. ztunnel 不进 CDS/LDS/RDS 体系,只消费 Address 与 WorkloadAuthorization 两类资源,故障域是”整个节点”。
  3. waypoint 是标准 Envoy,但作用域由”挂载关系”(kind.Address 更新)决定,不是 Sidecar CR——排障入口不同。
  4. ambient 代理目前跳过 sidecar 已有的作用域过滤优化,源码里明写着 TODO,这是评估规模化 ambient 部署时的具体机制依据,不是空泛的成熟度评价。

系列目录 · 上一篇:多集群东西向发现扇出 · 下一篇:Linkerd 对照

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-08-11 · network / kubernetes

Istio / 网格控制面内核:从 CRD 到 xDS

补齐 Envoy 数据面 xDS 消费侧与 Mesh 选型叙事之间的控制面内核:istiod 推送图、CRD/HTTPRoute 翻译、Ambient 多客户端、NACK/warming 责任与排障对齐。


By .