65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Fargate 在 AWS ECS 中部署 ASP.NET Core 微服务

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (4投票s)

2019年4月12日

CPOL

8分钟阅读

viewsIcon

21488

在本文中,我们将学习如何使用 Cloudformation 模板和 AWS Console,通过 Fargate 在 AWS ECS 中部署 ASP.NET Core 微服务。

引言

近年来,微服务获得了巨大的关注,大多数系统都在采用这种新的架构来开发业务应用程序。然而,微服务可能不是每个人或每个问题的唯一解决方案。假设您有一个独立的团队来构建和管理系统中的独立模块,那么这可能是一种理想的方法。话虽如此,即使对于单团队项目,它也可以是一种更好的架构,用于开发复杂的分布式应用程序并将其部署到任何云环境中。

您可以在此处找到更多关于微服务的优质资源。

在本系列中,我将带您了解如何在 AWS 中使用 ECS Fargate 部署 .NET Core 微服务。

为什么选择 ECS Fargate?

我喜欢 AWS Lambda 和 Azure Functions 等无服务器框架。然而,它们在内存、超时和框架版本方面存在一些限制。假设您有一个组件需要超过 3GB 的内存来处理其工作,并且/或者它可能需要超过 10 分钟,并且/或者它使用旧的 .NET Core 框架或 Node.js 框架。AWS Fargate 是一个无服务器框架,用于在 ECS 容器上部署应用程序,而无需我们维护主机。我们可以自由选择这些容器的框架和内存分配。

必备组件

  • 我假设您已经使用过 ASP.NET Core 应用程序。
  • 您需要对 AWS 服务(如 EC2、ECS、ELB、ECR、IAM 和 AWS 配置)有一些基本了解。
  • 开发机器上应安装Dotnet core SDKAWS CLIDocker以及 Visual Studio Code 或任何 IDE。

应用程序架构

  • 我为车辆保险用例创建了一个应用程序。任何客户端都可以向元数据服务发出 REST 调用来创建/更新客户、车辆信息和车辆保险报价请求。报价将在服务器上生成并返回给客户端。一旦您选择了报价,客户端应调用策略服务来处理并创建策略。
  • 我为这些服务创建了两个简单的 ASP.NET Core Web API 项目,一个用于管理客户、车辆和报价等基本信息。另一个用于管理策略。
  • 每个服务都将与自己的数据库交互,以使这些服务完全独立。
  • 这些数据库之间的数据可以通过事件模式进行同步或更改,这超出了本次演示的范围。

AWS 基础设施架构

我们将使用 Fargate 将这些简单的微服务部署到 AWS ECS 集群。

  • 来自客户端的每个请求都可以到达单个应用程序负载均衡器,然后负载均衡器会通过匹配 URL 模式将请求转发到相应的目标组。
  • 目的是为每个服务创建一个唯一的目标组,以便它们将请求转发到使用 Fargate 在 ECS 集群中启动的容器。
  • ECS 容器中运行的 API 应能够在同一 VPC 中与 SQL Server RDS、Elasticache 和 DynamoDB 等数据库服务进行通信。

ASP.NET Core WebAPI 的就绪性

首先,让我们了解 ASP.NET Core webapi 服务中需要注意的部分,以便能够部署到 ECS 集群。

  • 所有查找数据和会话相关数据都应存储在单个 Redis 缓存实例或某个公共数据库中,以便所有服务实例都能从单个存储库访问数据。
    services.AddStackExchangeRedisCache(options =>
    {
       options.Configuration = Configuration["Cache:AWSRedisEndPoint"];
    });
  • 每个服务都应配置一个健康检查路由,以便 ELB 可以检查容器中的服务是否正在运行。我使用了内置中间件来配置此功能。
    //this line in ConfigureServices method of Startup.cs
    services.AddHealthChecks();
    //this line in Configure method of Startup.cs
    app.UseHealthChecks(“/health”);
  • 服务中的所有路由都应具有一个通用的基础路由路径,以便 ELB 中的请求能够通过匹配基础路由路径发送到此服务的目标组。
    [Route(“metadataapi/[controller]”)]
    public class CustomersController : ControllerBase
    [Route(“metadataapi/[controller]”)]
    public class VehiclesController : ControllerBase
  • 我使用了 Swagger 进行 API 发现文档。此 Swagger 配置也应考虑使用基础路由路径。
    app.UseSwagger(c =>
    {
     c.RouteTemplate=”policyapi/swagger/{documentName}/swagger.json”;\
    });
    app.UseSwaggerUI(c =>
    { 
     c.SwaggerEndpoint(“/policyapi/swagger/v1/swagger.json”,”APIdoc”);
     c.RoutePrefix = “policyapi/swagger”;
    });

用于在 ECS 上运行容器的 Docker 镜像

  • Docker 是一个在主机上创建和部署应用程序容器的平台。如果您之前没有接触过 Docker,请考虑学习一些基础知识。我喜欢这个Pluralsight 课程
  • 我为每个服务创建了 Dockerfile,其中包含构建 API 镜像的基本说明。
  • 我还创建了一个 docker-compose 文件,用于在本地主机上构建和运行这些容器。
  • 您需要创建一个.env 文件来为服务设置环境变量。
  • 使用终端中的此命令构建并在容器中运行镜像。
    docker-compose up -d --build
  • 通过导航到 Swagger URL https://:8080/metadataapi/swagger,确保 API 在容器中运行正常。
  • 使用此命令为每个服务创建镜像仓库。
    aws ecr create-repository --repository-name metadata-api
  • 您也可以通过登录 AWS ECR 控制台来创建仓库。

  • 使用以下命令为运行中的服务镜像打上 ECR 仓库 URI 的标签。
    docker tag metadataapi:latest
    875373411184.dkr.ecr.us-west1.amazonaws.com/insurancemetadata:latest
  • 登录 ECR 以将此镜像推送到云。我们需要运行此命令来生成登录命令。
    aws ecr get-login --no-include-email --region us-west-2
  • 复制并粘贴上述命令的输出到终端以执行实际登录。
  • 成功登录后,将这些服务镜像推送到云。
    docker push 
    875373411184.dkr.ecr.us-west-1.amazonaws.com/insurancemetadata

使用 Cloudformation 在 ECS 集群中部署服务镜像

将 Docker 镜像推送到 ECR 仓库后,我们可以使用以下两个 Cloudformation 模板来部署服务。

  • 第一个用于创建负载均衡器、安全组和集群等通用资源。
  • 第二个用于使用 Fargate 在容器中配置服务,并创建必要的 IAM 角色、目标组、任务定义和 ECS 服务。

我们需要通过传递必要的参数为应用程序中的每个服务创建一个堆栈。

  • 您可以使用 AWS Console 来为这些 Cloudformation 模板创建堆栈,或从命令行执行它们。

    aws cloudformation deploy 
       --template-file /path_to_template/microservice-cluster-elb.yaml 
    --stack-name my-new-stack
    --parameter-overrides EnvironmentName=mycluster vpcid=<vpcid> ...
  • 第一个堆栈成功完成后,我们需要为每个服务创建堆栈。这次,我们需要查找第一个堆栈的输出以传递给服务堆栈,例如 elbruleidsecuritygroupnameclustername
  • 在创建服务之前,请确保模板中定义了所有必需的环境变量。
  • 第二个堆栈创建后,您可以在 AWS Console 中找到 ELB 负载均衡器的 DNS 条目。
  • 浏览每个服务的 Swagger URL,以确保 API 已成功部署。

  • 这些 Cloudformation 模板也可重用于 CI/CD 工具集成。
  • 部署这些微服务的另一个选项是使用 AWS Web Console。

使用 AWS Console 在 ECS 集群中部署服务镜像

我们已经学习了如何使用 Cloudformation 在 AWS ECS Fargate 中部署 .NET 微服务。在本节中,我们将使用 AWS Console 部署相同的应用程序,以了解每个 AWS 服务。

步骤 1:应用程序负载均衡器 - ELB

  • 我们使用 ELB 将 HTTP 请求平均分发到所有 ECS 容器。ELB 是 AWS 中完全托管的负载均衡器。

  • 将 API 镜像推送到 AWS ECR 仓库后,只需验证它们是否存在于 AWS Console 中。

  • 导航到 **EC2 服务**,点击 **负载均衡器**,选择 **创建负载均衡器**,然后选择 **应用程序负载均衡器**。

  • 输入基本信息,选择 VPC 和子网。

  • 配置 **安全组**,并设置所需的 IP 地址以允许访问 ELB。

  • 输入默认目标组名称和设置。另外,

  • 检查并点击 **创建**,然后导航到 ELB Dashboard。
  • 导航到 **监听器** 选项卡,然后点击 **查看/编辑规则** 链接。

  • 导航到 **编辑** 选项卡,然后编辑默认规则以返回固定响应 503。

  • 点击 **更新** 按钮,找到 ELB 的 DNS 名称并进行浏览。

步骤 2:ECS 集群

  • ECS 是 AWS 在云中用于容器的自定义编排服务。
  • 导航到 **ECS**,选择 **集群**,然后点击 **创建集群**。

  • 选择 **仅网络** 选项作为集群模板。这告诉 ECS 使用 Fargate。

  • 输入名称,然后点击 **创建**。

步骤 3:ECS TaskDefinition 和 ECS Service

  • TaskDefinition:这是一组指令,例如在集群中创建容器时要使用的镜像、环境变量、内存大小和端口。
  • 导航到 ECS 下的 **任务定义** 菜单,然后点击 **创建新任务定义** 按钮。

  • 在下一步,选择 Fargate 作为启动类型。

  • 输入名称和其他详细信息,例如任务角色 - 如果任务执行角色不存在,请在 IAM 控制台中创建一个。

  • 通过点击底部的 **添加容器** 按钮为该任务添加容器。
    • 在容器弹出窗口中填写名称、服务镜像 URL 和端口等信息。您可以将其余设置保留为默认值,除非有特定要求。

  • 添加容器后,只需点击 **创建** 按钮,然后导航到任务详细信息页面进行确认。
  • ECS 服务 是 ECS 中在一种环境中以期望数量的容器执行任务定义的机制。此外,您可以为这些容器配置 ELB 目标组,以便负载均衡器能够访问它们。

  • 导航到 **集群** 的仪表板,然后选择我们创建的集群。

  • 在集群详细页面的 **服务** 选项卡下,点击 **创建** 按钮。

  • 输入所有基本信息,例如启动类型、名称、任务定义和任务数量。

  • 选择 VPC 和至少两个子网(优先选择私有子网)以及安全组。

  • 选择我们在步骤 1 中创建的应用程序负载均衡器。

  • 点击 **添加负载均衡器** 按钮,并填写信息以为此服务创建单独的目标组。另外,请确保您输入的路径模式与您的 API 基础根路径 — /metadataapi* 和健康检查路由相同。

  • 除非您需要设置 Route 53 DNS,否则请取消选择 Route 53,然后点击 **下一步**。

  • 检查并点击 **创建服务**。
  • 等待几分钟让任务运行,然后通过转到 **集群详细信息** 页面的 **任务** 选项卡来验证任务状态。

  • 如果您看到任何错误,或者任务从未返回“运行中”状态,只需通过点击页面上第一个链接导航到执行任务页面。您应该能看到详细的错误信息和日志。
  • 现在,通过浏览器访问 ELB DNS 名称以及 Swagger 路由,以验证服务是否成功运行。

结论

为微服务应用程序中的所有其他服务重复步骤 3,它们应该可以通过相同的 ELB DNS URL 和不同的路由访问。

通过这种方法,您可以在不影响其他服务的情况下部署微服务。显然,这种 UI 方法只是为了理解各种服务。大多数情况下,我们应该使用某种基础设施即代码技术,如 Cloudformation、Terraform 或 AWS Code Deploy,以便与我们的 CI/CD 工具集成。

参考文献

历史

  • 2019年4月18日:初始版本
© . All rights reserved.