拓扑感知路由

拓扑感知路由 提供了一种机制,可帮助将网络流量保留在其 originating 的区域内。优先考虑集群中 Pod 之间的同区域流量有助于提高可靠性、性能(网络延迟和吞吐量)或降低成本。
功能状态: Kubernetes v1.23 [测试版]

拓扑感知路由 调整路由行为,以优先将流量保留在其 originating 的区域内。在某些情况下,这可以帮助降低成本或提高网络性能。

动机

Kubernetes 集群越来越多地部署在多区域环境中。 拓扑感知路由 提供了一种机制,可帮助将流量保留在其 originating 的区域内。在为 服务 计算端点时,EndpointSlice 控制器会考虑每个端点的拓扑(区域和可用区),并填充提示字段以将其分配给某个可用区。集群组件(例如 kube-proxy)随后可以使用这些提示,并使用它们来影响流量的路由方式(优先考虑拓扑更近的端点)。

启用拓扑感知路由

您可以通过将 service.kubernetes.io/topology-mode 注释设置为 Auto 来为服务启用拓扑感知路由。当每个可用区中有足够的可用端点时,将在 EndpointSlices 上填充拓扑提示,以将各个端点分配给特定的可用区,从而使流量路由到更靠近其 originating 的位置。

最佳工作条件

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

1. 传入流量均匀分布

如果很大一部分流量 originating 自单个可用区,则该流量可能会使已分配给该可用区的端点子集过载。如果预计传入流量 originating 自单个可用区,则不建议使用此功能。

2. 服务每个可用区有 3 个或更多端点

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

工作原理

“自动”启发式算法尝试按比例将多个端点分配给每个可用区。请注意,此启发式算法最适合具有大量端点的服务。

EndpointSlice 控制器

EndpointSlice 控制器负责在此启发式算法启用时设置 EndpointSlices 上的提示。控制器将按比例分配一定数量的端点给每个可用区。此比例基于运行在该可用区中的节点的 可分配 CPU 内核数。例如,如果一个可用区有 2 个 CPU 内核,而另一个可用区只有 1 个 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. 无法实现均衡分配: 在某些情况下,将无法实现可用区之间端点的均衡分配。例如,如果可用区 a 的大小是可用区 b 的两倍,但只有 2 个端点,则分配给可用区 a 的端点接收到的流量可能是可用区 b 的两倍。如果控制器无法将每个可用区的“预期过载”值降低到可接受的阈值以下,则它不会分配提示。重要的是,这不是基于实时反馈。各个端点仍然有可能过载。

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

  4. 一个或多个端点没有可用区提示: 发生这种情况时,kube-proxy 会假定正在进行从拓扑感知提示到拓扑感知提示的转换。在此状态下过滤服务的端点将很危险,因此 kube-proxy 会回退到使用所有端点。

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

约束

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

  • 对于 originating 自一部分可用区的流量比例很大的服务,此方法将无法很好地工作。相反,这假设传入流量将大致与每个可用区中节点的容量成正比。

  • EndpointSlice 控制器在计算每个可用区的比例时会忽略未准备好的节点。如果很大一部分节点未准备好,这可能会产生意想不到的后果。

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

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

  • 这可能不适用于自动缩放。例如,如果大量流量 originating 自单个可用区,则只有分配给该可用区的端点才会处理该流量。这可能会导致 水平 Pod 自动缩放器 未检测到此事件,或者新添加的 Pod 在不同可用区中启动。

自定义启发式算法

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

后续步骤

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