Kubernetes拓扑感知路由

2023-10-23 50

拓扑感知路由(Toplogy Aware Routing)调整路由行为,以优先保持流量在其发起区域内。 这种方式在某些情况下有助于降低成本或提高网络性能。拓扑感知路由是 Kubernetes 中用于确定 Pod 之间最优路径的机制。通过使用节点和区域信息,将流量保留在同一个区域中,可以实现更好的网络性能和更低的成本。这对那些需要处理大量网络流量的场景尤为重要。

拓扑感知路由还可以提供更好的容错能力。如果一个区域的节点宕机,可以轻松地将流量切换到另一个区域中的节点上,从而确保服务的连续性和稳定性。

一、动机

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

二、启用拓扑感知路由

在 Kubernetes 1.27 之前,此行为是通过 service.kubernetes.io/topology-aware-hints 注解来控制的。

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

三、效果最佳时间

此特性在以下场景中的工作效果最佳:

1、 入站流量均匀分布

如果大部分流量源自同一个区域,则该流量可能会使分配到该区域的端点子集过载。 当预计入站流量源自同一区域时,不建议使用此特性。

2、 服务在每个区域具有至少 3 个端点

在一个三区域的集群中,这意味着有至少 9 个端点。如果每个区域的端点少于 3 个, 则 EndpointSlice 控制器很大概率(约 50%)无法平均分配端点,而是回退到默认的集群范围的路由方法。

四、工作原理

“自动”启发式算法会尝试按比例分配一定数量的端点到每个区域。 请注意,这种启发方式对具有大量端点的 Service 效果最佳。

1、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"

2、kube-proxy

kube-proxy 组件依据 EndpointSlice 控制器设置的提示,过滤由它负责路由的端点。 在大多数场合,这意味着 kube-proxy 可以把流量路由到同一个区域的端点。 有时,控制器在另一不同的区域中分配端点,以确保在多个区域之间更平均地分配端点。 这会导致部分流量被路由到其他区域。

五、保护措施

Kubernetes 控制平面和每个节点上的 kube-proxy 在使用拓扑感知提示信息前,会应用一些保护措施规则。 如果规则无法顺利通过,kube-proxy 将无视区域限制,从集群中的任意位置选择端点。

1、端点数量不足: 如果一个集群中,端点数量少于区域数量,控制器不创建任何提示。

2、不可能实现均衡分配: 在一些场合中,不可能实现端点在区域中的平衡分配。 例如,假设 zone-a 比 zone-b 大两倍,但只有 2 个端点, 那分配到 zone-a 的端点可能收到比 zone-b 多两倍的流量。 如果控制器不能确保此“期望的过载”值低于每一个区域可接受的阈值,控制器将不添加提示信息。 重要的是,这不是基于实时反馈。所以对于特定的端点仍有可能超载。

3、一个或多个 Node 信息不足: 如果任一节点没有设置标签 topology.kubernetes.io/zone, 或没有上报可分配的 CPU 数据,控制平面将不会设置任何拓扑感知提示, 进而 kube-proxy 也就不能根据区域来过滤端点。

4、至少一个端点没有设置区域提示: 当这种情况发生时, kube-proxy 会假设从拓扑感知提示到拓扑感知路由(或反方向)的迁移仍在进行中, 在这种场合下过滤 Service 的端点是有风险的,所以 kube-proxy 回退到使用所有端点。

5、提示中不存在某区域: 如果 kube-proxy 无法找到提示中指向它当前所在的区域的端点, 它将回退到使用来自所有区域的端点。当向现有集群新增新的区域时,这种情况发生概率很高。

六、限制

1、当 Service 的 internalTrafficPolicy 值设置为 Local 时, 系统将不使用拓扑感知提示信息。可以在同一集群中的不同 Service 上使用这两个特性, 但不能在同一个 Service 上这么做。

2、这种方法不适用于大部分流量来自于一部分区域的 Service。 相反,这项技术的假设是入站流量与各区域中节点的服务能力成比例关系。

3、EndpointSlice 控制器在计算各区域的比例时,会忽略未就绪的节点。 在大部分节点未就绪的场景下,这样做会带来非预期的结果。

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

5、EndpointSlice 控制器在分派或计算各区域的比例时,并不会考虑 容忍度。 如果 Service 背后的各 Pod 被限制只能运行在集群节点的一个子集上,计算比例时不会考虑这点。

6、这项技术和自动扩缩容机制之间可能存在冲突。例如,如果大量流量来源于同一个区域, 那只有分配到该区域的端点才可用来处理流量。这会导致 Pod 自动水平扩缩容 要么不能处理这种场景,要么会在别的区域添加 Pod。

七、自定义启发方式

Kubernetes 提供了多种部署方式,但没有一种启发式方法可以适用于所有场景来按区域分配端点。因此,Kubernetes 引入了自定义启发式方法的能力,以满足不同使用场景的需求。该特性的关键目标是允许用户在无法满足其需求的情况下开发自定义的启发式方法。

在 Kubernetes 1.27 版本中,已经实现了启用自定义启发式方法的第一步。这是一个相对受限的实现,可能尚未涵盖一些重要的、可进一步探索的场景。然而,这为用户提供了一个开始定制化路由行为的平台,并为未来的改进和探索铺平了道路。

  • 广告合作

  • QQ群号:707632017

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。