【Linkerd】destination 架构:四容器 Pod 与 Informer 驱动

💡 原文中文,约7400字,阅读约需18分钟。
📝

内容提要

Linkerd 2.20的destination控制器通过Informer监视Kubernetes API,将EndpointSlice变更经EndpointTranslator转为per-target的gRPC Get()流推送给proxy。Pod内含四容器:destination负责发现、sp-validator校验ServiceProfile、policy求值策略、反身proxy提供mTLS。2.20优化了等价订阅者间共享状态,内存最高降84%,但需按集群实际churn评估。

🔎

延伸解读

per-target 流与 xDS 的排障差异

Linkerd destination 采用按目标查询的 gRPC 流(destination.Get()),与 xDS 的按资源类型订阅不同。排障时不应寻找 EDS 订阅 ACK,而应检查特定 service 的 Get() 流是否存活,以及 EndpointSlice watch 是否一致。空端点与流断开在应用层都表现为超时,但证据包不同:前者查 EndpointSlice 与 selector,后者查 destination Pod 事件与 gRPC 日志。

四容器同 Pod 的故障域含义

destination Pod 内四个容器共享同一生命周期,任一容器 OOM 会导致整个 Pod 重启,因此 Pod 内是单故障域。跨 Pod 的故障域(如 destination 挂而 identity 仍活)在 Deployment 层成立。2.20 内存优化降低的是 destination 容器 OOM 概率,但不改变四容器同 Pod 的事实,扩缩容时需考虑整 Pod 的资源限制。

2.20 内存优化的适用边界

2.20 通过共享等价订阅者间的过滤与 diff 状态,在负载测试中内存最高降约 84%,但该数字基于高 Pod churn、大量并发 Get() 流的假设。若集群服务名扇出小、churn 低,内存下降可能不明显。优化的是单副本内存曲线,并未取消 watch 成本,在 churn 极高且策略复杂的集群,destination 仍可能是首个需要水平扩容的组件。

Q&A

Linkerd 2.20 的 destination 控制器是如何获取 Kubernetes 资源变更的?

destination 控制器使用 client-go 的 Informer/Reflector 监视 Kubernetes API(如 Pod、Service、EndpointSlice),避免轮询 apiserver。当资源变更时,事件进入 EndpointTranslator 等翻译层,转换为 proxy 可消费的端点描述。

Linkerd destination Pod 内包含哪四个容器,各自的作用是什么?

destination Pod 包含四个容器:destination 负责服务发现和端点翻译;sp-validator 作为 ValidatingAdmissionWebhook 校验 ServiceProfile;policy 容器求值策略 CRD(如 Server、AuthorizationPolicy);linkerd-proxy 作为反身代理,为控制面组件间通信提供 mTLS 和可观测性。

Linkerd 2.20 对 destination 控制器做了哪些内存优化?效果如何?

Linkerd 2.20 重构了 destination 控制器的内部状态管理,在具有相同过滤条件的订阅者之间共享端点过滤和 diff 状态,减少了重复的 EndpointSlice diff 副本。官方负载测试显示内存最高可降低约 84%,但实际效果需根据集群的 churn 情况评估。

Linkerd destination 与 Istio Pilot 在配置分发机制上有何不同?

Linkerd destination 采用 per-target 的 gRPC Get() 流,每个目标服务维护独立的流,按需推送变更;而 Istio Pilot 使用 xDS 协议,按资源类型和名字集合进行订阅和广播。排障时应关注目标服务的 Get() 流是否存活,而不是 EDS 订阅 ACK。

sp-validator 在 Linkerd 中扮演什么角色?如果 ServiceProfile 校验失败会怎样?

sp-validator 是 ValidatingAdmissionWebhook,在 ServiceProfile 持久化到 etcd 之前校验其语法和约束,防止无效配置进入集群。如果校验失败,资源会被拒绝,客户端会收到 webhook 错误。

policy 容器在 destination Pod 中负责什么?它与端点翻译解耦有什么好处?

policy 容器是独立控制器,负责求值 Server、AuthorizationPolicy、MeshTLSAuthentication 等策略 CRD,并将结果供 destination 组合进对 proxy 的响应。与端点翻译解耦的好处是:policy 控制器可独立升级或扩容,且 admission 阶段的错误不会污染已建立的 Get() 流。

为什么 destination Pod 内要包含一个 linkerd-proxy 容器?

destination Pod 内的 linkerd-proxy 是反身代理,让控制面组件间的 gRPC 和 HTTP 流量也经过 mesh,获得 mTLS 和黄金指标。这体现了 Linkerd 控制面自身也使用服务网格,便于统一运维和观测。

🏷️

标签

➡️

继续阅读