LabHub
学习 学习路径 课程

ICA — Istio 认证助理

把代理从 Pod 里拿出来,变了什么

在 LabHub 中继续学习

一句话总结

Ambient 模式将 L4 与 L7 分离,形成了不再强制所有工作负载承担完整 Envoy 成本的架构。但与此同时,故障域也从 Pod 扩大到了节点。

概念图: 不再强制所有工作负载承担完整 Envoy 成本 · 真正需要 L7 功能的服务只占全部服务的一部分 · ztunnel · waypoint

为什么需要它

Sidecar 模型的成本用数字看十分直观。在拥有 500 个 Pod 的集群中,如果每个 sidecar 占用 120MiB 内存,单是这些代理就需要约 58GiB;如果每个代理的 CPU request 为 100m,还会有 50 vCPU 从可调度容量中消失。此外,由于 proxy 位于 Pod 内,升级版本就必须滚动重启所有工作负载。注入 label、revision tag 或 webhook 配置只要有一项不一致,就会出现“部分 Pod 在 mesh 内、部分 Pod 在 mesh 外”的状态。此时若启用 STRICT,所有未注入的 Pod 都会断开。

除此之外,还有一项决定性观察:真正需要 L7 功能的服务只占全部服务的一部分。其余大多数服务只需要 mTLS 和基础 telemetry,sidecar 模型却仍要求它们承担完整 Envoy 的成本。

工作原理

Ambient 分为两层。

节点间流量通过 HBONE tunnel 传输。它在端口 15008 上,以基于 mTLS 的 HTTP/2 CONNECT 封装原始 TCP stream。借助 HTTP/2 stream multiplexing,同一对节点间的多个连接可以共享一条 mTLS 连接,从而降低握手成本。CONNECT header 中携带原始目的地与身份,因此接收端 ztunnel 无需打开 payload 就能完成 L4 授权判定。

有一项设计原则必须牢记:waypoint 归目的地所有。 在 sidecar 模型中,客户端 proxy 执行路由与重试;在 Ambient 中,则由拥有目标服务的团队通过自己的 waypoint 执行 L7 策略。这样策略所有权更加清晰,但“按调用方设置不同 timeout”等客户端策略需要重新设计。

也必须诚实看待代价。经过 waypoint 的路径包含 3 个 hop(ztunnel → waypoint → ztunnel),可能比 sidecar 的 2 个 hop 更长。而且,一旦 ztunnel 故障,该节点的全部 mesh 流量都会受到影响。 sidecar 的 proxy 故障被限制在单个 Pod,Ambient 的故障域却是整个节点。PodDisruptionBudget、priority class 和重启监控都必须纳入运维设计。

调试时,顺序决定一切。应按照流量经过的顺序读取 istioctl proxy-config

listener  이 프록시가 그 포트를 듣고 있는가
   ->
route     VirtualService 가 라우팅 테이블로 번역됐는가
   ->
cluster   DestinationRule(서킷브레이커, TLS)이 반영됐는가
   ->
endpoint  그 subset 에 실제 파드 IP 가 잡혀 있는가

只要找到从哪个阶段开始与预期不符,需要修正的资源也就自然确定了。503 response flag 对照表也是同样的思路。

标志 含义 首要怀疑对象
UH no healthy upstream subset label 与 Pod label 不一致
UO upstream overflow 超过 connectionPool 上限
UF upstream connection failure 仅一侧启用 STRICT 导致 mTLS 不一致,或错误判断端口协议
NR no route VirtualService 匹配缺失,或没有 catch-all
URX max retries reached 重试耗尽——应结合其他标志追踪根因

关于可观测性,还要注意最后一点。Envoy 会自动创建 span,但如果应用没有把入站请求的 trace header 传播到出站请求,trace 就会中断。 部署 mesh 后 trace 仍支离破碎,多数是这个原因;这也是 mesh 唯一无法替应用完成的部分。

现场会遇到的情况

作者的家庭实验室中,hubble-relay 与 hubble-ui 曾一直处于 Pending。事件信息为 0/1 nodes are available: 1 node(s) had untolerated taint(s)。原因很简单:控制平面节点带有 node-role.kubernetes.io/control-plane:NoSchedule taint,而这两个组件不是 DaemonSet,而是 Deployment,因此没有 toleration。 相比之下,CoreDNS 带有默认 toleration,所以能够正常启动;worker 加入后,问题立即消失。

这个案例也可以直接用于理解 Ambient:ztunnel 是 DaemonSet,waypoint 是 Deployment。 也就是说,ztunnel 会自动在每个节点启动,而 waypoint 必须由 scheduler 寻找可用位置。若只剩带 taint 的节点或资源不足,waypoint 会静默停留在 Pending,该 namespace 的 L7 策略将完全无法执行。因此,当出现“L4 正常,只有 L7 策略不生效”的症状时,首先要检查 waypoint Pod 状态。

还有一点:该家庭实验室使用 --skip-phases=addon/kube-proxy,从一开始就不安装 kube-proxy,而不是安装后再删除。因为只要 kube-proxy 运行过一次,KUBE-SERVICES / KUBE-SVC-* / KUBE-SEP-* chain 就会残留在节点上。从 sidecar 转换到 Ambient 时也适用同样原则:一个 namespace 中不能同时存在注入 label 与 ambient label。删除注入 label 后,必须通过滚动重启清除现有 sidecar,然后再添加 ambient label。

下一项测验要确认什么

本模块是概念模块,不安排实验,而是通过测验检查 Ambient 架构、HBONE、故障域、读取 proxy-config 的顺序以及 response flag 判读。这五项不仅是考试重点,也是实际故障处理时最先使用的工具。