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

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

使用场景

此类架构的用例包括:

  • 应用托管平台:您提供一个平台,供客户部署其代码。例如,Web 托管平台(客户提供 Web 服务器)或函数即服务平台(客户提供函数)。
  • 代理托管平台:您的客户使用 SDK 构建 AI 代理,您的平台在后台运行这些代理。
  • 微调模型平台:您可以根据客户需求自定义 AI 模型。然后,平台会根据需求利用 GPU 运行这些工作负载。
  • 用户定义的函数:您的软件允许客户使用代码定义自定义逻辑。例如,您提供了一个分析引擎,并希望允许客户编写自定义函数;或者您提供了一个 API 网关,并希望允许客户根据自己的自定义逻辑过滤或更改请求。
  • 软件即服务 (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 项目时,费用不会更高,从而可以按照整理 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 组织,此数量没有限制。每个结算账号的项目数量软上限为 10 万个,您可以与 Google 联系,提高此上限。您的组织还可以创建多个结算账号,并将它们归入“账号群组”(目前处于私密预览阶段)。
  • 更简单的监控和管理
    • 为每个租户使用一个项目,可简化数据删除流程,因为删除租户的数据归根结底就是删除相应的项目。
    • Google Cloud 监控和日志记录功能可跨项目使用,让您能够监控整个舰队。
    • 借助项目级配额,您可以限制特定租户的 Cloud Run 资源利用率,从而可能使限制与您自己的定价层级保持一致。
    • 借助自定义组织政策,您可以对文件夹的所有项目应用特定限制,例如可用区域或 CPU/内存分配上限。

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

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

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

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

请求路由和自定义网域

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

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

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

声誉和滥用行为

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

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

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

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