拓扑感知路由

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

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

动机

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

启用拓扑感知路由

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

何时效果最佳

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

1. 入站流量均匀分布

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

2. Service 在每个可用区有 3 个或更多端点

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

工作原理

“自动”启发式算法试图按比例将一定数量的端点分配给每个可用区。请注意,此启发式算法最适用于具有大量端点的 Service。

EndpointSlice 控制器

启用此启发式算法时,EndpointSlice 控制器负责在 EndpointSlice 上设置提示。控制器将按比例分配端点到每个可用区。此比例基于在该可用区中运行的节点的可分配 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 控制器在部署或计算每个可用区的比例时,不考虑容忍度。如果 Service 背后的 Pods 仅限于集群中的节点子集,则不会考虑这一点。

  • 这可能与自动扩缩不协调。例如,如果大量流量源自单个可用区,则只有分配给该可用区的端点会处理该流量。这可能导致 Horizontal Pod Autoscaler 未检测到此事件,或者新添加的 Pods 在不同的可用区启动。

自定义启发式算法

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

下一步

  • 请参阅使用 Service 连接应用程序教程
  • 了解与 service.kubernetes.io/topology-mode 注解密切相关的 trafficDistribution 字段,它为 Kubernetes 中的流量路由提供了灵活的选项。
上次修改时间:2024 年 6 月 4 日 上午 11:40 PST:修复 topology-aware-routing.md 中的失效链接 (b0b5779581)