动态路由 HTTP 流量到用户特定的 Docker 容器

动态路由 HTTP 流量到用户特定的 Docker 容器

我正在尝试构建一项服务,该服务将在 AWS(最有可能是 ECS)中的 Docker 容器内运行用户特定的 Java 进程。每个用户每个容器一个 Java 进程。唯一的例外可能是启动一个替换容器来替换行为不正常的容器。Java 进程是一个打包的软件,无法修改以满足我的需求。我本质上是希望围绕这个特定的软件构建一个 SaaS 服务,我知道需要与软件开发人员协商许可细节。

Java 进程有自己的内置 Web 服务器,它使用非标准端口(例如 30000-30004)来访问其 WebUI。它可以根据配置支持 HTTP 或 HTTPS。我计划在每个 EC2 实例上运行尽可能多的这些容器,以使其更具成本效益(这意味着 EC2 实例上的不同端口映射到容器的内部端口(30000-30004)。

我想将 Java 进程的内置 UI 与一些其他元素包装在一起,以便控制 Java 进程(停止、启动等),并通过另一个 Web 服务器或可能通过 Lambda 的 API 网关提供我的 UI。这将允许用户根据需要启动或停止其实例,并且整个系统将使用这些请求来启动或停止用户的特定 Docker 容器。

举个例子,可能会有数万个并发用户。该项目的预计市场规模约为 100,000 名用户。可能的市场规模约为每月 200 万用户。实际上,总用户数可能约为 10,000 名,其中约 7,500 名在任何给定月份内处于活跃状态。由于 ALB 的限制仅允许 1000 个目标和 100 条规则,因此潜在的规模可能会消除使用应用程序负载均衡器为每个用户的容器实例设置单独的目标和目标组的选项。

为了解变化率,单个容器可能需要在用户与其交互时运行几个小时甚至一天或更长时间。但它也可能偶尔只使用几分钟。单个用户的容器可能每周或每两周只需要一次,也可能每天都需要使用。

现在来回答这个问题,处理上述 Docker 容器的路由流量的最佳解决方案有哪些?我希望从自己的域托管所有这些内容,并使用基于路径的路由将请求发送到正确的容器。

例如:

  • container1 适用于在主机 ec2-app1 的端口 30000-30004 上运行的用户 1
  • container2 适用于在主机 ec2-app1 的端口 31000-31004 上运行的用户 2
  • container3 适用于在主机 ec2-app2 的端口 30000-30004 上运行的用户 3

用户不应能够访问除专门为其会话启动的容器之外的任何容器。Java 进程中有一些内置身份验证可用于帮助实现这一点。

我本质上是在用单用户软件构建多租户服务,我知道我必须构建相当多的自定义工具,但我并不反对这样做。当需要自定义代码时,我更喜欢与 Python 配合良好的解决方案,但如果有必要,也欢迎使用其他语言。我怀疑我需要在容器内或执行它们的 EC2 实例上包含某种代理或启动脚本,这些脚本将在容器启动后将容器注册到路由系统。然后,我需要研究一个类似的关闭脚本来删除容器的注册,以及一个常规系统,以便在容器或 EC2 实例因未正确关闭而失败时进行清理。我已经研究过 HAProxy 和 Nginx,我愿意听取有关这些的想法,但也非常欢迎其他选择。

提前感谢您的建议!

答案1

您绝对正确,您需要创建大量自定义工具来实现这一点,但我认为这是可以做到的。

我采用的方法是使用应用程序负载均衡器 (ALB) 和目标组。ALB 可以根据路径创建自定义路由,并根据路径规则匹配将流量发送到特定目标组(即服务器,或者在您的情况下是 Docker 容器),例如:

  • 规则 1:路径以 /user1 开始,将流量发送到 TG1
  • 规则 2:路径以 /user2 开始,将流量发送到 TG2
  • ETC..
  • 规则 N:默认规则,所有其他流量到 TGN(您的主站点、404 处理程序等)

您将需要创建工具来;

  • 配置为用户提供服务所需的容器。Docker 容器可以使用动态端口,并且同一个 EC2/ECS 实例可以存在于不同端口上的多个 TG 中。容器处于活动状态后,找出它正在监听的动态端口。
  • 提供一个 TG 来托管这些容器,并在适当的端口上注册适当的目标。
  • 更新您的 ALB 以为您的路径添加新规则,路由到您刚刚创建的 TG。
  • 重定向用户

您可能可以在 Lambda 函数的范围内完成所有这些操作。我看不出有什么理由要花超过 5 分钟的最大生命周期来完成这些操作……最长的部分是等待容器激活,但即使这样也不算太长。

相关内容