AWS App Runner 上的 .NET 工作负载

模块 3

模块 3:AWS App Runner 上的 .NET Web API

 动手实验

实验目标

在此动手实验中,您将创建一个使用 DynamoDB 表的 .NET Web API,然后将其容器化并托管于 AWS App Runner 之中。您可以在 Windows PC、macOS 或 Linux 计算机上完成此实验,也可以在云端的 Cloud9 环境中完成此实验。

首先,您将创建一个 DynamoDB 表和访问该表的 .NET 6 Web API 项目。在本地进行测试后,您将使用 Docker 和适用于 .NET CLI 的 AWS 部署工具对软件进行容器化并将其部署到 Amazon Elastic Container Registry(ECR)。然后,您将创建 App Runner 服务,以及与 DynamoDB 通信所需的 AWS Artifact,其中包括一个 IAM 角色、一个 VPC 连接器和一个适用于 DynamoDB 的 VPC 端点。您将在云端测试您的应用程序,并验证该应用程序能否从 DynamoDB 检索数据。您将在 App Runner 控制台中监控应用程序并查看日志。最后,您将更新该项目并将更新推送到 ECR,然后看到 App Runner 自动对其进行部署。最后,您将删除应用程序及其资源。

此实验包含 12 个步骤:

  1. 设置 AWS
  2. 设置开发环境
  3. 创建 DynamoDB 表
  4. 创建 .NET Web API 项目
  5. 在本地测试
  6. 将 Web API 项目发布到 ECR
  7. 创建 IAM 角色
  8. 创建 App Runner 服务
  9. 为 DynamoDB 创建 VPC 端点
  10. 在云端测试
  11. 部署更新
  12. 关闭项目

 所需时间

90 分钟

实施

第 1 步:设置 AWS

在此步骤中,您将设置 AWS 环境。

如果您已开始开发并部署到了 AWS App Runner,并且已经安装了适用于 .NET CLI 的 AWS 部署工具,则可以快进到第 3 步。

 1.获取 AWS 账户

使用现有的 AWS 账户或创建一个 AWS 账户。请勿使用生产账户。

 2.选择 AWS 区域

登录 AWS 管理控制台,然后选择一个支持 AWS App Runner支持 DynamoDB 的 AWS 区域,以在其中运行。

3.创建开发环境

如果使用本地计算机进行此实验,请继续执行第 2 步。

如果使用 Cloud9,请继续执行以下操作。

通过 AWS 管理控制台设置 Cloud9 环境:

A. 在 AWS 管理控制台中,导航到 Cloud9 并单击“创建环境”。

B. 将环境命名为 AppRunnerLab。

C. 保留默认设置并单击“创建”。

D. 等待环境完成创建,这需要几分钟时间。如果由于 t2.micro 实例类型在该区域不可用而导致环境创建失败,请重复上述步骤并选择另外一种小型实例类型。如果免费套餐中不包含该实例类型,请注意您需按照特定费率为实验期间对该实例类型的使用付费。

检查您的成果

现在,您应该:

✓ 有一个 AWS 账户

✓ 知道如何登录 AWS 管理控制台

✓ 已选择要运行的区域

✓ 有可用的本地计算机或 Cloud9 环境

第 2 步:设置开发环境

在此步骤中,您将安装软件,以设置开发环境。请跳过已安装项目。

1.安装 AWS CLI

安装 AWS 命令行界面(CLI)。

2.配置 AWS CLI

配置 AWS CLI,使其与 AWS 账户中的用户关联。

在命令/终端窗口中,使用以下命令配置区域:aws configure

3.安装 .NET SDK

安装 .NET 6 SDK。下载并安装适用于您操作系统的 SDK。

如果使用 Cloud9,则可以在“安装所需工具”(第 1 步和第 2 步)下运行这些命令。然后,运行以下命令:./dotnet-install.sh -c LTS

4.安装适用于 .NET CLI 的 AWS 开发工具

在命令/终端窗口中,使用以下命令安装适用于 .NET CLI 的 AWS 部署工具:

dotnet tool install -g aws.deploy.tools

5.安装 Docker

安装 Docker Desktop。如果您已安装 Docker,请注意,您需要使用的是版本 17.05 或更高版本。

6.安装 IDE

安装 IDE,例如 Microsoft Visual Studio 2022(Windows)、Visual Studio Code(Linux、macOS、Windows)或 JetBrains Rider(Linux、macOS、Windows)。确保您已安装适用于 C# 中的 .NET Web 开发的选项或扩展程序。

检查您的成果

现在,您应该:

✓ 已安装所有必备软件

✓ 已为您的 AWS 用户和区域配置 AWS CLI

第 3 步:创建 DynamoDB 表

在此步骤中,您将创建一个名为 Weather 的 DynamoDB 表,然后再创建一些数据记录。

 1.在 AWS 管理控制台中创建 DynamoDB 表

在 AWS 管理控制台中,导航到 Amazon DynamoDB 并单击创建表

    A. 表名称:Weather
    B. 分区键:Location
    C. 排序键:Timestamp
    D. 单击创建表

 2.在表中填充项目

单击 Weather 表名称,进入其详细信息页面,然后单击浏览表项目。添加以下项目:

A.单击创建项目JSON 视图。输入以下 JSON(Dallas, morning),然后单击创建项目

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T06:00:00"
  },
  "Summary": {
    "S": "Hot"
  },
  "TempC": {
    "N": "33"
  },
  "TempF": {
    "N": "92"
  }
}

B.以同样的方式,使用以下 JSON 添加第二个项目(Dallas, mid-day):

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T12:00:00"
  },
  "Summary": {
    "S": "Scorching"
  },
  "TempC": {
    "N": "43"
  },
  "TempF": {
    "N": "109"
  }
}

C.使用以下 JSON 添加第三个项目(Dallas, evening):

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T18:00:00"
  },
  "Summary": {
    "S": "Hot"
  },
  "TempC": {
    "N": "36"
  },
  "TempF": {
    "N": "97"
  }
}

D.使用以下 JSON 添加第四个项目(Minneapolis, morning):

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T06:00:00"
  },
  "Summary": {
    "S": "Cool"
  },
  "TempC": {
    "N": "13"
  },
  "TempF": {
    "N": "56"
  }
}

E.使用以下 JSON 添加第五个项目(Minneapolis, mid-day):

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T12:00:00"
  },
  "Summary": {
    "S": "Balmy"
  },
  "TempC": {
    "N": "22"
  },
  "TempF": {
    "N": "72"
  }
}

F.使用以下 JSON 添加第六个项目(Minneapolis, evening): 

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T18:00:00"
  },
  "Summary": {
    "S": "Balmy"
  },
  "TempC": {
    "N": "19"
  },
  "TempF": {
    "N": "67"
  }
}

检查您的成果

现在,您应该:

✓ 有一个名为 Weather 的 DynamoDB 表,并且表中填充了 6 个项目。

第 4 步:创建 .NET Web API 项目

在此步骤中,您将使用 dotnet new 命令创建一个 Web API 项目,并更新其代码以从 DynamoDB 表中检索数据。

1.将目录更改为开发文件夹

打开命令/终端窗口并将目录更改为开发文件夹。

2.创建 .NET WebAPI 项目

运行以下 dotnet new 命令,创建一个名为 HelloAppRunnerVpc 的新 Web API 项目。

dotnet new webapi -n HelloAppRunnerVpc --framework net6.0

3.在 IDE 中打开项目

在您的 IDE 中打开该 HelloAppRunnerVpc 项目。

如果您已为 IDE 安装了 AWS Toolkit,请将 AWS 各区服务浏览器中的区域设置为您在第 1 步中选择的区域。

4.审核已生成的项目

已生成的项目是 WeatherForecast API,在 .NET 示例中非常常用。

要进行试用,请按 F5 并用 Swagger 对其进行测试。您会看到该服务有一个 /WeatherForecast 操作,可返回模拟天气数据 JSON。

停止运行程序。

5.添加 AWS SDK NuGet 软件包

在命令/终端窗口中,将目录更改为项目文件夹。运行以下 dotnet add package 命令,将 AWS SDK NuGet 软件包 AWSSDK.DynamoDBv2 添加到项目中:

cd HelloAppRunnerVpc
 dotnet add package AWSSDK.DynamoDBv2

6.修改 Program.cs

在代码编辑器中打开 Program.cs,然后删除或注释掉此语句,App Runner 不需要使用此语句:

//app.UseHttpsRedirection();

 7.对 WeatherForecast 类进行编码

打开 WeatherForecast.cs 并将其替换为以下代码。此类包含从 Weather 表中检索的一个项目:

namespace HelloAppRunnerVpc;

public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
    public int TemperatureF { get; set; }
    public string? Summary { get; set; }
}

 8.对 WeatherForecastController 类进行编码

打开 Controllers 文件夹中的 WeatherForecastController.cs,然后将其替换为以下代码。将 RegionEndpoint.USEast1 更新为您正在其中运行的区域。此代码在服务的根目录下实施运行状况检查方法,并在 /WeatherForecast 目录下实施 WeatherForecast 方法,后者接受一个位置参数并从 DynamoDB Weather 表为其检索数据。它对表执行扫描,以查找分区键与位置相匹配的记录。结果以一组 JSON 记录的形式输出。
using Amazon;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DocumentModel;
using Microsoft.AspNetCore.Mvc;

namespace HelloAppRunnerVpc.Controllers;

[ApiController]
[Route("")]
public class WeatherForecastController : ControllerBase
{
    static readonly RegionEndpoint region = RegionEndpoint.USEast1;

    private readonly ILogger _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet("")]
    public string GetHealthcheck()
    {
        return "Healthcheck: Healthy";
    }

    [HttpGet("WeatherForecast")]
    public async Task<IEnumerable<WeatherForecast>> GetWeatherForecast(string location = "Dallas")
    {
        List<WeatherForecast> forecasts = new List<WeatherForecast>();

        try
        {
            _logger.LogInformation($"00 enter GET, location = {location}");

            var client = new AmazonDynamoDBClient(region);
            Table table = Table.LoadTable(client, "Weather");

            var filter = new ScanFilter();
            filter.AddCondition("Location", ScanOperator.Equal, location);

            var scanConfig = new ScanOperationConfig()
            {
                Filter = filter,
                Select = SelectValues.SpecificAttributes,
                AttributesToGet = new List<string> { "Location", "Timestamp", "TempC", "TempF", "Summary" }
            };

            _logger.LogInformation($"10 table.Scan");

            Search search = table.Scan(scanConfig);

            List<Document> matches;
            do
            {
                _logger.LogInformation($"20 table.GetNextSetAsync");
                matches = await search.GetNextSetAsync();
                foreach (var match in matches)
                {
                    forecasts.Add(new WeatherForecast
                    {
                        Date = Convert.ToDateTime(match["Timestamp"]),
                        TemperatureC = Convert.ToInt32(match["TempC"]),
                        TemperatureF = Convert.ToInt32(match["TempF"]),
                        Summary = Convert.ToString(match["Summary"])
                    });
                }
            } while (!search.IsDone);

            _logger.LogInformation($"30 exited results loop");

        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "90 Exception");
        }

        _logger.LogInformation($"99 returning {forecasts.Count} results");

        return forecasts.ToArray();
    }
}

9.保存更改并进行构建

保存您的更改并确保项目成功构建。

检查您的成果

现在,您应该:

✓ 有一个名为 HelloAppRunnerVpc 的 Web API 项目

✓ 已在 WeatherForecastController.cs 中设置区域

第 5 步:在本地测试

在此步骤中,您将在本地测试 Web API 并确认从 DynamoDB 检索数据。

 1.调试项目

在 IDE 中按 F5,然后等待应用程序在浏览器中完成构建并启动。

 2.测试运行状况检查操作

在浏览器中,从 URL 中移除 Swagger 路径,以访问服务根目录。然后,您应该会看到一条运行状况检查消息。App Runner 会定期对站点执行 ping 操作,来检查运行状况。

 3.测试达拉斯的天气预报操作

将 /WeatherForecast?location=Dallas 添加到 URL 路径的末尾。您应该会看到天气预报数据 JSON,其中包含您在第 1 步中在 DynamoDB 表中创建的值。

4.测试明尼阿波利斯的天气预报操作

将 URL 路径更改为以 /WeatherForecast?location=Minneapolis 结尾。现在您可以看到该城市的数据。

5.测试无效位置的天气预报操作

试试其他位置名称,您会看到一个空响应,因为表中没有相应的数据。

6.停止程序

停止运行程序。

虽然在本地测试时,我们的应用程序可以直接访问 DynamoDB,但在云端却无法直接访问,因为默认情况下,App Runner 仅可访问公共端点。我们必须采取额外步骤,为 App Runner 添加一个 VPC 连接器,并为 DynamoDB 添加一个匹配的 VPC 端点。

检查您的成果

现在,您应该:

✓ 已在本地测试您的 Web API 项目。

✓ 确认已检索到 DynamoDB 数据。

第 6 步:将 Web API 项目发布到 ECR

在此步骤中,您将使用 AWS .NET 部署工具对项目进行容器化并将容器映像推送到 Amazon Elastic Container Registry(ECR)。

1.创建 Dockerfile

使用以下代码将名为 Dockerfile 的文本文件添加到您的项目文件夹:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["HelloAppRunnerVpc.csproj", "."]
RUN dotnet restore "./HelloAppRunnerVpc.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "HelloAppRunnerVpc.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "HelloAppRunnerVpc.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HelloAppRunnerVpc.dll"]

2.部署到 ECR

将您的项目作为容器映像部署到 ECR:

a.在命令/终端窗口中,运行以下命令启动部署,并指定您的首选区域。(图 1)

dotnet aws deploy --region us-west-2

b.选择相应选项,将容器映像推送到 Amazon Elastic Container Registry(ECR)

c.在“当前设置”提示符处,输入数字来更改图像标签,并将其设置为最新。(图 2)

d.按 Enter 键确认部署。

3.等待部署

等待部署完成。

4.在 AWS 管理控制台中确认部署

确认容器映像已部署到 ECR。在 AWS 管理控制台中,导航到 ECR。此时应列出一个名为 helloapprunnervpc 的存储库。

检查您的成果

现在,您应该:

✓ 已使用 Dockerfile 容器化您的项目。

✓ 已将容器映像部署到 Amazon ECR。

第 7 步:创建 IAM 角色

在此步骤中,您将使用 AWS 管理控制台创建一个名为 AppRunnerInstanceDynamoDB 的 IAM 角色。此角色将允许 App Runner EC2 实例访问 DynamoDB 表。

1.为 DynamoDB 表创建访问策略

创建一个允许访问 Weather DynamoDB 表的策略:    

    a.导航到 Identity and Access Management(IAM)。

    b.从左侧窗格中选择“策略”,然后单击“创建策略”。

    c.创建策略并输入以下 JSON,将 [account] 替换为您的 12 位 AWS 账号,并将 [region] 替换为您的区域。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "dynamodb:*",
            "Resource": "arn:aws:dynamodb:[region]:[account]:table/Weather"
        }
    ]
}

    d.依次单击“下一步:标签”和“下一步:查看”。将策略命名为 ddb-Weather,然后单击“创建策略”。

2.为 EC2 实例创建角色

为 App Runner EC2 实例创建角色:

    a.从左侧窗格中选择角色,然后单击创建角色

    b.对于“可信实体类型”,选择“AWS 服务”。(图 1)

    c.对于“应用场景”,选择“EC2”并单击“下一步”。(图 1)

    d.搜索并选择以下权限:ddb-Weather、AmazonDynamoDBFullAccessAWSAppRunnerFullAccess。然后,单击下一步。(图 2)

    e.在“信任关系”选项卡上,单击“编辑信任策略”。将其替换为此 JSON,然后单击“更新策略”。(图 5)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "ec2.amazonaws.com",
                    "tasks.apprunner.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

    f.将角色命名为 AppRunnerInstanceDynamoDB,然后单击创建角色。(图 3)

检查您的成果

现在,您应该:

✓ 有一个名为 AppRunnerInstanceDynamoDB 并带有 3 个策略的 IAM 角色。 

第 8 步:创建 App Runner 服务

在此步骤中,您将创建 App Runner 服务和一个 VPC 连接器。

 1.创建服务

在 AWS 管理控制台中,导航到 AWS App Runner,然后单击创建服务

    a.存储库类型:容器注册表。 (图 1)

    b.提供程序:Amazon ECR

    c.单击浏览,然后选择您在第 6 步中部署到 ECR 的容器。(图 2)

    d.对于“部署设置触发器”,选择自动

    e.对于“ECR 访问角色”,选择创建新服务角色

    f.单击下一步

 2.配置服务

在“配置服务”页面上,

    a.服务名称:HelloAppRunnerVpc

    b. b.端口:80

3.配置实例角色

展开“安全”部分并将实例角色设置为 AppRunnerInstanceDynamoDB

4.创建 VPC 连接器

展开“网络”部分并创建 VPC 连接器:

    a.在“网络”下,选择自定义 VPC

    b.在“VPC 连接器”下,单击新增

    c.VPC 连接器名称:AppRunnerDynamoDB。(图 1)

    d.VPC:选择您的默认 VPC。

    e.子网:选择所有子网。

    f.安全组:选择您的默认安全组。(图 2)

    g.单击添加。如果您收到错误消息,显示您的某个子网不支持 App Runner 服务,请将其从子网列表中移除,然后再次单击添加。(图 2)

    h.单击下一步,然后单击创建并部署

5.等待部署

等待部署,这需要几分钟的时间。这是休息的好时机。

6.记录服务 URL

服务部署完成后,您将看到成功创建服务消息。

记录默认域 URL。这是您的服务 URL。

刷新事件日志,您应该会看到服务正在运行的确认消息。

7.浏览到服务 URL

浏览到 URL,您应该会看到您的运行状况检查。我们的服务托管在 App Runner 中,但它尚无法访问 DynamoDB。我们已创建 App Runner VPC 连接器,但我们仍然需要为 DynamoDB 创建相匹配的 VPC 端点。

检查您的成果

现在,您应该:

✓ 有一项名为 HelloAppRunnerVpc、正在运行的 AWS App Runner 服务。

✓ 有服务端点 URL。

✓ 已确认运行状况检查 URL 能在浏览器中正常响应。

第 9 步:为 DynamoDB 创建 VPC 端点

在此步骤中,您将为 DynamoDB 创建 VPC 端点。

1.在 AWS 管理控制台中,导航到 VPC

2.创建端点

从左侧面板中选择“端点”,然后单击创建端点

    a.名称:vpc-endpoint-dynamodb。(图 1)

    b. b.服务类别:AWS 服务

    c.服务:在搜索框中输入 DynamoDB,然后选择 com.amazonaws.region.dynamodb

    d.VPC:选择您的默认 VPC。

    e.路由表:选择“主路由表”。

    f.单击创建端点。(图 2)

检查您的成果

现在,您应该:

有一个名为 vpc-endpoint-dynamodb、适用于 DynamoDB 的 VPC 端点。

第 10 步:在云端测试

现在,我们已准备好将其整合在一起,并可以在云端测试 Web API 了。

 1.访问服务 URL

在浏览器中,访问您在第 6 步中记录的服务 URL。您会看到运行状况检查的响应。

 2.测试达拉斯的天气预报操作

/WeatherForecast?location=Dallas 添加到路径的末尾。现在,您可以看到您在第 1 步中输入的达拉斯的记录

 3.测试明尼阿波利斯的天气预报操作

3.将路径的末尾改为 /WeatherForecast?location=Minneapolis,然后您会看到该市的记录。

恭喜! 您的 Web API 已托管于 AWS App Runner 之中,且该服务正在与 DynamoDB 通信。

检查您的成果

现在,您应该:

✓ 已确认您的 AWS App Runner 服务能够从 DynamoDB 表中检索数据。

第 11 步:部署更新

在此步骤中,您将更新 Web API、推送经过更新的容器,并看到 App Runner 自动将更新后的容器部署到该服务。之所以如此,是因为我们在创建服务时在第 8 步中配置了自动部署。

1.修改服务

在您的 IDE 中,更改 GetWeatherForecast 方法,使响应略有不同。例如,您可以在“摘要”字段中添加一个感叹号。

2.在本地构建和测试

在本地构建和测试项目,确保其按预期运行。 

3.重新部署容器

停止程序。在命令/终端窗口中,再次运行 dotnet aws deploy,将更新后的容器部署到 ECR,就像在第 6 步中的操作一样。确保标签仍为 最新

4.监控服务重新部署

在 AWS App Runner 控制台中,查看您的服务。部署新容器不久后,App Runner 将自动部署更新。

5.测试更新后的服务

等待更新完成后,按照第 10 步中的操作浏览到该服务,对其进行测试。确认您现在可以看到该服务输出的新版本。

检查您的成果

现在,您应该:

✓ 已通过更改完成了对 Web API 项目的更新。

✓ 已向 ECR 部署了更新的容器。

✓ 确认 App Runner 已自动部署更新。 

第 12 步:关闭项目

您可以随意对项目进行更改,以测试您的知识掌握情况。

完成项目的所有相关操作后,将其关闭。您一定不希望为自己没有使用的东西付费。

1.删除 App Runner 服务

在 AWS 管理控制台中,导航到 App Runner 并删除 HelloAppRunnerVpc 服务

2.删除 DynamoDB 表

导航到 DynamoDB 并删除 Weather

3.删除容器映像

导航到 ECR 并删除 helloapprunnervpc 容器映像。

4.删除 Cloud9 环境

如果使用 Cloud9,请导航到 Cloud9 并删除 AppRunnerLab 环境。

检查您的成果

现在,您应该:

✓ 已删除 App Runner 服务。

✓ 已删除 DynamoDB 表。

✓ 已删除 ECR 容器映像。 

摘要

在此实验中,您创建了一个 DynamoDB 表并在其中填充了数据。您使用 dotnet new 命令生成了一个 .NET Web 应用程序项目。您对 Web API 进行编码,使其能够从 DynamoDB 表中检索天气数据。您将容器部署到了 ECR。您创建了一个 App Runner 服务来托管该 Web API。您创建了一个 App Runner VPC 连接器并为 DynamoDB 创建了一个 VPC 端点,以连接这两个可以连接的服务。您对当前托管于 AWS 上的应用程序进行了测试,并看到它可以正常运行。您将更新后的容器部署到了 ECR 并看到它自动部署到了 App Runner 服务。最后,您从 AWS 中取消了应用程序的分配。

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