跳转至

07 从配置文件走向控制平面

本章目标:理解动态配置要解决什么问题,画出“期望状态 → 翻译 → 发布 → 接受 → 请求验证”的完整链路。先修:运行过实验一,理解静态文件改动需要重新加载。

文件方案何时开始吃力

假设你有一百台 Envoy,每台承担不同租户流量。后端实例随扩缩容变化,证书定期轮换,应用每天调整路由。人工改 YAML、分发、重启,不仅慢,也难以回答“哪些节点已更新,哪些仍在旧版本”。即使你写脚本把文件复制出去,也还需要处理生成失败、部分节点不可达、旧版本回滚、并发写入和权限。

控制平面将这些职责组织成持续运行的系统。它接收高层配置,校验和翻译为 Envoy 资源,按节点或分组保存,再通过 xDS 发布。Envoy 接受或拒绝更新,控制平面记录相关状态。整个过程中,客户端业务请求仍由 Envoy 转发。

声明意图与生成资源

用户可能只写“把 book.example 的 /api 转给商品服务”。系统却要生成监听器、HCM、虚拟主机、路由、Cluster 和端点,处理证书、端口和资源名字,保持引用关系可用。高层模型让使用者少接触细节,但不会消除细节;控制平面必须正确承担它们。

本节关系图

这条链有多种“成功”。数据库保存成功只证明意图持久化;翻译成功证明能构造资源;发布缓存成功证明服务端有了候选版本;ACK 说明某类更新被确认;真实请求成功才证明选定场景的业务路径工作。任何一个步骤都不自动替代下一步的证据。

reconcile 是持续比较

Kubernetes 控制器经常使用协调循环(reconcile):读取当前对象与关联对象,计算期望结果,再使实际状态接近期望状态。它不是只能执行一次的安装脚本。事件可能重复、合并或在重试后再次出现,所以操作要具有幂等性:同一输入重复处理,不应不断创建无意义的新资源或产生重复副作用。

在你自己的 Go xDS 服务中,也会遇到类似问题。一次蓝绿切换应生成一份确定的资源图,而不是每收到一次 HTTP 调用就随机变更 Cluster 名字。版本号帮助服务端与客户端识别更新,但单纯增加版本并不保证内容正确。上游发现、配置校验、缓存发布和日志观测应有清晰边界。

节点身份与配置分组

Envoy 连接控制平面时会提供 Node 信息。Node.ID 常用于把它映射到正确配置。如果 Envoy 自称 envoy-book,服务端却给 book-envoy 发布 snapshot,就可能一直收不到期望配置。能建 gRPC 连接并不能证明配置分组正确。

多个 Envoy 也可以共享同一个配置组,前提是它们应获得相同配置。生产系统还需要认证和授权,不能因为客户端声称某个 Node.ID 就把对应租户的敏感配置交给它。Node.ID 是标识字段,认证身份是另一层安全机制。实验二为学习而简化,仅在隔离的本机网络运行。

失败时保持可解释

如果新版本因字段无效而被拒绝,系统应能记录版本、类型、错误与目标节点;如果后端地址失效,配置可能被接受而请求仍失败。两类错误的修复点不同。控制平面应尽量在发布前检查资源,Envoy 的校验仍是最后一道独立防线。保留上一份可用配置可以降低坏更新影响,但不能代替滚动发布、告警与回滚策略。

Envoy 动态更新常以资源类型分别进行,ADS 把多种发现服务复用到一条流上,便于依赖排序和协调;它并不提供跨所有资源、所有代理的一次全局提交。后续设计生产更新时应考虑旧路由与新 Cluster 短暂共存,先增加依赖,再切换引用,最后移除不再使用的资源。

下一篇会做什么

实验二会运行一个 Go 程序,把蓝、绿两个 Cluster 和端点放入 SnapshotCache,通过 ADS 服务交给 Envoy。管理接口切换 RDS 目标,你会看到无须重启 Envoy 就能从 blue 变为 green。我们会解释 Any、Node.ID、版本号、nonce、ACK/NACK 和 Consistent() 的实际边界。然后再看 EG 如何把这些底层能力接到 Kubernetes API 上。

练习与参考答案

  1. 管理 API 返回 200,但业务请求仍旧路由,至少有哪些可能?
  2. 为什么重复处理同一个期望状态不应不断创建不同名字的资源?
  3. ADS 是否保证一百台 Envoy 在同一纳秒切换所有资源?
参考答案
  1. API 只保存意图、翻译/发布失败、Node 分组不匹配、Envoy 尚未收到或拒绝配置、资源依赖尚未就绪,或者测试请求未命中新路由。应逐层查证。
  2. 事件可重复,稳定资源身份便于引用、去重、更新与回收;随机新名字可能泄漏资源、触发无谓变更。
  3. 不保证。ADS 是多类发现服务的复用机制,仍需面对资源类型、节点与网络时序差异。

继续:xDS 协议。来源:go-control-plane 缓存接口、xDS 服务端、Envoy xDS 协议。