将其作为社区 wiki 发布在评论中以获得更好的可见性,请随意编辑和扩展。
解决这个问题的最佳选择是使用istio - Locality Load Balancing https://istio.io/latest/docs/tasks/traffic-management/locality-load-balancing/。链接中的要点:
地点定义工作负载实例的地理位置
在你的网格内。以下三元组定义了一个位置:
-
区域:代表较大的地理区域,例如美国东部。一个区域通常包含多个可用区。在
Kubernetes,标签topology.kubernetes.io/region决定了
节点的区域。
-
区域:区域内的一组计算资源。通过在一个区域内的多个可用区中运行服务,可以在不同可用区之间进行故障转移
区域内的区域,同时保持数据局部性
最终用户。在 Kubernetes 中,标签 topology.kubernetes.io/zone
确定节点的区域。
-
分区:允许管理员进一步细分分区,进行更细粒度的控制,例如“同架”。分区概念
Kubernetes 中不存在。因此,Istio 引入了自定义
节点标签topology.istio.io/subzone来定义子区域。
这意味着 Pod 在区域中运行bar
地区的foo
不是
被认为是在区域中运行的 Pod 的本地资源bar
地区的baz
.
评论中建议了可以考虑进行流量平衡调整的另一个选项:
use nodeAffinity https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity实现调度之间的一致性pods
and nodes
在特定的“地区”。
目前有两种类型的节点亲和力,称为requiredDuringSchedulingIgnoredDuringExecution
and
preferredDuringSchedulingIgnoredDuringExecution
。你可以想到
它们分别为“硬”和“软”,因为前者
指定将 Pod 调度到节点上必须满足的规则
(类似于nodeSelector,但使用更具表现力的语法),而
后者指定调度程序将尝试的首选项
强制执行但不保证。的“IgnoredDuringExecution”部分
名称意味着,类似于 nodeSelector 的工作方式,如果标签在
节点在运行时发生变化,使得 Pod 上的亲和性规则不存在
当时间不再满足时,Pod 会继续在节点上运行。未来我们
计划提供requiredDuringSchedulingRequiredDuringExecution
哪个
将等同于requiredDuringSchedulingIgnoredDuringExecution
除了它会从不再满足条件的节点中驱逐 pod
Pod 的节点关联性要求。
因此,一个例子requiredDuringSchedulingIgnoredDuringExecution
将是“仅在具有 Intel CPU 的节点上运行 pod”和一个示例preferredDuringSchedulingIgnoredDuringExecution
将是“尝试运行
这组 pod 位于故障区域 XYZ,但如果不可能,那么
允许一些人跑到别处”。
Update: 基于@mirekphd 评论 https://stackoverflow.com/questions/70006961/best-method-to-keep-client-server-traffic-in-the-same-region-node-in-kubernete#comment123810994_70036319,它仍然无法按照要求的方式充分发挥作用:
事实证明,在实践中 Kubernetes 并没有真正让我们切换
一旦我们启动了实际数量的 Pod,就离开辅助区域
复制品(只需几个就足以看到它)......他们至少保留了一些
按照设计,将 Pod 放置在其他区域/DC/区域中(当您
意识到它消除了对 docker 注册表的依赖
生存,至少在标记图像的默认 imagePullPolicy 下),GitHub 问题 #99630 - NodeAffinity PreferredDuringSchedulingIgnoredDuringExecution 效果不佳 https://github.com/kubernetes/kubernetes/issues/99630#issuecomment-790740081
请参阅@mirekphd 的回答 https://stackoverflow.com/a/70041931/15537201