我目前正在从Service Fabric切换到Kubernetes,并且想知道如何进行自定义和更复杂的负载平衡。
到目前为止,我已经阅读了有关Kubernetes提供“服务”的信息,该服务可以为隐藏在其后的Pod进行负载平衡,但这只能以更简单的方式提供。
我现在要重写的内容在Service Fabric中如下所示:
我有这个界面:
public interface IEndpointSelector
{
int HashableIdentifier { get; }
}
在我的ASP.Net应用程序中跟踪帐户的上下文,例如继承这个。然后,我编写了一些代码,到目前为止,这些代码将通过服务结构集群API进行服务发现,并跟踪所有服务,并在任何实例死亡或重新生成时更新它们。
然后,基于此标识符的确定性(由于缓存了上下文等),并给定了前端目标服务的多个副本->后端调用,我可以将某个帐户的流量可靠地路由到某些终结点实例。
现在,我将如何在Kubernetes中做到这一点?
正如我已经提到的,我找到了“服务”,但是它们的负载平衡似乎不支持自定义逻辑,而仅在处理无状态实例时才有用。
在Kubernetes中是否还有一种服务发现的方法,可以在某些地方用来替换现有代码?
答案 0 :(得分:2)
StatefulSet是构建块,可确保在Kubernetes上进行有状态的工作负载。
StatefulSet Pod具有由序号,稳定的网络身份和稳定的存储组成的唯一身份。
例如,如果您的StatefulSet名称为sharded-svc
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sharded-svc
例如3个副本,它们将由<name>-<ordinal>
命名,其中 ordinal 从0开始到副本1。
您的广告连播名称为:
sharded-svc-0
sharded-svc-1
sharded-svc-2
并且可以使用dns名称访问这些吊舱:
sharded-svc-0.sharded-svc.your-namespace.svc.cluster.local
sharded-svc-1.sharded-svc.your-namespace.svc.cluster.local
sharded-svc-2.sharded-svc.your-namespace.svc.cluster.local
假设您的 Headless服务被命名为sharded-svc
,并且将其部署在命名空间your-namespace
中。
考虑到前端目标服务的多个副本->后端调用,我可以可靠地将某个帐户的流量路由到某个终结点实例。
您在这里描述的是您的有状态服务就是所谓的 sharded 或 partitioned 。 Kubernetes并不是开箱即用的,但是您拥有了所有需要的构建基块来进行这种服务。 它可能存在于提供该功能的第三方服务中,您可以对其进行部署,也可以对其进行开发。
您可以创建由多个Pod之一组成的服务sharding-proxy
(可能来自Deployment,因为它可能是无状态的)。此应用需要查看sharded-svc
中的pods / service / endpoints,才能知道它可以将流量路由到何处。可以使用client-go或其他替代方法进行开发。
此服务可实现您在分片中所需的逻辑,例如 account-nr 模数3被路由到相应的pod ordinal
更新:存在具有 sharding 功能的第三方代理,例如Weaver Proxy
基于标题/路径/正文字段的共享请求
推荐阅读:Weaver: Sharding with simplicity
要使用您的分片服务,客户端会将请求发送到您的sharding-proxy
,然后应用您的路由或分片逻辑(例如,具有 account的请求-nr 模数3被路由到相应的Pod(标准),并将请求转发到与您的逻辑相符的sharded-svc
的副本。>
目录服务:将sharded-proxy
实施为目录服务可能会更容易,但这取决于您的要求。客户可以问您的目录服务我应该向哪个statefulSet副本发送 account-nr X ,您的服务答复例如sharded-svc-2
客户端中的路由逻辑:可能最简单的解决方案是在客户端中使用路由逻辑,并让该逻辑计算到哪个statefulSet副本发送请求
答案 1 :(得分:0)
由于性能原因,服务通常在内核空间中运行代理,因此编写自定义代码很困难。 Cillium确实允许为某些网络功能编写eBPF程序,但我认为服务路由不是其中之一。因此,这几乎意味着要使用用户空间代理。如果您的服务是基于HTTP的,则可以查看一些现有的Ingress控制器,以查看它们是否足够接近或允许您编写自己的自定义会话路由逻辑。否则,您必须自己编写一个守护程序来处理它。