概览

SaaS 公司运营适用于大量租户的解决方案。AWS 边缘服务(例如,CloudFront、AWS WAF 等...)的多租户部署要求谨慎的设计决策,以满足灵活性、成本、可扩展性和运营开销等业务需求。

架构决策

在使用 CloudFront 设计多租户解决方案时,请考虑以下架构决策:

  • 您对所有租户使用相同的主机名(例如,saas.com/tenant1、saas.com/tenant2)还是单独的主机名? 如果您使用相同的主机名,则可以选择使用单个 CloudFront 发行版进行部署。
  • 如果您使用不同的主机名,则使用的是相同的域名(例如,tenant1.saas.com、tenant2.saas.com)还是单独的域名(例如,tenant1.com、tenant2.com)? CloudFront 发行版可以与单个 TLS 证书相关联,该证书可以托管多个主机名(SAN 证书)。使用相同的域名时,您可以选择按租户部署 CloudFront 发行版,也可以为所有租户部署带有通配符 CNAME 和 TLS 证书(*.saas.com)的单一发行版。如果域不同,则可以选择按租户部署 CloudFront 发行版,也可以选择部署多个发行版,每个发行版都有 SAN 证书,可以托管多达 100 个不同的域。但是,您附加到同一 TLS 证书的域越多,给 TLS 证书颁发过程带来的阻碍就越大。
  • 由谁控制域名? 如果租户控制其域,则需要采取其他步骤将其主机名作为 CNAME 添加到 CloudFront 发行版中。出于安全原因,CloudFront 要求您通过附上涵盖主机名的有效 TLS 证书来证明您对域的所有权。租户要么需要共享自己的 TLS 证书(您要将其上传到 ACM),要么允许您使用 ACM 代表他们颁发 TLS 证书。使用第二种方法,ACM 要求他们在自己的 DNS 中创建 CNAME 令牌以证明他们对该域的所有权。
  • 租户共享相同的内容还是不同的内容? 如果他们共享通用内容,可以考虑将共享内容托管在可供不同租户使用的单个域上。这样可以提高共享内容的缓存命中率。
  • 如果您为多个租户使用 CloudFront 发行版,您是在同一个源上托管租户还是在不同的源上托管租户? 如果您使用相同的源(例如,单个 S3 存储桶或单个 ALB),则可以通过 URL 路径或主机标头区分租户。如果您选择这种区分租户的方法,请将主机标头添加到缓存密钥中。如果您使用不同的源(例如,每个租户一个 S3 存储桶,或者在 ALB 集群上对租户进行分片),则需要对源请求事件使用 Lambda@Edge 以将流量路由到正确的源。请注意,如果您使用路径来区分租户(例如,saas.com/tenant1、saas.com/tenant2),则可以使用 CloudFront 缓存行为将不同的租户本地路由到其源,但对每个 CloudFront 发行版的行为数量有配额。
  • 您的设计是否尊守每个 AWS 服务和每个 AWS 账户的 AWS 配额?

在设计中考虑以下折衷方案。请注意,您可以为多层产品实现差异化折衷。例如,在您控制域名的基本层级中,所有租户共享相同的 CloudFront 发行版。您的高级租户将通过 AWS WAF 各获得一个带有自定义域和安全保护的专用 CloudFront 发行版。

  每个租户托管在专用的 CloudFront 发行版上 多个租户托管在同一个 CloudFront 发行版上
可观测性 每个租户原生可用 在发行版层可用,需要额外的工作才能使用日志提取每个租户的指标
爆炸半径 更改仅影响一个租户 单个更改会影响所有租户
运营开销 需要大规模自动化,通过批量部署来避免 CloudFront API 级别的限制
自定义 每个租户可以有自己不同的配置 所有租户的配置相同。启用 WAF 时,将对所有请求收费
性能 每个 CloudFront 发行版都需要单独按流量预热(例如,与源的连接) 所有租户都将从预热的 CloudFront 发行版受益

CloudFront 发行版可以连接到单个 AWS WAF WebACL。同一个 WebACL 可以在多个 CloudFront 发行版中使用。除了以下几点之外,前面提到的折衷也适用于 WAF 部署:

  使用每个租户的 WebACL 为多个租户使用相同的 WebACL
价格 WebACL/规则成本随租户数量呈线性增长 WebACL/规则成本与租户数量无关
误报 规则更新可能仅导致单个租户出现误报 规则更新可能导致多个单一租户出现误报

常见使用案例

每个租户的子域

在这种情况下,您需要为每个租户创建一个子域名(tenant1.saas.com)。Route 53 配置为对 CloudFront 发行版使用通配符别名记录(*.saas.com),还配置了通配符 CNAME(*.saas.com),缓存密钥中包含主机标头。提供动态请求的 ALB 源使用主机标头本地区分租户。请注意,在这种情况下,单个内容失效将适用于所有租户,因为 CloudFront 的失效与缓存密钥的标头部分无关,例如主机标头。提供静态内容的 S3 存储桶需要对查看器请求事件配置一个 CloudFront 函数来读取主机标头,并将 URL 重写到 S3 中的租户目录(例如,tenant1.saas.com/index.html -> s3://bucket:arn/tenant1/index.html)。如果您要向 S3 中的所有租户提供相同的内容,例如相同的单页应用程序,但使用 API 区分租户,请考虑使用此简单解决方案

如果您在不同的源上托管租户,则需要对源请求事件配置一个 Lambda@Edge 函数,以将租户请求路由到托管租户的源。要了解有关此实施的更多信息,请阅读以下案例研究:

拥有自己域名的租户

在这种情况下,对每个租户专用 CloudFront 发行版,并自动执行该流程(例如,使用 Amazon Certificate Manager 创建发行版和 TLS 证书颁发)。确保事先提高相关配额(例如,每个账户的发行版数量、TLS 证书的数量)。在某些情况下,您需要在多个 AWS 账户之间对 CloudFront 发行版进行分片。

终止服务器上的 TLS

如果 CloudFront 无法满足您的需求,可以考虑建立反向代理队列(例如,基于 NLB 和 EC2)来终止 TCP/TLS 连接,并事先使用 Global Accelerator 以提高安全性和性能。请注意,在这种情况下,您应根据需要在反向代理中实现缓存。

资源

此页内容对您是否有帮助?