5

我目前正在从 Service Fabric 切换到 Kubernetes,并且想知道如何进行自定义和更复杂的负载平衡。

到目前为止,我已经阅读了有关 Kubernetes 提供“服务”的信息,这些服务可以为隐藏在它们后面的 pod 进行负载平衡,但这只能以更简单的方式使用。

我现在要重写的内容在 Service Fabric 中如下所示:

我有这个界面:

public interface IEndpointSelector
{
    int HashableIdentifier { get; }
}

例如,在我的 ASP.Net 应用程序中跟踪帐户的上下文会继承这一点。然后,我编写了一些代码,这些代码现在将通过服务结构集群 API 进行服务发现,并跟踪所有服务,并在任何实例死亡或重新生成时更新它们。

然后,基于此标识符的确定性(由于缓存的上下文等),并给定前端 -> 后端调用的目标服务的多个副本,我可以可靠地将某个帐户的流量路由到某个端点实例.

现在,我将如何在 Kubernetes 中执行此操作?

正如我已经提到的,我找到了“服务”,但它们的负载平衡似乎不支持自定义逻辑,并且仅在使用无状态实例时才有用。

还有一种方法可以在 Kubernetes 中进行服务发现,我可以在这里使用它来替换我现有的代码吗?

4

2 回答 2

10

有状态集

StatefulSet是Kubernetes 上的有状态工作负载的构建块,具有一定的保证。

稳定且唯一的网络身份

StatefulSet Pod 具有唯一的身份,由序数、稳定的网络身份和稳定的存储组成。

例如,如果您的 StatefulSet 的名称为sharded-svc

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sharded-svc

例如,您有 3 个副本,这些副本将以序号从 0 到 replicas-1的<name>-<ordinal>位置命名。

您的 pod 的名称将是:

sharded-svc-0
sharded-svc-1
sharded-svc-2

并且可以使用 dns 名称访问这些 pod:

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 Service已命名sharded-svc并且您将其部署在 namespace 中your-namespace

分片或分区

给定前端->后端调用的目标服务的多个副本,我可以可靠地将某个帐户的流量路由到某个端点实例。

您在这里描述的是您的有状态服务是所谓的shardedpartitioned。这不是 Kubernetes 开箱即用的,但您拥有此类服务所需的所有构建块。它可能存在提供此功能的第 3 方服务,您可以部署或开发它。

分片代理

您可以创建一个sharding-proxy由多个 pod 组成的服务(可能来自Deployment,因为它可以是无状态的)。这个应用程序需要观察你的 pods/service/端点sharded-svc以了解它可以将流量路由到哪里。这可以使用client-go或其他替代方案来开发。

该服务在分片中实现您想要的逻辑,例如account-nr模数 3 被路由到相应的 pod序号

更新:有具有分片功能的 3rd 方代理,例如Weaver Proxy

基于 headers/path/body 字段的分片请求

推荐阅读:Weaver:简单的分片

使用分片服务

为了使用您的分片服务,客户端向您发送请求sharding-proxy,然后应用您的路由分片逻辑(例如,将account-nr模数为 3 的请求路由到相应的 pod ordinal)并将请求转发到与您的逻辑匹配的副本。sharded-svc

替代解决方案

目录服务:sharded-proxy作为目录服务实现可能更容易,但这取决于您的要求。客户可以向您的目录服务询问我应该向哪个 statefulSet 副本发送account-nr X和您的服务回复,例如sharded-svc-2

客户端中的路由逻辑:可能最简单的解决方案是将您的路由逻辑 放在客户端中,并让此逻辑计算向哪个 statefulSet 副本发送请求。

于 2019-11-03T08:45:52.843 回答
0

出于性能原因,服务通常在内核空间中运行代理,因此编写自定义代码很困难。Cillium 确实允许为某些网络功能编写 eBPF 程序,但我不认为服务路由是其中之一。所以这几乎意味着使用用户空间代理。如果您的服务是基于 HTTP 的,您可以查看一些现有的 Ingress 控制器,看看是否有足够接近的控制器或允许您编写自己的自定义会话路由逻辑。否则你将不得不自己编写一个守护进程来处理它。

于 2019-11-02T23:39:40.637 回答