Kubernetes中的有状态服务的分片负载平衡 [英] Sharded load balancing for stateful services in Kubernetes
问题描述
我目前正在从Service Fabric切换到Kubernetes,并且想知道如何进行自定义和更复杂的负载平衡.
到目前为止,我已经阅读了有关Kubernetes提供服务"的信息,该服务可以对隐藏在其后的Pod进行负载平衡,但这只能以更简单的方式提供.
我现在要重写的内容在Service Fabric中如下所示:
我有这个界面:
公共接口IEndpointSelector{int HashableIdentifier {get;}}
在我的ASP.Net应用程序中跟踪帐户的上下文,例如继承这个.然后,我编写了一些代码,到目前为止,这些代码将通过服务结构集群API进行服务发现,并跟踪所有服务,并在任何实例死亡或被重新生成时更新它们.
然后,基于此标识符的确定性(由于缓存了上下文等),并给出了前端目标服务的多个副本->后端调用,我可以将某个帐户的流量可靠地路由到某些终结点实例.
现在,我将如何在Kubernetes中做到这一点?
正如我已经提到的,我找到了服务",但是它们的负载平衡似乎不支持自定义逻辑,而仅在处理无状态实例时才有用.
在Kubernetes中是否还有一种服务发现的方法,我可以在这里用来替换现有代码?
StatefulSet
StatefulSet 是构建模块Kubernetes上有状态的工作负载,并且有一定的保证.
稳定且唯一的网络身份
StatefulSet Pod具有由序号,稳定的网络身份和稳定的存储组成的唯一身份.
例如,如果您的StatefulSet名称为 sharded-svc
apiVersion:apps/v1种类:StatefulSet元数据:名称:sharded-svc
例如3个副本,这些副本将由< name>-< ordinal>
命名,其中 ordinal 从0开始到副本1.
您的广告连播名称为:
sharded-svc-0分片-svc-1分片-svc-2
,并且可以使用dns名称访问这些吊舱:
sharded-svc-0.sharded-svc.your-namespace.svc.cluster.localsharded-svc-1.sharded-svc.您的命名空间.svc.cluster.localsharded-svc-2.sharded-svc.您的命名空间.svc.cluster.local
假设您的 Headless Service 被命名为 sharded-svc
,并将其部署在名称空间 your-namespace
中.
共享或分区
考虑到前端目标服务的多个副本->后端调用,我可以可靠地将某个帐户的流量路由到某个终结点实例.
您在这里描述的是,您的有状态服务就是所谓的 sharded 或 partitioned .Kubernetes并没有开箱即用,但是您已经具备了所有需要的构建基块来进行这种服务.可能会存在一个第三方服务,该服务可提供您可以部署的功能,也可以对其进行开发.
共享代理
您可以创建由多个Pod之一组成的服务 sharding-proxy
(可能来自端点sharded-svc 知道它可以将流量路由到何处.可以使用 client-go 或其他替代方法进行开发.
此服务可实现您在分片中所需的逻辑,例如 account-nr 模数3被路由到相应的pod ordinal
更新:存在具有 sharding 功能的第三方代理,例如 Weaver代理
基于标题/路径/正文字段的共享请求
推荐阅读: Weaver:简单的分片
使用分片服务
要使用您的分片服务,客户端会将请求发送到您的 sharding-proxy
,然后应用您的 routing 或 sharding逻辑(例如,请求具有 account-nr 模数3的路由发送到相应的Pod(emordinal ),并将请求转发给 sharded-svc
与您的逻辑相符.
替代解决方案
目录服务:将 sharded-proxy
实现为目录服务可能会更容易,但这取决于您的要求.客户可以询问您的目录服务我应该向哪个statefulSet副本发送 account-nr X ,您的服务答复例如 sharded-svc-2
客户端中的路由逻辑:可能最简单的解决方案是在客户端中使用路由逻辑,然后让该逻辑计算到哪个statefulSet副本发送请求
I am currently switching from Service Fabric to Kubernetes and was wondering how to do custom and more complex load balancing.
So far I already read about Kubernetes offering "Services" which do load balancing for pods hidden behind them, but this is only available in more plain ways.
What I want to rewrite right now looks like the following in Service Fabric:
I have this interface:
public interface IEndpointSelector
{
int HashableIdentifier { get; }
}
A context keeping track of the account in my ASP.Net application e.g. inherits this. Then, I wrote some code which would as of now do service discovery through the service fabric cluster API and keep track of all services, updating them when any instances die or are being respawned.
Then, based on the deterministic nature of this identifier (due to the context being cached etc.) and given multiple replicas of the target service of a frontend -> backend call, I can reliably route traffic for a certain account to a certain endpoint instance.
Now, how would I go about doing this in Kubernetes?
As I already mentioned, I found "Services", but it seems like their load balancing does not support custom logic and is rather only useful when working with stateless instances.
Is there also a way to have service discovery in Kubernetes which I could use here to replace my existing code at some points?
StatefulSet
StatefulSet is a building block for stateful workload on Kubernetes with certain guarantees.
Stable and unique network identity
StatefulSet Pods have a unique identity that is comprised of an ordinal, a stable network identity, and stable storage.
As an example, if your StatefulSet has the name sharded-svc
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sharded-svc
And you have e.g. 3 replicas, those will be named by <name>-<ordinal>
where ordinal starts from 0 up to replicas-1.
The name of your pods will be:
sharded-svc-0
sharded-svc-1
sharded-svc-2
and those pods can be reached with a dns-name:
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
given that your Headless Service is named sharded-svc
and you deploy it in namespace your-namespace
.
Sharding or Partitioning
given multiple replicas of the target service of a frontend -> backend call, I can reliably route traffic for a certain account to a certain endpoint instance.
What you describe here is that your stateful service is what is called sharded or partitioned. This does not come out of the box from Kubernetes, but you have all the needed building blocks for this kind of service. It may happen that it exists an 3rd party service providing this feature that you can deploy, or it can be developed.
Sharding Proxy
You can create a service sharding-proxy
consisting of one of more pods (possibly from Deployment since it can be stateless). This app need to watch the pods/service/endpoints in your sharded-svc
to know where it can route traffic. This can be developed using client-go or other alternatives.
This service implements the logic you want in your sharding, e.g. account-nr modulus 3 is routed to the corresponding pod ordinal
Update: There are 3rd party proxies with sharding functionallity, e.g. Weaver Proxy
Sharding request based on headers/path/body fields
Recommended reading: Weaver: Sharding with simplicity
Consuming sharded service
To consume your sharded service, the clients send request to your sharding-proxy
that then apply your routing or sharding logic (e.g. request with account-nr modulus 3 is routed to the corresponding pod ordinal) and forward the request to the replica of sharded-svc
that match your logic.
Alternative Solutions
Directory Service: It is probably easier to implement sharded-proxy
as a directory service but it depends on your requirements. The clients can ask your directory service to what statefulSet replica should I send account-nr X and your serice reply with e.g. sharded-svc-2
Routing logic in client: The probably most easy solution is to have your routing logic in the client, and let this logic calculate to what statefulSet replica to send the request.
这篇关于Kubernetes中的有状态服务的分片负载平衡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!