第 10 篇 钉死了 ACK 的协议含义:隔离校验通过并意图应用。生产联调里更常见的投诉是:「控制面已经 ACK,金丝雀路由怎么还没吃到?」答案几乎总在 warming 与 依赖尚未就绪,而不是 nonce 算错。
本文把三条线拧在一起:Cluster / Listener warming;SDS 证书与密钥轮转;xDS 热更新相对进程级 Hot restart 的边界。进程交接与 drain 见 第 12 篇。
本文是「Envoy / 数据面代理内核」系列第 11 篇(共 16 篇)。→ 系列目录
篇目 核心内容 第 10 篇 · ADS / SotW / Delta ACK/NACK、version/nonce 第 11 篇 · Warming / SDS warming、证书轮转、热更新边界 第 12 篇 · Hot restart / drain 父子交接与连接排空
版本锚定:Envoy v1.39.0 xDS protocol(Resource warming)、Cluster manager、Secret discovery service (SDS)。无伪造
config_dump/ stats。
一、为什么 ACK 之后流量仍可能是旧的
把「配置生效」拆成至少四层:
| 层 | 问题 | 典型信号 |
|---|---|---|
| 协议 | 本批资源隔离校验是否通过 | ACK / NACK |
| 依赖 | RDS/EDS/SDS 等依赖是否齐 | warming 中;超时用缓存或失败 |
| 快照 | Worker TLS 快照是否已切到新对象 | 新旧并存窗口 |
| 请求 | 进行中的流是否仍绑定旧 Route/Cluster | 长连接、已选路由 |
协议文档写明:ACK 不表示配置已成功应用。Cluster / Listener 还要过 warming;Route 本身不做 warming——控制面必须保证路由引用的 Cluster 已就位,再推 RDS。这是「ACK ≠ 新路由上量」的规范锚点。
flowchart TD
push["xDS push"] --> ack{"Isolation valid?"}
ack -->|"NACK"| keepOld["Keep previous version"]
ack -->|"ACK"| warm["Cluster / Listener warming"]
warm --> deps{"EDS / RDS / SDS ready?"}
deps -->|"no"| pending["Not serving yet / use cache"]
deps -->|"yes"| swap["Atomic swap into active set"]
swap --> traffic["New requests see new config"]
二、Cluster warming
官方 Cluster manager(v1.39.0):Cluster 在启动与 CDS 更新时都会 warming,未完成前不对流量可见。
完成条件包括:
- 初始服务发现:DNS 解析或 EDS 更新等到位。
- 若配置了主动健康检查:对发现的 host 完成初始探测,得到初始健康视图。
语义:
- 新建 Cluster:warming 完成前,对其余组件「不存在」;引用它的 HTTP 路由会得到 404 或 503(取决于配置)。
- 更新 Cluster:旧 Cluster 继续服务;新实例 warming 完成后原子替换,避免服务中断。
xDS 协议补充的 Envoy 实现细节:
- Cluster warming 完成要求管理端提供新的
ClusterLoadAssignment响应,即便 endpoint 集合未变。 - warming 超时后,若存在缓存的
ClusterLoadAssignment,Envoy 可用缓存完成 warming。
CDS 更新 cluster 定义时,连接池会排空并重建;纯 EDS 增删 host 则不影响既有 host 上的连接——这是官方 xDS configuration API overview(v1.39.0)里推荐「CDS 集群仍走 EDS」的原因之一。
三、Listener warming
协议:若 Listener 通过 RDS 引用
RouteConfiguration,Listener warming 在拿到对应
Route 后完成。初始化阶段若一直等不到 EDS/RDS,Envoy
不会完成初始化,CDS/LDS
更新也不会真正生效。
Envoy 实现细节与 Cluster 不对称:
- Listener warming:即使管理端未再推
Route,也可用先前已发送的
RouteConfiguration完成 warming。 - 管理端只需在 Route 变更或从未发送时再推 RDS。
LDS 增删改 Listener 时,还会走 drain(与
Hot restart 共用 --drain-time-s
等语义,细节见第 12 篇):旧监听连接被优雅关闭,新 Listener
在 warming
后接管。这仍是同进程内配置对象替换,不是二进制热重启。
四、SDS:证书轮转与「未就绪」边界
4.1 机制位置
SDS(Secret Discovery Service)按与其他 xDS 相同的协议推送 TLS 密钥材料:证书链、私钥、校验上下文、session ticket keys 等。好处是证书过期时由中心 SDS 推新材料,不必为换证重建 Pod/容器(相对「Secret 挂载 + 重部署」)。
4.2 未就绪 vs 失败后的行为
官方 SDS 文档(v1.39.0)区分两种状态:
| 对象 | 远程 SDS 尚未成功取到 secret | 连接失败或坏数据导致取证失败 |
|---|---|---|
| Downstream Listener | 不标 active;不开端口 | 可标 active 并开端口,但到该端口的连接被 reset |
| Upstream Cluster | 不标 active;不用于路由 | 可标 active,但打到该 Cluster 的请求被 拒绝 |
因此排障时「端口开了却瞬间 reset」或「路由命中却上游拒绝」,要先查 SDS,而不是只查 RDS ACK。
4.3 轮转路径
- gRPC SDS 推送:优先路径;新 secret 到达后 Envoy 可立即用于新握手。
- 文件系统旋转:secret
指向路径时,默认真目录上的
move/rename(
IN_MOVED_TO);v1.39.0 起watched_directory.watch_modify可额外订阅IN_MODIFY,适配「原地写文件」的密钥管理器。 - 静态与 SDS 证书:同一
DownstreamTlsContext内不可混用静态证书与 SDS 证书。
TLS 总览还指出:session resumption 可跨 Hot restart 与并行实例——这与「证书材料热更新」是不同层的能力。
五、热更新边界:xDS 能换什么、不能换什么
动态配置总览的分层意图:
| 能力 | 不停流量热更新? | 典型仍要 Hot restart / 全量重启 |
|---|---|---|
| EDS / RDS / 多数 CDS / LDS | 是(带 warming / drain) | — |
| SDS 证书 | 是(成功推送后) | 文档亦列「证书轮转」为极少情况下 hot restart 动机之一——取决于部署是否走 SDS |
| Admin、部分 tracing driver、二进制 | 否 | 是 |
Listener socket_options 在 hot restart
中 |
子进程沿用父进程 socket options | 要改则全量重启或 LDS 更新路径 |
工程判断:能用 xDS + warming 解决的,不要上 Hot restart;Hot restart 解决的是代码与无法热替换的进程级状态,代价是父子双进程与连接排空窗口(第 12 篇)。
常见「ACK 了但仍旧路由」清单:
- RDS ACK,但目标 Cluster 仍在 warming(EDS/健康检查未完)→ 503/404。
- LDS ACK,Listener 仍等首包 Route / SDS。
- 控制面顺序反了:先 RDS 指到
Y,后 CDS/EDS 提供Y→ 短暂黑洞。 - 长连接上的请求仍绑定更新前选中的路由对象。
- 看错实例:ACK 在 A 节点,流量在 B 节点。
六、争论与开放问题
| 争论 | A | B |
|---|---|---|
| Route 不做 warming | 控制面必须严格排序,语义清晰 | 误推时易黑洞,运维压力大 |
| warming 超时用 EDS 缓存 | 提高可用性 | 可能用过期 endpoint 服务 |
| SDS 失败后开端口再 reset | 避免无限卡住监听 | 对客户端表现为连接异常,难与防火墙区分 |
开放问题:在 endpoint 高频抖动下,每次 CDS 触发的「强制新 CLA」warming 与连接池排空,如何与 Incremental EDS 的差量更新叠加才不放大尾延迟——需按控制面实现与集群规模实测。
七、参考资料
规范 / 官方文档(A)
- Envoy Proxy, xDS REST and gRPC protocol — Resource warming / Eventual consistency, v1.39.0。
- Envoy Proxy, Cluster manager — Cluster warming, v1.39.0。
- Envoy Proxy, Secret discovery service (SDS), v1.39.0。
- Envoy Proxy, xDS configuration API overview, v1.39.0。
源码(A)
envoyproxy/envoytag v1.39.0:source/common/upstream/(cluster warming)、source/server/(listener manager)、source/common/secret/。
站内对照
实验台账
- 本篇无命令输出。排障时可在有环境时查 admin
/config_dump、/stats中 warming / SDS 相关计数,但不在此粘贴未执行结果。
八、小结
- ACK 只过协议关;Cluster/Listener warming 与依赖就绪才决定能否服务。
- 新建 Cluster 不可见 → 404/503;更新则旧实例继续服务直至原子切换。
- SDS 未就绪与取证失败语义不同——后者可能开端口但 reset,或拒绝上游请求。
- xDS 热更新覆盖绝大多数运行时配置;二进制与少数进程级项才需要 Hot restart。
→ 系列目录 · 上一篇:ADS / SotW / Incremental · 下一篇:Hot restart 与 drain
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Envoy 数据面】xDS 资源树:LDS→RDS→CDS→EDS 的依赖、命名与顺序
把 Listener、RouteConfiguration、Cluster、ClusterLoadAssignment(及 SDS)画成依赖树,说明资源命名如何串起引用、warming 与 make-before-break 顺序为何决定短暂黑洞,并衔接到 ADS/SotW/Delta。
【Envoy 数据面】生产排障:五条坐标系上的失败清单
按第 1 篇五条坐标系拆解无上游、路由未生效、证书/SDS、warming 黑洞、hot restart 与连接泄漏;给出 admin 核对顺序与观测信号入口,不虚构延迟数字。
Envoy / 数据面代理内核:从 Listener 到 xDS
补齐站内 Envoy 单篇地图与 Mesh/网关选型之间的数据面内核层:Main/Worker、FilterChainMatch、HCM、Cluster/连接池、xDS warming 与 Hot restart,并以排障与选型收束。
【Envoy 数据面】数据面全景:从 Listener 到 xDS 的可编程代理内核
定位 Envoy 相对 Nginx/HAProxy 静态配置代理与 Mesh 选型叙事的生态位;钉住请求路径、配置快照、FilterChainMatch、xDS warming、上游资源五条坐标系,并给出与 network/57 的分工及 16 篇阅读路线。