使用 Flux 简化 Amazon EKS 多租户应用程序部署 - AWS Prescriptive Guidance

使用 Flux 简化 Amazon EKS 多租户应用程序部署

Nadeem Rahaman、Aditya Ambati、Aniket Dekate 和 Shrikant Patil,Amazon Web Services

摘要

注意:AWS CodeCommit 现已不再向新客户提供。AWS CodeCommit 的现有客户可以继续正常使用该服务。了解更多

许多提供产品和服务的公司隶属于受数据监管的行业,这类行业要求在其内部业务职能之间建立数据壁垒。此模式描述了如何使用 Amazon Elastic Kubernetes Service(Amazon EKS)中的多租户功能来构建数据平台,在共享单个 Amazon EKS 集群的租户或用户之间实现逻辑隔离与物理隔离。此模式通过以下方法实现隔离:

  • Kubernetes 命名空间隔离

  • 基于角色的访问控制 (RBAC)

  • 网络策略

  • 资源配额

  • 服务账户的 AWS Identity and Access Management(IAM)角色(IRSA)

此外,此解决方案使用 Flux,确保在部署应用程序时保持租户配置不可变。您可通过在配置中指定包含 Flux kustomization.yaml 文件的租户存储库来部署租户应用程序。

此模式实现以下内容:

  • 通过手动部署 Terraform 脚本创建的 AWS CodeCommit 存储库、AWS CodeBuild 项目和 AWS CodePipeline 管道。

  • 托管租户所需的网络和计算组件。这些组件是使用 Terraform 通过 CodePipeline 和 CodeBuild 创建的。

  • 通过 Helm 图表配置的租户命名空间、网络策略和资源配额。

  • 使用 Flux 部署的、分属不同租户的应用程序。

建议您根据自身的独特需求和安全考量,仔细规划并构建适合自己的多租户架构。此模式为您的实现提供了起点。

先决条件和限制

先决条件

限制

  • 对 Terraform 手动部署的依赖:该工作流的初始设置,包括创建 CodeCommit 存储库、CodeBuild 项目和 CodePipeline 管道,依赖于手动 Terraform 部署。这在自动化和可扩展性方面存在潜在的限制,因为需要手动干预才能进行基础设施更改。

  • 对 CodeCommit 存储库的依赖:该工作流依赖 CodeCommit 存储库作为源代码管理解决方案,并且与 AWS 服务紧密耦合。

架构

目标架构

此模式通过部署三个模块来为数据平台构建管道、网络和计算基础设施,如下图所示。

管道架构:

适用于 Amazon EKS 多租户架构的管道基础设施

网络架构:

适用于 Amazon EKS 多租户架构的网络基础设施

计算架构:

适用于 Amazon EKS 多租户架构的计算基础设施

工具

AWS 服务

  • AWS CodeBuild 是一项完全托管式构建服务,可编译源代码、运行单元测试和生成部署就绪的构件。

  • AWS CodeCommit 是一项版本控制服务,可帮助您私下存储和管理 Git 存储库,而无需管理自己的源代码控制系统。

  • AWS CodePipeline 可帮助您快速对软件发布过程的不同阶段进行建模和配置,并自动执行持续发布软件变更所需步骤。

  • Amazon Elastic Kubernetes Service(Amazon EKS)可帮助您在 AWS 上运行 Kubernetes,而无需安装或维护您自己的 Kubernetes 控制面板或节点。

  • AWS Transit Gateway 是连接虚拟私有云(VPC)和本地网络的中央枢纽。

  • Amazon Virtual Private Cloud(Amazon VPC)可帮助您将 AWS 资源启动到您定义的虚拟网络中。该虚拟网络类似于您在数据中心中运行的传统网络,并具有使用 AWS 的可扩展基础设施的优势。

其他工具

  • Cilium 网络策略支持 Kubernetes L3 和 L4 网络策略。它们可通过 L7 策略进行扩展,为 HTTP、Kafka 和 gRPC 以及其他类似协议提供 API 级安全防护。

  • Flux 是一款基于 Git 的持续交付(CD)工具,可自动完成 Kubernetes 上的应用程序部署。

  • Helm 是 Kubernetes 的开源软件包管理器,可帮助您在 Kubernetes 集群上安装和管理应用程序。

  • Terraform 是 HashiCorp 推出的基础设施即代码(IaC)工具,可帮助您创建和管理云和本地资源。

代码存储库

此模式的代码可在 GitHub EKS 多租户 Terraform 解决方案存储库中找到。

最佳实践

有关此实施方案的使用指南和最佳实践,请参阅以下内容:

操作说明

任务描述所需技能

克隆项目存储库。

在终端窗口中运行以下命令,克隆 GitHub EKS 多租户 Terraform 解决方案存储库:

git clone https://github.com/aws-samples/aws-eks-multitenancy-deployment.git
AWS DevOps

引导 Terraform S3 存储桶和 Amazon DynamoDB。

  1. bootstrap 文件夹中,打开 bootstrap.sh 文件并更新 S3 存储桶名称、DynamoDB 表名称和 AWS 区域 的变量值:

    S3_BUCKET_NAME="<S3_BUCKET_NAME>" DYNAMODB_TABLE_NAME="<DYNAMODB_NAME>" REGION="<AWS_REGION>"
  2. 运行 bootstrap.sh 脚本。该脚本需要 AWS CLI,您已将其作为先决条件的一部分安装。

    cd bootstrap ./bootstrap.sh
AWS DevOps

更新 run.shlocals.tf 文件。

  1. 成功完成引导过程后,从 bootstrap.sh 脚本的 variables 部分复制 S3 存储桶和 DynamoDB 表名称:

    # Variables S3_BUCKET_NAME="<S3_BUCKET_NAME>" DYNAMODB_TABLE_NAME="<DYNAMODB_NAME"
  2. 将这些值粘贴到项目根目录下的 run.sh 脚本中:

    BACKEND_BUCKET_ID="<SAME_NAME_AS_S3_BUCKET_NAME>" DYNAMODB_ID="<SAME_NAME_AS_DYNAMODB_NAME>"
  3. 将项目代码上传至 CodeCommit 存储库。您可以通过 Terraform 自动创建此存储库,方法是在 true 文件中将以下变量设置为 demo/pipeline/locals.tf

    create_new_repo = true
  4. 根据您的要求更新 locals.tf 文件,以创建管道资源。

AWS DevOps

部署管道模块。

要创建管道资源,请手动运行以下 Terraform 命令。目前尚无自动运行这些命令的编排。

./run.sh -m pipeline -e demo -r <AWS_REGION> -t init ./run.sh -m pipeline -e demo -r <AWS_REGION> -t plan ./run.sh -m pipeline -e demo -r <AWS_REGION> -t apply
AWS DevOps
任务描述所需技能

启动管道。

  1. templates 文件夹中,确保 buildspec 文件将以下变量设置为 network

    TF_MODULE_TO_BUILD: "network"
  2. CodePipeline 控制台的管道详细信息页面上,选择发布更改以启动管道。

首次运行后,每当您向 CodeCommit 存储库主分支提交更改时,管道就会自动启动。

该管道包括以下阶段

  • validate 初始化 Terraform,使用 checkovtfsec 工具运行 Terraform 安全扫描,并将扫描报告上传到 S3 存储桶。

  • plan 显示 Terraform 计划并将该计划上传到 S3 存储桶。

  • apply 应用来自 S3 存储桶的 Terraform 计划输出并创建 AWS 资源。

  • destroy 移除在 apply 阶段创建的 AWS 资源。要启用此可选阶段,请在 demo/pipeline/locals.tf 文件中将以下变量设置为 true

    enable_destroy_stage = true
AWS DevOps

验证通过网络模块创建的资源。

确认在管道部署成功后创建了以下 AWS 资源:

  • 出口 VPC,包含 3 个公有子网和 3 个私有子网、互联网网关以及 NAT 网关。

  • 包含 3 个私有子网的 Amazon EKS VPC。

  • 租户 1 和租户 2 的 VPC,每个 VPC 各包含 3 个私有子网。

  • 中转网关,包含所有 VPC 连接以及通往每个私有子网的路由。

  • Amazon EKS 出口 VPC 的静态中转网关路由,包含目标 CIDR 数据块 0.0.0.0/0。这是使所有 VPC 能够通过 Amazon EKS 出口 VPC 访问出站互联网的必需配置。

AWS DevOps
任务描述所需技能

更新 locals.tf 以启用 CodeBuild 项目对 VPC 的访问权限。

要为 Amazon EKS 私有集群部署附加组件,必须将 CodeBuild 项目附加到 Amazon EKS VPC。

  1. demo/pipeline 文件夹中,打开 locals.tf 文件,并将 vpc_enabled 变量设置为 true

  2. 运行 run.sh 脚本,将更改应用于管道模块:

    demo/pipeline/locals.tf ./run.sh -m pipeline -env demo -region <AWS_REGION> -tfcmd init ./run.sh -m pipeline -env demo -region <AWS_REGION> -tfcmd plan ./run.sh -m pipeline -env demo -region <AWS_REGION> -tfcmd apply
AWS DevOps

更新 buildspec 文件以构建计算模块。

templates 文件夹中,在所有 buildspec YAML 文件中,将 TF_MODULE_TO_BUILD 变量的值从 network 设置为 compute

TF_MODULE_TO_BUILD: "compute"
AWS DevOps

更新租户管理 Helm 图表的 values 文件。

  1. 打开位于以下位置的 values.yaml 文件:

    cd cfg-terraform/demo/compute/cfg-tenant-mgmt

    文件如下所示:

    --- global: clusterRoles: operator: platform-tenant flux: flux-tenant-applier flux: tenantCloneBaseUrl: ${TEANT_BASE_URL} repoSecret: ${TENANT_REPO_SECRET} tenants: tenant-1: quotas: limits: cpu: 1 memory: 1Gi flux: path: overlays/tenant-1 tenant-2: quotas: limits: cpu: 1 memory: 2Gi flux: path: overlays/tenant-2
  2. globaltenants 部分中,根据您的需求更新以下配置:

    • tenantCloneBaseUrl – 托管所有租户代码的存储库的路径(我们对所有租户使用相同的 Git 存储库)

    • repoSecret – Kubernetes 密钥,存储用于对全局租户 Git 存储库进行身份验证的 SSH 密钥和已知主机信息

    • quotas – 您想要为每个租户申请的 Kubernetes 资源配额

    • flux path – 全局租户存储库中租户应用程序 YAML 文件的路径

AWS DevOps

验证计算资源。

在前面的步骤中更新文件后,CodePipeline 会自动启动。确认它已为计算基础设施创建了以下 AWS 资源:

  • 使用私有端点的 Amazon EKS 集群

  • Amazon EKS Worker 节点

  • Amazon EKS 附加组件:外部密钥、aws-loadbalancer-controllermetrics-server

  • GitOps 模块、Flux Helm 图表、Cilium Helm 图表和租户管理 Helm 图表

AWS DevOps
任务描述所需技能

验证 Kubernetes 中的租户管理资源。

运行以下命令,检查借助 Helm 是否成功创建了租户管理资源。

  1. 已创建租户命名空间,如 values.yaml 中所指定:

    kubectl get ns -A
  2. 为每个租户命名空间分配配额,如 values.yaml 中所指定:

    kubectl get quota --namespace=<tenant_namespace>
  3. 每个租户命名空间的配额详细信息都是正确的:

    kubectl describe quota cpu-memory-resource-quota-limit -n <tenant_namespace>
  4. Cilium 网络策略已应用于每个租户命名空间:

    kubectl get CiliumNetworkPolicy -A
AWS DevOps

验证租户应用程序部署。

运行以下命令,验证租户应用程序是否已部署。

  1. Flux 能够连接到 GitOps 模块中指定的 CodeCommit 存储库:

    kubectl get gitrepositories -A
  2. Flux 自定义控制器已在 CodeCommit 存储库中部署了 YAML 文件:

    kubectl get kustomizations -A
  3. 所有应用程序资源均部署在其租户命名空间中:

    kubectl get all -n <tenant_namespace>
  4. 已为每个租户创建入口:

    kubectl get ingress -n <tenant_namespace>

故障排除

问题解决方案

您会遇到类似于以下内容的错误消息:

Failed to checkout and determine revision: unable to clone unknown error: You have successfully authenticated over SSH. You can use Git to interact with AWS CodeCommit.

请按照以下步骤解决问题:

  1. 验证租户应用程序存储库:存储库为空或配置错误可能导致该错误。确保租户应用程序存储库包含所需的代码。

  2. 重新部署 tenant_mgmt 模块:在 tenant_mgmt 模块配置文件中,找到 app 数据块,然后将 deploy 参数设置为 0

    deploy = 0

    运行 Terraform apply 命令后,将 deploy 参数值更改回 1

    deploy = 1
  3. 重新检查状态:执行前面的步骤后,使用以下命令检查问题是否仍然存在:

     kubectl get gitrepositories -A

    如果问题仍然存在,请考虑更深入地研究 Flux 日志以获取更多详细信息,或参阅 Flux 一般问题排查指南

相关资源

其他信息

以下是部署租户应用程序的存储库结构示例:

applications sample_tenant_app ├── README.md ├── base │ ├── configmap.yaml │ ├── deployment.yaml │ ├── ingress.yaml │ ├── kustomization.yaml │ └── service.yaml └── overlays ├── tenant-1 │ ├── configmap.yaml │ ├── deployment.yaml │ └── kustomization.yaml └── tenant-2 ├── configmap.yaml └── kustomization.yaml