适用于运行不受信任代码的多租户平台的 Cloud Run

本页面介绍了创建多租户架构以使用 Cloud Run 托管不受信任的代码的最佳实践。作为 Google Cloud 客户,“租户”定义为您自己的客户之一,“不受信任的代码”是由这些租户提供的要在您的平台上运行的代码。

使用场景

此类架构的使用场景包括:

  • App Hosting 平台:您提供一个平台,供客户部署其代码。例如,网站托管平台(客户提供网络服务器) 或函数即服务平台(客户提供函数)。
  • 智能体托管平台:您的客户使用 SDK 构建 AI 智能体,您的平台在后台运行这些智能体。
  • 微调模型平台:您提供为每个客户定制 AI 模型的功能。 然后,您的平台会利用 GPU 按需运行这些模型。
  • 用户定义的函数:您的软件允许客户使用代码定义自定义逻辑。例如,您提供了一个分析引擎,并希望允许客户编写自定义函数;或者您提供了一个 API Gateway,并希望允许客户根据自己的自定义逻辑过滤或 mutate 请求。
  • 软件即服务 (SaaS) 可扩展性:您可能正在提供 SaaS,并希望允许客户使用扩展程序来扩展其功能。这些扩展程序可能由客户或合作伙伴编写。

Google Cloud 客户已成功在生产环境中使用 Cloud Run 来实现这些用例。

多租户平台面临的挑战

创建此类架构的典型挑战包括:

  • 安全性:无法扫描或清理提供的代码。不可信代码可能包含恶意操作或易受攻击的依赖项。如果隔离不当,不可信代码可能会访问属于其他租户的敏感数据。仅仅将代码打包到容器中并不是足够强大的安全边界。此外,还需要通过应用最小权限原则来限制代码可以执行的操作。
  • 成本效益:如果每个租户都会为您的平台带来固定成本,那么这种架构可能会变得昂贵。
  • 租户管理:管理数十万个租户可能具有挑战性,尤其是在数据删除方面。

Cloud Run 的优势

基于 Cloud Run 的架构为常见挑战提供了解决方案,具有许多优势,例如安全性、成本效益和租户管理。

安全

Cloud Run 提供与此架构相关的开箱即用安全功能:

  • 计算隔离:Cloud Run 可确保容器实例之间严格隔离,无论是同一服务的容器实例,还是来自不同项目的不同服务的容器实例。如需详细了解容器安全性和执行环境,请参阅安全设计概览。
  • 安全更新:可以启用基础映像的自动安全更新,以便使已部署工作负载的操作系统和运行时保持最新状态并打好补丁,而无需进行大规模重新部署。
  • 网络隔离:Cloud Run 不仅会对容器进行沙盒化处理,还会提供多租户网络栈。
  • 服务身份:Cloud Run 工作负载可以配置为具有专用身份,这些身份具有受限权限。

成本效益

  • 缩减至零和按用量付费:Cloud Run 实例在不使用时会自动缩减至零,从而确保托管的工作负载仅在需要运行时才收费。与利用“始终开启”虚拟机的架构相比,这种架构可实现非常高效的资源利用。
  • 按请求结算:除了缩减至零之外,您还可以受益于更精细的结算模式,该模式仅在处理请求时收费,从而提供更高的成本效益。
  • 按需和快速启动:缩容后,Cloud Run 服务可以快速扩容,从而使已部署应用的最终用户几乎感觉不到延迟。
  • 自动费用标签:Cloud Run 报告的所有费用都会添加标签,以便您自动执行租户的费用归因和跟踪。
  • 承诺降低总费用:在结算账号级别,您可以使用灵活承诺使用折扣来优化任何基准 Cloud Run 用量的支出。

租户管理

由于 Cloud Run 具有按需特性,因此使用多个 Google Cloud 项目时,Cloud Run 费用不会更高,从而可以实现整理 Google Cloud 项目中所述的租户管理。

多租户平台的目标架构

概括来讲,建议的架构如下:

。

组织您的 Google Cloud 项目

您需要设置 Google Cloud 组织、离线结算,并与您的客户支持团队联系,告知他们您正在以转销商账号身份行事。Google Cloud 可能会与您合作,确保建立适当的沟通渠道,以缓解滥用行为。

您必须使用文件夹来整理 Google Cloud 项目,尤其重要的是,您必须将运行第一方代码的项目与运行租户不受信任代码的项目放在不同的文件夹中。您需要自动执行租户初始配置,以便在创建租户的项目和资源时无需人机协同。

Google 建议每个租户使用一个 Google Cloud 项目。您也可以在同一项目中托管多个租户,但这会带来额外的限制:

每个 Google Cloud 项目一个租户(推荐)

在此架构中,平台的每个租户都托管在专用Google Cloud 项目中,这具有许多优势:

  • 更简单的安全性: Google Cloud 项目是其包含的所有资源的严格边界。这意味着,如果租户需要访问多个Google Cloud 资源(例如多个 Cloud Run 服务、一个 Cloud Storage 存储桶),您可以使用项目作为安全边界。
  • 限制较少:
    • 给定项目中的资源数量有限。例如,Cloud Run 仅允许在项目的每个区域中创建 1,000 个服务。服务账号和其他相关资源数量也存在类似的限制。
    • 项目数量本身就是一项配额,可以增加, Google Cloud 组织的项目数量没有限制。每个结算账号的项目数量软上限为 100,000 个,您可以通过与 Google 沟通来提高此上限。您的组织还可以创建多个结算账号,并将其分组到“账号群组”(目前处于非公开预览版阶段)中。
  • 更简单的监控和管理:
    • 为每个租户使用一个项目可以简化数据删除流程,其中删除租户的数据可以归结为删除相应的项目。
    • Google Cloud Monitoring 和 Logging 可跨项目运行,让您能够监控整个舰队。
    • 借助项目级配额,您可以为给定租户设置 Cloud Run 资源利用率上限,从而使限制与您自己的价格层级保持一致。
    • 通过自定义组织政策,您可以对文件夹的所有项目应用特定限制,例如可用区域或最大 CPU/内存分配。

创建 Google Cloud 项目并初始化 API 和资源可能会产生延迟,Google 建议您使用预先创建的项目池,以便在需要时分配给租户。

每个 Google Cloud 项目有多个租户(不推荐)

您可以在同一 Google Cloud项目中托管多个租户,但 Google 不建议采用此架构。

许多 Google Cloud 服务都有每个项目的资源限制。例如,Cloud Run 具有不可调整的限制,即一个项目中每个区域最多可有 1,000 个 Cloud Run 服务。因此,每个项目托管多个租户仍需要您管理 Google Cloud 项目舰队,这会增加租户管理的整体复杂性。从安全角度来看,Google Cloud 项目被设计为安全边界,在同一项目中托管两个不同的租户需要您在安全方面更加谨慎。例如,通过确保专用服务账号和精细权限来使用。

部署到多个区域

为了提高可靠性和可伸缩性,Google 建议将租户部署分散到多个 Google Cloud 区域。每个租户应用都部署到单个区域,但您可以为不同的租户使用不同的区域。区域选择可以是随机的,也可以考虑租户的位置以优化延迟时间。

请求路由和自定义网域

如果您想向最终用户公开租户的 Cloud Run 服务,则需要添加自己的网域并使用自己的路由逻辑。例如,将子网域映射到托管租户服务的 Google Cloud 项目。

您可以实现自定义路由服务,但 Google 建议您将全球外部应用负载均衡器与 Service Extensions 搭配使用来实现路由逻辑。Service Extensions 可以作为插件(逻辑与请求处理内嵌执行)或标注(路由逻辑委托给单独的 Cloud Run 服务,该服务可以调用Google Cloud的可伸缩多区域数据库之一,例如 Spanner)实现。

使用应用负载均衡器还可让您利用 Cloud CDN 添加缓存层,并使用 Cloud Armor 为平台提供额外的分布式拒绝服务 (DDoS 攻击) 攻击防护。

声誉和滥用行为

任何允许运行不受信任代码的托管平台都会遭到滥用。

我们建议您为提供的每个信誉层级使用不同的 Cloud Billing 账号。例如,免费层级租户不应与高付费客户关联到同一结算账号。Google 可能会认为这些结算账号具有不同的信誉级别。

如整理 Google Cloud 项目中所述,除了按结算账号进行分隔之外,您还应使用文件夹来整理项目。Google 可以帮助您设置文件夹级配额,以确保文件夹中的所有资源消耗的资源绝不会超过设定的上限,从而使您能够更好地管理平台的费用。

默认情况下,Google 会根据Google Cloud 服务条款自动移除滥用工作负载,Google 还可以在 Cloud Logging 中记录滥用检测事件,然后您可以采取措施。