WEFOX ITALY 在 Amazon EKS 上实现 SaaS 多租户之旅

作者: inboxhg |

本博客由 WEFOX ITALY 首席架构师 Marco Sciatta、亚马逊云科技高级解决方案架构师 Majid Shokrolahi、亚马逊云科技容器首席解决方案架构师 Tsahi Duek 撰写。

Wefox Italy 是一家领先的保险公司,致力于为保险业提供创新解决方案。

在意大利的 Wefox,各个团队都在开发不同的产品,其中许多产品最近需要支持具有强大数据和资源隔离的多租户模式,以满足新客户的需求。同时,需要维护的请求和实例数量的增加给运营团队带来了相当大的压力。我们需要一种解决方案,使我们的团队能够在标准化环境中轻松、快速地发布和维护各种应用程序实例。

为了应对这些挑战,我们采用了云软件服务 (SaaS) 模式。我们开发了一个多功能平台,能够在标准化环境中一致部署任何应用程序,并利用该方法提供最高级别的自定义。

这篇文章详细介绍了我们如何使用 Amazon Elastic Kubernetes Service(Amazon EKS)和 GitOps 实践构建全面的 SaaS 解决方案。通过利用亚马逊云科技服务,我们创建了一个可配置且易于维护的环境。

我们设计了这篇文章中描述的解决方案,以支持组织中的不同角色及其需求。以下是每个角色及其要求的描述:

SaaS 平台团队管理应用程序和客户租户的入职。这需要租户管理系统,使应用程序团队能够为不同的客户租户单独创建应用程序模型。

DevOps 团队负责构建和管理全系统功能,例如 API GW 配置、服务网格部署、身份提供商 (IdP) 的 AuthZ(授权)和 AuthN(身份验证)以及类似服务。

应用程序团队负责构建面向客户的应用程序,并使用 SaaS 平台团队和 DevOps 团队提供的功能,以孤岛模式为每个客户租户部署这些应用程序。

解决方案概述

我们的解决方案主要基于 EKS SaaS 工厂参考架构,包括三个不同的集群:一个 SaaS 控制平面集群和两个数据平面集群。

SaaS 控制平面集群托管 SaaS 运行所需的所有基本服务,包括集中管理、租户管理服务和监控工具。它由 SaaS 平台团队管理,其服务可供需要为客户租户启动新应用程序的应用程序团队提供。

这两个 Data Plane 集群专用于部署工作负载,确保应用程序服务独立于核心操作服务运行。第一个是我们的应用程序共享服务集群,由 DevOps 团队管理(与 SaaS 控制平面不同,包括授权和 Kong API GW 服务)。在此集群中部署的服务被用作集群中任何应用程序使用的系统范围功能的基础。第二个是我们的业务应用程序集群,应用程序团队可以在其中部署业务服务。目前,我们只有一个业务集群,但是随着我们的应用程序和客户群的增长,我们计划增加更多的业务应用程序集群,同时保持共享服务集群作为所有部署的基础。原始业务集群将保持默认部署环境。

两个数据平面在同一 Istio 服务网格中运行,在它们之间提供高级安全层和全面的流量控制。使用 Istio,我们可以毫不费力地将高级功能整合为标准应用程序功能。

这种双集群方法可确保明确区分关注点,显著增强安全性并优化可扩展性。下图显示了架构。

图 1:高级架构

图 1:高级架构

该解决方案的一个核心方面是采用 GitOps 方法,这些方法可以简化和自动化我们的操作,从而提供一个完全可定制的环境。在基础设施管理方面,我们使用 Terraform 作为我们的基础设施即代码(IAC)工具,由我们的内部 GitLab CI/CD 管道精心编排。这种方法使我们能够以一致、可重复的方式定义和配置基础架构。除此之外,我们还使用 Argo CD 来管理 Kubernetes 清单,确保集群上自动维护应用程序的所需状态。通过集成 Terraform 和 Argo CD,我们实现了基础设施和应用程序管理的无缝端到端解决方案。这种强大的组合使我们能够自动化部署流程,并确保整个平台上的环境保持一致。

该解决方案的主要优点:

  • 控制自动化:采用 Terraform 即基础设施即代码(IaC)工具和 Argo CD 进行应用程序管理,使我们能够通过 CI/CD、Terraform 模块和掌舵图实现应用程序部署和生命周期的每个部分的自动化,但要保持其完全可配置和可定制。
  • 安全性:EKS Pod 身份根据最小权限原则确保 Pod 级访问控制亚马逊云科技服务。Istio 采用 mTLS(双向 TLS)和授权策略,以及通过开放策略代理 (OPA) 实现的策略即代码,提供了精细的权限管理,增强了整体安全态势。
  • 敏感值管理:密钥和参数安全地存储在 Amazon Secrets Manager 或 Parameter Store 中,这是 Amazon Systems Manager 的一项功能,并通过密钥存储 CSI 驱动程序自动注入到相应的容器中。这种方法可以防止敏感数据泄露,并确保安全的存储和处理。
  • 租户隔离Amazon VPC CNI 插件与网络策略和 Istio 授权策略相结合,通过网络级隔离和精细访问控制、提高监管标准合规性以及简化安全配置管理,增强安全性。
  • 集中式工具集:应用程序可以利用以共享服务形式提供的不同服务。这包括作为开放式遥测收集器的 Keycloak 用于收集监控数据等。此外,某些功能可以通过配置来激活,例如使用策略即代码。
  • 成本效率:使用 Amazon EKS 可以利用 Karpenter 进行动态扩展,从而实现经济高效的资源管理。此外,该解决方案降低了维护需求,使我们的运营团队能够专注于基础设施管理而不是单个应用程序,从而进一步提高了整体效率。

基准基础设施通过 Terraform 进行配置,并由我们的内部 GitLab CI/CD 管道进行编排。VPC、网络结构、三个 Amazon EKS 集群以及所有必需的亚马逊云科技支持服务(例如 IAM 角色)均通过 Terraform 代码部署,使用标准的亚马逊云科技模块和 EKS,允许预置一个已经安装了一些有用的 Kubernetes 对象的即用型 Amazon EKS 集群,例如密钥存储-csi 驱动程序和 aws-负载均衡器控制器。

主要的 Amazon EKS 集群(称为控制平面)托管 SaaS 解决方案运行所需的所有服务。这些是用于租户和应用程序管理的服务,以及用于管理特定组件(例如 Kong API 网关控制平面)的服务。其中之一是 Argo CD,用于在定义的所有集群上部署和管理工作负载。

第二个集群称为共享集群,托管的服务不绑定到特定应用程序,而是在所有应用程序中普遍使用。

最后一个集群是应用程序集群,除非另行指定,否则它将用作应用程序的默认部署环境。

作为基础架构的一部分,Istio 服务网格安装在共享集群和应用程序集群之间的主配置中。在配置 Amazon EKS 集群期间,Argo CD 会自动配置为能够在两个数据平面集群上部署工作负载。

应用程序部署和堆栈

我们 SaaS 解决方案的支柱之一是维护 GitOps 运营模式。

为了实现这一目标,应用程序概念围绕四个不同的存储库构建,每个存储库都旨在管理应用程序生命周期的不同方面:基础架构、部署、API 和域以及策略即代码。图 2 显示了堆栈和存储库。

图 2:堆栈和存储库

图 2:堆栈和存储库

同时,为了支持相同应用程序的不同部署模式或层级,我们引入了堆栈的概念(筒仓共享等)

这种方法为表示 SaaS 环境中的任何类型的部署模型提供了必要的精细度,但是,我们决定支持开箱即用的孤岛模型,在共享集群上实现每租户命名空间隔离,提供 4 种不同的存储库模板,用作每个应用程序的基础:

  • 堆栈:标准的 Terraform 存储库和 CI/CD 管道。该存储库包含用于部署默认 "筒仓" 堆栈的 terraform 代码。terraform 代码由不同的模块组成,用于根据同一存储库中名为 app_config 的 yaml 文件中指定的应用程序配置来配置基础架构组件
  • 清单:包含将通过 argocd 应用程序部署的 Kubernetes 清单。默认情况下,它包含用于安装租户命名空间基线(命名空间定义、网络策略等)的清单以及自以为是的结构化目录树。
  • API:包含能够在 API 网关上进行配置的 CI/CD 管道、一些开放的 API 定义以及通过声明格式进行配置。遵循 Apiops 的概念。
  • 策略:包括可重复使用的 Rego 策略模板,这些模板在应用程序配置中启用后可与 Opa 一起使用。

我们将这些存储库分开,以保持运营和应用程序团队之间的明确所有权。

应用程序入门

我们为内部团队提供用户界面,以简化应用程序创建流程。用户界面允许指定不同的应用程序详细信息,例如名称、域名和亚马逊云科技资源,这些资源需要预置并可供构成应用程序的所有服务使用。

将提供给构成该应用程序的所有服务,并可供其使用。图 3:内部团队的用户界面 — 第 1 部分


图 3:内部团队的用户界面 — 第 1 部分

创建应用程序时,应用程序管理器服务(我们在控制平面集群中称之为 saasd 的内部开发工具)会克隆四个存储库模板,使用指定的配置对其进行初始化,然后将它们上传到相应的应用程序 GitLab 组。

创建应用程序和存储库后,可以将服务添加到应用程序中。

图 4:内部团队的用户界面 — 第 2 部分

图 4:内部团队的用户界面 — 第 2 部分

服务配置包括基础设施和部署设置,例如必需的亚马逊云科技服务,如 Amazon RDS 数据库、映像标签、要公开的 Kubernetes 服务端口和环境变量。

配置服务后,saasd 会在基础架构和部署之间划分信息,并在两个应用程序存储库上进行相应的更改。

在基础架构存储库上,app_config 文件将使用新服务的相关信息进行更改。

在清单存储库中,添加了一个新的目录树,其中包含头盔图表和值文件定义。

图 5:应用程序入门

图 5:应用程序入门

租户入职

在 SaaS 解决方案中创建应用程序不会将任何内容部署到集群中,因为只有在租户加入时才会配置基础架构。租户入职涉及基于所选堆栈和应用程序存储库创建应用程序基础架构和服务部署。通过用户界面中的一键操作,租户可以加入任何已配置的 SaaS 应用程序。创建新租户时,入职管道会自动触发。该管道使用部署在控制平面集群上的四个微服务来准备 SaaS 环境。

图 6:租户入职

图 6:租户入职

流程描述如下:

  • 租户注册服务调用租户经理来存储租户数据信息
  • 租户注册服务调用用户管理器服务,在 IdP 上创建专用域、注册第一个用户并为新租户注册一个 OAuth 应用程序
  • 租户注册服务使用先前服务收集的数据致电提供者
  • 供应商调用 saad 服务,检索应用程序详细信息,并通过 API 触发相应的 app_stack 存储库 CI/CD,将租户和堆栈等一些参数传递给部署

应用程序堆栈存储库 CI/CD 管道被触发时,给定的参数用于动态配置 Terraform 状态后端并启动相应的堆栈地形代码。

图 7:集群上的租户入职和应用程序部署

图 7:集群上的租户入职和应用程序部署

这允许为不同的租户部署相同的应用程序堆栈,每个租户都有独立的 Terraform 状态文件。Terraform 代码按指定配置资源,最终模块桥接基础架构和部署。它收集非敏感信息并在控制平面集群中注册 Helm 图表。此图表包含一个指向应用程序清单存储库的 Argo CD 应用程序,该应用程序配置为同步基准图表。基准图表按照应用程序模式安装清单以创建租户命名空间、为每项服务配置隔离策略、资源配额和 Argo CD 应用程序。

应用程序发布

在 SaaS 环境中,在所有租户部署中保持一致的基础架构和代码库至关重要。该解决方案使用 GitOps 来管理部署和基础设施更新。当团队通过将容器镜像推送到 Amazon Elastic Container Registry(Amazon ECR)来发布新的服务版本时,他们会通过其服务 CI/CD 管道自动或手动更新存储库中的 Kubernetes 清单。由于每个租户采用默认 Silo 堆栈模型的 Argo CD 应用程序都有自己的 Argo CD 应用程序指向同一个应用程序清单存储库,因此 Argo CD 会自动协调集群中每个应用程序租户的清单。对于基础设施变更,DevOps 团队修改堆栈存储库中的 Terraform 代码,然后合并到触发 CI/CD 管道的存储库中。CI/CD 管道由动态步骤组成,由脚本动态构建。该脚本向租户管理器查询以检索使用该应用程序堆栈部署的租户列表。对于每个租户,它会动态创建一个 GitLab CI 管道步骤,其中包括使用适用于每个租户的状态文件后端应用 Terraform 配置的说明。

图 8:应用程序发布工作流程

图 8:应用程序发布工作流程

与首次入门一样,Terraform 代码最后会安装新版本的基本 Helm 图表,其中包含新基础架构的值,因此 Argo CD 可以协调该租户的应用程序状态。通过这种方式,我们可以确保以适当的方式按顺序更新集群上的部署基础架构。

这种方法始终适用于为简化应用程序维护而开发的所有工具。例如,用于向应用程序添加新服务的用户界面会解析配置,并模仿手动流程,自动对清单或基础架构存储库进行新的提交。此过程对于共享服务入门来说是相同的。

结论

构建 SaaS 解决方案会带来租户隔离、无缝入职和邻居噪音问题等挑战。我们的架构将典型的 SaaS 结构转变为支持各种应用程序和基础设施部署的多功能平台。我们使用孤岛资源模型,确保完全自动化的共享群集环境中的安全和隔离。GitOps 方法支持自定义应用程序生命周期,允许在不影响其他基础设施组件的情况下跨不同的亚马逊云科技账户、集群或 VPC 进行部署。我们鼓励您实施这种多功能架构以简化多租户部署,并采用 GitOps 来增强控制。要了解更多信息,请参阅 Amazon EKS SaaS 工厂参考架构和 Amazon EKS SaaS 指南。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。