OCI 上的多租户应用程序部署模型
关于 Tenancies
务必不要将 OCI 租户与 SaaS 应用中的租户概念混淆。
OCI 租户:这是您在注册 OCI 服务时收到的账户。它表示您的根账户,并用作安全、隔离的分区,您可以在其中组织和管理 OCI 资源。
租户(在 SaaS 上下文中):假设 ISV 在 OCI 上构建 SaaS 平台。当 ISV 在平台中预配自己的客户时,每个客户都被视为一个租户。从这个意义上讲,一个租户代表一个客户组织,每个租户可以有多个用户与其关联。
简而言之,OCI 租户是指 OCI 账户本身,而租户是指使用由其他实体(例如 ISV)托管在 OCI 上的应用程序的组织(例如 SaaS 客户)。
体系结构
此架构在高层次上代表 OCI 上的多租户应用部署模型。
下图说明了此参考体系结构:
这种灵活的体系结构分为三个层:
| 层 | 用途 | 关键操作 |
|---|---|---|
| 初始验证 (OCI IAM) | 验证全局身份 | 身份证明验证后发出 JSON Web 标记 (JWT) |
| 验证中间件 | 验证每个请求的身份 | 从 JWT 提取租户和用户上下文 |
| 数据访问层或 ORM 挂钩 | 实施数据隔离 | 自动按 tenant_id 筛选所有查询 |
每一层描述如下:
初始验证和租户上下文建立
- 验证服务:用户通常通过使用特定于租户的 URL(例如 mycompany.app.com)或在登录期间选择租户来登录。
- 作为身份提供者的 OCI 身份和访问管理 (OCI IAM): OCI IAM(特别是专用身份域)将验证用户的身份证明。至关重要的是,它确认用户不仅有效,而且也是他们尝试访问的特定租户组(例如 mycompany-users)的成员。
- JWT 发布:成功验证后,OCI IAM 身份域会发出已签名的 JSON Web 标记 (JWT)。此令牌包括以下关键声明:
- sub :用户的唯一标识符。
- groups :用户所属的 IAM 组的 OCID 数组。这是标识租户的关键。
- 可以使用 OCI IAM 中的定制属性添加自定义声明(例如
tenant_id或tenant_name)。(可选)
验证中间件 - "Who" 层
必须设计后端以安全地提取和传播租户上下文。此架构支持使用 OCI API Gateway 或 OCI Load Balancer 执行按请求身份验证和租户上下文传播。
- OCI API 网关:这是建议的入口点。它可以执行 JWT 验证本身,从而从应用程序代码中卸载此责任。您可以对其进行配置,以根据 OCI IAM 身份域的 JWKS 端点验证签名。
- OCI 负载平衡器:可以处理 SSL 终止和路由,但可以将 JWT 传递到验证中间件进行验证。
操作:OCI API Gateway 验证 JWT 的签名和到期。如果无效,它将立即拒绝请求。如果有效,则它将请求转发到上游服务,通常在标头中传递验证的标记或提取的声明(例如 X-USER-ID、X-TENANT-ID)。
如果您使用的是 OCI 负载平衡器而不是 OCI API 网关,则应用后端的第一个组件必须是身份验证中间件。
操作:从 Authorization: Bearer <token> 标头中提取 JWT,使用 OCI IAM 的公钥验证其签名,解码声明,并将 user_id 和 tenant_id(从声明的组派生)注入请求上下文中,以便所有后续层都使用。
Data Access Layer or Object-Relational Mapper (ORM) Hook - “什么”层
此层会自动将租户 ID 注入到每个 SQL 查询中。
- 示例:对
getAllInvoices()的调用将转换为SELECT * FROM invoices WHERE tenant_id = :tenant_id。 - 实施:最好通过集中数据访问层或 ORM(例如 Hibernate)挂钩或“租户感知”连接池来实施,以避免人为错误。
- ORM 钩子:通过在应用程序框架级别拦截和修改数据库操作来启用真正的隐式租户隔离的机制。
租户数据隔离策略:
此架构支持两个用于隔离和保护租户数据的选项:
选项 1:应用产品层
ORM Hooks/Scopes(ORM 钩子/范围):使用 Hibernate (Java)、Django ORM (Python) 或 Eloquent (PHP) 等框架,可以定义全局范围,自动将租户筛选器添加到特定模型的所有查询中。
或者
选项 2:数据库级别
您可以使用辨别列、每个租户的单独方案或每个租户的单独数据库:
- 鉴别器列(最常见):
将向每个特定于租户的表或文档添加
tenant_id列。应用程序的数据访问层 (Data Access Layer,DAL) 或 ORM 负责自动将
WHERE tenant_id = ?子句附加到每个查询。这可通过以下方式实现:- 资料档案库模式:所有数据库访问都流经一个中心类或一组类。此资料档案库将根据当前请求上下文中的
tenant_id自动将租户筛选器添加到每个 SELECT、INSERT、UPDATE 和 DELETE 操作中。 - 连接上下文:对于某些 SQL 数据库(例如 Oracle HeatWave MySQL ),应用程序可以设置会话变量(例如
SET @tenant_id = 'mycompany123';),然后在视图或存储过程中使用它。但是,应用程序层仍负责为每个连接设置此值。
- 资料档案库模式:所有数据库访问都流经一个中心类或一组类。此资料档案库将根据当前请求上下文中的
- 每个租户的方案:
每个租户在同一数据库实例中都有一个专用数据库方案。
应用程序逻辑(基于租户 ID)必须切换数据库连接的当前方案。
- 每个租户的连接池:为每个租户维护一个单独的连接池,其中每个连接都预先配置为使用租户的模式(例如
USE tenant_mycompany;)。 - 动态连接切换:使用连接池,该连接池根据当前 tenant_id 设置结账时的模式(例如,对 PostgreSQL 使用
SET search_path TO tenant_mycompany;命令)。
- 每个租户的连接池:为每个租户维护一个单独的连接池,其中每个连接都预先配置为使用租户的模式(例如
- 每个租户的数据库:
每个租户都有自己的物理隔离数据库实例,并自带企业密钥加密。
应用程序需要租户数据查找服务才能将
tenant_id映射到正确的数据库连接字符串。- 应用程序将保存到多个数据库的连接池。
- DAL 使用请求上下文中的租户 ID 从池中获取正确的连接,并对专用租户数据库执行查询。
此选项具有优点和缺点:
- 优点:最高隔离性、安全性和性能。租户甚至可以位于不同的数据库版本或引擎类型上。
- 成本:运营开销、成本和复杂性最高。必须在每个租户数据库上运行数据库迁移和补丁程序。
此体系结构实现以下组件:
- Tenancy
租户是 Oracle 在您注册 OCI 时在 Oracle Cloud 中设置的安全隔离分区。您可以在租户的 OCI 上创建、组织和管理资源。租户是公司或组织的同义词。通常,公司将具有单个租户,并反映其在该租户中的组织结构。单个租户通常与单个订阅关联,而单个订阅通常只有一个租户。
- OCI 身份和访问管理
Oracle Cloud Infrastructure Identity and Access Management (IAM) 为 OCI 和 Oracle Cloud Applications 提供用户访问控制。借助 IAM API 和用户界面,您可以管理身份域及其中的资源。每个 OCI IAM 身份域都代表一个独立的身份和访问管理解决方案或不同的用户群体。
- 负载平衡器
Oracle Cloud Infrastructure Load Balancer 提供从单个入口点到多个服务器的自动流量分配。
- OCI API 网关
借助 Oracle Cloud Infrastructure API Gateway ,您可以发布具有专用端点的 API,这些端点可从您的网络访问,并且您可以根据需要向公共互联网公开。这些端点支持 API 验证、请求和响应转换、CORS、验证和授权以及请求限制。
- Oracle Key Management Cloud Service
OCI 密钥管理服务 Oracle Cloud Infrastructure (OCI) 密钥管理服务 (KMS) 是一项基于云的服务,可为存储在 OCI 中的数据集中管理和控制加密密钥。OCI KMS 是由客户管理的加密,提供 OCI Vault(Virtual Vault 和 Private Vault)、OCI Dedicated KMS 和 OCI External KMS 服务。
- OCI Compute
借助 Oracle Cloud Infrastructure Compute ,您可以在云中预配和管理计算主机。您可以启动具有配置的计算实例,以满足您在 CPU、内存、网络带宽和存储方面的资源需求。创建计算实例后,您可以安全地访问它,重新启动它,附加和分离卷,并在不再需要时终止它。
- OCI 功能
Oracle Cloud Infrastructure Functions 是一个完全托管、多租户、高度可扩展、按需提供的函数即服务 (FaaS) 平台。它由 Fn Project 开源引擎提供支持。使用 OCI Functions ,您可以部署代码,直接调用代码或触发代码以响应事件。OCI Functions 使用 Oracle Cloud Infrastructure Registry 中托管的 Docker 容器。
- OCI Kubernetes 引擎
Oracle Cloud Infrastructure Kubernetes Engine ( OCI Kubernetes Engine 或 OKE )是一项完全托管、可扩展且高度可用的服务,可用于将容器化应用部署到云端。您可以指定应用所需的计算资源, OKE 可在现有租户的 OCI 上预配这些资源。OKE 使用 Kubernetes 跨主机集群自动部署、扩展和管理容器化应用。
- Oracle HeatWave MySQL
Oracle MySQL Database Service 是一个完全托管的数据库服务,可帮助开发人员使用全球广受欢迎的开源数据库快速开发和部署安全的云原生应用。Oracle HeatWave MySQL 是一款面向 Oracle MySQL Database Service 的集成式高性能内存中查询加速器,可提高分析和事务处理查询的 MySQL 性能。
- Oracle NoSQL Database Cloud Service
借助 Oracle NoSQL Database Cloud Service ,开发人员可以轻松使用文档、固定模式和键值数据库模型构建应用,通过数据复制实现高可用性,从而实现可预测的单位数毫秒响应时间。该服务可为按需和预配容量模式提供主动 - 主动区域复制、ACID 事务、无服务器扩展、全面的安全性和低按使用付费定价,包括与本地 Oracle NoSQL Database 100% 兼容。
- OCI 对象存储
OCI Object Storage 可访问任意内容类型的大量结构化和非结构化数据,包括数据库备份、分析数据以及图像和视频等丰富内容。您可以安全地直接从应用或云平台内存储数据。您可以扩展存储,而不会出现性能或服务可靠性下降的情况。
将标准存储用于您需要快速、立即和频繁访问的“热”存储。将归档存储用于长期保留且很少或很少访问的“冷”存储。
- 无服务器 Oracle Autonomous Database
Oracle Autonomous Database Serverless 是一个 Oracle Autonomous Database 。您拥有一个完全弹性的数据库,Oracle 可自主运行数据库生命周期的各个方面,包括数据库放置、备份和更新。
- 透明数据加密
透明数据加密 (Transparent Data Encryption,TDE) 可透明地加密 Oracle AI Database 中的静态数据。TDE 与 Oracle AI Database 完全集成,可以加密整个数据库备份 (RMAN)、数据泵导出、整个应用程序表空间或特定敏感列。无论是在表空间存储文件、临时表空间、还原表空间还是其他文件(例如重做日志)中,加密的数据都会在数据库中保持加密。这可以防止未经授权的访问数据库数据的尝试,而不会影响应用程序使用 SQL 访问数据的方式。
推荐
- VCN
创建 VCN 时,根据您计划附加到 VCN 中的子网的资源数,确定所需的 CIDR 块数和每个块的大小。使用标准专用 IP 地址空间内的 CIDR 块。
选择与要设置专用连接的任何其他网络(在 Oracle Cloud Infrastructure 、内部部署数据中心或其他云提供商中)不重叠的 CIDR 块。
创建 VCN 后,您可以更改、添加和删除其 CIDR 块。
设计子网时,请考虑流量和安全要求。将特定层或角色中的所有资源附加到同一子网,该子网可以用作安全边界。
- 安全列表
使用安全列表定义适用于整个子网的入站和出站规则。
- 网络安全组 (NSG)
您可以使用 NSG 定义一组适用于特定 VNIC 的入站和出站规则。我们建议使用 NSG 而非安全列表,因为 NSG 使您能够将 VCN 的子网体系结构与应用的安全要求分开。
- Cloud Guard
克隆和定制 Oracle 提供的默认配方,以创建定制检测器和响应器配方。通过这些配方,您可以指定生成警告的安全违规类型以及允许对它们执行哪些操作。例如,您可能希望检测可见性设置为公共的 OCI Object Storage 存储桶。
在租户级别应用 Oracle Cloud Guard ,以涵盖最广泛的范围,并减轻维护多个配置的管理负担。
还可以使用“托管列表”功能将某些配置应用于检测器。
- 安全区域
对于需要最大安全性的资源,Oracle 建议您使用安全区域。安全区域是与 Oracle 定义的基于优秀实践的安全策略配方关联的区间。例如,不能从公共 Internet 访问安全区域中的资源,并且必须使用客户管理的密钥对其进行加密。在安全区域中创建和更新资源时,OCI 将根据配方中的策略验证操作,并防止违反任何策略的操作。
注意事项
部署此体系结构时,请考虑这些选项。
- 性能:
- 在 API 上设置基于租户的速率限制
- 使用 OKE 中每个名称空间的 Kubernetes 资源配额来限制每个租户的云池、CPU 和内存
- 为高需求租户利用专用节点池
- 在数据库连接上设置每租户池大小
- 安全:
- OCI IAM 组控制用户可以访问的租户。这由 JWT 强制执行。
- 支持 Oracle Cloud Guard 检测配置错误
- 成本:
根据您的业务需求进行评估,无论您是需要表级、方案级还是企业级客户的专用数据库。例如:
- Tier 1:Standard (Discriminator Column):租户共享相同的表/方案。
- 第 2 层:高级(每个租户的模式):租户在同一数据库中获得专用方案。
- 第 3 层:企业(每个租户的数据库):租户获得专用数据库实例。
- 打补丁和应用程序更新
在单实例多租户 SaaS 体系结构中,如果不为所有租户打补丁,则无法为一个租户打补丁。您的所有客户共享相同的应用代码库、运行时和基础设施。这一现实带来了重大挑战:如何安全、高效地推出更新,同时不会给整个用户群造成中断停机?答案在于专门为此目的设计的现代 DevOps 部署策略:使用零停机部署策略,在不同版本之间实现无缝转换,而无需强制用户脱机。
- Blue – Green Deployment:这涉及维护两个相同的生产环境:一个 "Blue"(运行当前版本)和一个 "Green"(运行新版本)。在 Green 中部署和测试新版本后,您可以将所有流量从 Blue 无缝切换到 Green。如果出现任何错误,您可以立即切换回,使回滚成为非事件。旧的蓝色环境已经退役。
- Canary Deployment(金丝雀部署):此策略通过执行逐步部署来降低风险。新版本将部署到受控的小用户子集(“金丝雀”)。您可以密切监视此组以查找错误或性能问题。如果度量看起来不错,您会逐渐向更多用户推出更新,直到每个人都在新版本上。
您将强制升级窗口通知用户(例如,“如果未指定升级日期,升级将在星期日 12:00,mm/dd/yyyy”)自动进行。在该窗口之后,您将终止旧版本的会话并将所有流量重定向到新版本。然后,旧的应用程序代码将完全关闭。
- Database 注意事项
您无法在切换应用程序版本的确切时刻切换数据库方案。大多数 SaaS 公司都使用以下方法来避免这种情况:
- 向后兼容的数据库方案更改
- 功能标志/切换
- 基于租户元数据的版本控制
这允许新代码在部署期间针对旧模式版本安全运行,从而实现零停机迁移和即时回退。
了解更多
了解有关多租户应用程序部署的更多信息。
查看以下其他资源:
- 设置基础结构以托管多个单租户 SaaS 应用程序
- Oracle Private Cloud Appliance 编写策略以访问跨租户的资源
- 跨租户访问:OCI 中的 AssumeRole (博客)
- Oracle Multitenant
- Oracle Cloud Infrastructure 文档
- Oracle Cloud Infrastructure 的体系结构完善的框架
- 云采用框架
