拓扑感知路由

拓扑感知路由 提供了一种机制,有助于将网络流量保持在它最初产生的区域内。在集群中,Pod 之间优先使用同一区域的流量,有助于提高可靠性、性能(网络延迟和吞吐量)或降低成本。
特性状态: Kubernetes v1.23 [beta]

拓扑感知路由 调整路由行为,优先将流量保持在其来源区域内。在某些情况下,这有助于降低成本或提高网络性能。

动机

Kubernetes 集群越来越多地部署在多区域环境中。拓扑感知路由 提供了一种机制,有助于将流量保持在它最初产生的区域内。在计算 Service 的端点时,EndpointSlice 控制器会考虑每个端点的拓扑(区域和地区),并填充提示字段以将其分配给一个区域。诸如 kube-proxy 等集群组件随后可以消费这些提示,并使用它们来影响流量的路由方式(优先选择拓扑上更近的端点)。

启用拓扑感知路由

你可以通过将 service.kubernetes.io/topology-mode 注解设置为 Auto 来为一个 Service 启用拓扑感知路由。当每个区域都有足够的可用端点时,拓扑提示将填充到 EndpointSlices 上,以将各个端点分配到特定区域,从而使流量路由到更接近其来源的位置。

最佳工作时机

此功能在以下情况下效果最佳

1. 入站流量均匀分布

如果大部分流量来自单个区域,则该流量可能会使已分配给该区域的端点子集过载。当预期入站流量来自单个区域时,不建议使用此功能。

2. Service 每个区域有 3 个或更多端点

在一个三区域集群中,这意味着 9 个或更多端点。如果每个区域的端点少于 3 个,则 EndpointSlice 控制器将无法均匀分配端点,而是会回退到默认的集群范围路由方法,这种可能性很高(≈50%)。

工作原理

“Auto”启发式方法尝试按比例为每个区域分配一定数量的端点。请注意,此启发式方法最适合具有大量端点的 Service。

EndpointSlice 控制器

当启用此启发式方法时,EndpointSlice 控制器负责在 EndpointSlices 上设置提示。控制器会为每个区域分配按比例数量的端点。此比例基于在该区域中运行的节点的可分配 CPU 核心数。例如,如果一个区域有 2 个 CPU 核心,而另一个区域只有 1 个 CPU 核心,则控制器会将两倍的端点分配给具有 2 个 CPU 核心的区域。

以下示例显示了填充提示后的 EndpointSlice 的外观

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: example-hints
  labels:
    kubernetes.io/service-name: example-svc
addressType: IPv4
ports:
  - name: http
    protocol: TCP
    port: 80
endpoints:
  - addresses:
      - "10.1.2.3"
    conditions:
      ready: true
    hostname: pod-1
    zone: zone-a
    hints:
      forZones:
        - name: "zone-a"

kube-proxy

kube-proxy 组件根据 EndpointSlice 控制器设置的提示来过滤其路由到的端点。在大多数情况下,这意味着 kube-proxy 能够将流量路由到同一区域中的端点。有时,控制器会从不同的区域分配端点,以确保区域之间更均匀地分配端点。这将导致一些流量被路由到其他区域。

安全措施

Kubernetes 控制平面和每个节点上的 kube-proxy 在使用拓扑感知提示之前会应用一些安全规则。如果这些规则没有通过检查,则 kube-proxy 会从集群中的任何位置选择端点,而不管区域如何。

  1. 端点数量不足: 如果集群中的端点少于区域数,则控制器将不会分配任何提示。

  2. 无法实现均衡分配: 在某些情况下,无法实现区域之间端点的均衡分配。例如,如果 zone-a 比 zone-b 大两倍,但只有 2 个端点,则分配给 zone-a 的端点可能接收的流量是 zone-b 的两倍。如果控制器无法使每个区域的“预期过载”值低于可接受的阈值,则不会分配提示。重要的是,这并非基于实时反馈。单个端点仍然可能变得过载。

  3. 一个或多个节点的信息不足: 如果任何节点没有 topology.kubernetes.io/zone 标签,或者没有报告可分配的 CPU 值,则控制平面不会设置任何拓扑感知端点提示,因此 kube-proxy 不会按区域过滤端点。

  4. 一个或多个端点没有区域提示: 发生这种情况时,kube-proxy 假设正在进行从拓扑感知提示过渡到或过渡出的过程。在这种状态下为 Service 过滤端点将是危险的,因此 kube-proxy 会回退到使用所有端点。

  5. 提示中未表示区域: 如果 kube-proxy 无法找到至少一个提示目标指向其正在运行的区域的端点,则会回退到使用来自所有区域的端点。当你向现有集群添加新区域时,最有可能发生这种情况。

约束

  • 当 Service 上的 internalTrafficPolicy 设置为 Local 时,不会使用拓扑感知提示。可以在同一集群中的不同 Service 上使用这两个功能,但不能在同一个 Service 上使用。

  • 对于大部分流量来自部分区域的 Service,此方法效果不佳。相反,这假设入站流量将大致与每个区域中节点的容量成正比。

  • EndpointSlice 控制器在计算每个区域的比例时会忽略未就绪的节点。如果大部分节点都未就绪,这可能会产生意想不到的后果。

  • EndpointSlice 控制器会忽略设置了 node-role.kubernetes.io/control-planenode-role.kubernetes.io/master 标签的节点。如果工作负载也运行在这些节点上,这可能会有问题。

  • EndpointSlice 控制器在部署或计算每个区域的比例时,不会考虑容忍度。如果支持服务的 Pod 仅限于集群中的一部分节点,则不会考虑这一点。

  • 这可能无法很好地与自动扩缩一起工作。例如,如果大量流量来自单个区域,则只有分配给该区域的端点将处理该流量。这可能导致水平 Pod 自动扩缩器要么没有注意到此事件,要么新添加的 Pod 在不同的区域中启动。

自定义启发式算法

Kubernetes 的部署方式多种多样,没有一种将端点分配给区域的启发式算法适用于所有用例。此功能的一个关键目标是,如果内置的启发式算法不适用于您的用例,则可以开发自定义启发式算法。启用自定义启发式算法的第一步已包含在 1.27 版本中。这是一个有限的实现,可能尚未涵盖某些相关且合理的情况。

下一步是什么

上次修改时间为 2024 年 6 月 4 日上午 11:40(太平洋标准时间):修复 topology-aware-routing.md 中的断开链接 (b0b5779581)