拓扑感知路由
Kubernetes v1.23 [beta]
注意
在 Kubernetes 1.27 之前,此功能被称为拓扑感知提示。拓扑感知路由调整路由行为,优先考虑将流量保留在其起源区域。在某些情况下,这有助于降低成本或改善网络性能。
动机
Kubernetes 集群越来越多地部署在多区域环境中。拓扑感知路由提供了一种机制,有助于将流量保留在其起源区域。在计算一组 Pod 上运行的应用程序作为网络服务公开的方式的端点时,EndpointSlice 控制器会考虑每个端点的拓扑结构(区域和区域)并填充提示字段,将其分配到区域。集群组件(如 kube-proxy)可以随后使用这些提示,并利用它们来影响流量的路由方式(优先考虑拓扑上更近的端点)。
启用拓扑感知路由
注意
在 Kubernetes 1.27 之前,此行为通过service.kubernetes.io/topology-aware-hints
批注进行控制。您可以通过将service.kubernetes.io/topology-mode
批注设置为Auto
,为服务启用拓扑感知路由。当每个区域中有足够的端点可用时,EndpointSlices 上将填充拓扑提示以将单个端点分配到特定区域,从而导致流量路由到更靠近其起源的位置。
最佳工作情况
此功能在以下情况下效果最佳
1. 入站流量均匀分布
如果很大比例的流量来自单个区域,那么流量可能会过载分配到该区域的端点子集。如果预期入站流量来自单个区域,则不建议使用此功能。
2. 服务在每个区域至少有 3 个端点
在三区域集群中,这意味着至少有 9 个端点。如果每个区域的端点少于 3 个,EndpointSlice 控制器无法均匀分配端点的可能性很高(≈50%),并且会回退到默认的集群范围路由方法。
工作原理
“Auto”启发式方法试图按比例将一定数量的端点分配到每个区域。请注意,此启发式方法最适合具有大量端点的服务。
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 将从集群中的任何地方选择端点,而不管区域如何。
端点数不足:如果集群中的端点少于区域数,则控制器不会分配任何提示。
无法实现均衡分配:在某些情况下,无法在区域之间实现端点的均衡分配。例如,如果区域 a 是区域 b 的两倍大,但只有 2 个端点,分配到区域 a 的端点可能会接收区域 b 的两倍流量。如果控制器无法将此“预期过载”值降到每个区域的允许阈值以下,则不会分配提示。重要的是,这不是基于实时反馈。各个端点仍然可能过载。
一个或多个节点信息不足:如果任何节点没有
topology.kubernetes.io/zone
标签,或者没有报告可分配 CPU 的值,则控制平面不会设置任何拓扑感知端点提示,因此 kube-proxy 不会按区域过滤端点。一个或多个端点没有区域提示:发生这种情况时,kube-proxy 假设正在进行从拓扑感知提示的转换或向拓扑感知提示的转换。在这种状态下,为服务过滤端点将很危险,因此 kube-proxy 会回退到使用所有端点。
区域在提示中没有表示:如果 kube-proxy 无法找到至少一个具有指向其运行区域的提示的端点,它会回退到使用来自所有区域的端点。当您将新区域添加到现有集群时,这种情况最有可能发生。
约束
当服务的
internalTrafficPolicy
设置为Local
时,不使用拓扑感知提示。可以在集群中的不同服务上同时使用这两个功能,但不能在同一服务上使用。这种方法对于来自区域子集的很大比例的流量来自的那些服务来说效果不佳。相反,它假设入站流量与每个区域中节点的容量大致成比例。
EndpointSlice 控制器在计算每个区域的比例时会忽略未就绪的节点。如果很大一部分节点未就绪,这可能会产生意想不到的后果。
EndpointSlice 控制器会忽略设置了
node-role.kubernetes.io/control-plane
或node-role.kubernetes.io/master
标签的节点。如果工作负载也在这些节点上运行,这可能会成为问题。EndpointSlice 控制器在部署或计算每个区域的比例时,不会考虑容忍度。如果支持服务的 Pod 被限制在集群中的节点子集内,则不会考虑这一点。
这可能不适用于自动缩放。例如,如果大量流量来自单个区域,则只有分配到该区域的端点会处理该流量。这可能会导致水平 Pod 自动缩放要么没有接收到此事件,要么新添加的 Pod 启动在不同的区域。
自定义启发式方法
Kubernetes 的部署方式多种多样,没有一个单一的启发式方法可以将端点分配到区域以适用于所有用例。此功能的一个关键目标是启用自定义启发式方法的开发,如果内置的启发式方法不适用于您的用例。在 1.27 版本中包含了启用自定义启发式方法的第一步。这是一个有限的实现,可能还没有涵盖一些相关的和合理的场景。
下一步
- 按照使用服务连接应用程序教程操作
- 了解与
service.kubernetes.io/topology-mode
批注密切相关的trafficDistribution字段,它为 Kubernetes 中的流量路由提供了灵活的选项。