教程:将多容器应用部署到 Azure 容器应用

可以使用 Visual Studio 将多容器 应用部署到 Azure 容器应用 。 通常,将每个容器部署到单独的容器应用实例,但在同一容器应用环境中包括所有应用的容器,以允许它们轻松安全地相互通信。 可以将每个容器应用配置为接受来自容器环境中的请求,或允许外部流量。 Azure 容器应用高度灵活且可配置,允许许多可能的微服务方案,以及一整套高级监视工具。 如果使用 Docker Compose 管理本地容器应用,可以考虑尝试将其移植到 Azure 中的容器应用环境。

此过程涉及使用 Visual Studio 和 Azure 门户的几个步骤。 还可以使用 Azure CLI 执行这些作,但这超出了本教程的范围。 首先,我们使用使用 “创建多容器”应用生成的应用,并使用 发布 过程部署它。 Visual Studio 将指导你完成创建第一个容器应用、容器应用环境以及创建容器注册表以存储容器映像的步骤。 然后,使用其他容器应用再次运行发布过程。 具体来说,必须在发布过程中选择相同的容器应用环境。 最后,需要将 Redis 缓存配置为使用 Azure Redis 缓存服务。 修改缓存配置代码并重新发布 Web API。 然后,配置权限以授予应用系统分配的托管标识对缓存的访问权限。

先决条件

  • 一份 Azure 订阅。 注册 免费试用版
  • 安装了 Azure 开发和 Web 开发工作负载的 Visual Studio 2022 或更高版本。
  • docker 文件夹中的 MulticontainerSample 项目https://github.com/MicrosoftDocs/vs-tutorial-samples。 示例解决方案包含两个项目:Web API 后端和 ASP.NET 的 Razor 前端,这是你在另一个 教程中创建的。 还可以从头开始创建这两个项目,因为它们对默认模板进行了非常简单的修改,方法是按照该教程作。 可以跳过 Docker Compose 步骤。

部署 Web API 后端

  1. 在解决方案资源管理器中,右键单击 Web API 项目节点,然后选择“ 发布”。

  2. 选择目标 Azure,然后选择 Azure 容器应用

  3. 如果尚未使用与 Azure 订阅关联的帐户登录,可以立即登录,或者根据需要更改租户。

  4. 在指定容器应用的屏幕上,选择“ 新建 ”以创建新的容器应用。

    显示“发布”过程中的屏幕的屏幕截图,其中指定了现有容器应用,或选择为 Web API 服务创建新容器应用。

  5. “创建 Azure 容器应用 ”页上,输入资源组等详细信息。 在此步骤中,你将创建新的资源组、新的容器环境和新的容器注册表。

    显示“发布”过程中创建新容器应用的屏幕的屏幕截图。

    创建资源可能需要一些时间。 完成后,单击“ 下一步 ”移动到下一步。

  6. 在下一步中,将创建容器注册表。 如果创建新的容器注册表,系统会询问一些详细信息。 可以选择与容器应用相同的区域和资源组。

  7. 下一步要求你选择容器生成类型。 如果没有 Dockerfile,请选择.NET SDK;如果有,请选择Docker Desktop

    显示选择容器生成类型的屏幕截图,其中选择了 Docker Desktop。

  8. 对于部署类型,请选择 “发布”(生成 pubxml 文件) 以创建发布配置文件。

    显示选择部署类型的屏幕截图,其中选择了发布到 pubxml 文件的选项。

  9. 选择 “完成 ”以完成发布过程,并创建发布配置文件。 如果看到有关访问已发布容器的额外配置的提示,请选择 “是”。

    提示是否授予管理员用户访问权限。

    此时会看到一个页面,其中显示了 Azure 中的活动,当您关闭页面时,“发布界面”现在包含容器应用的信息,例如 Web API 的 URL。

    显示完成发布过程后“发布”屏幕的屏幕截图。

    单击“ 发布 ”按钮以发布到 Azure 容器应用。 Visual Studio 请求创建 Azure 资源,并启动 WebAPI 容器应用的发布过程。

    Visual Studio 可能会尝试加载新容器应用的页面,但这不会在此阶段起作用。

现已发布一次,现已创建发布配置文件(.pubxml 文件),因此下次发布时无需重复这些步骤。 只需单击此屏幕上的 “发布” 按钮,除非您想重新开始或更改您指定的任何 Azure 资源。

稍后,你将使用 Azure 门户对入口进行进一步的配置更改,以支持 Azure Redis 缓存。但首先,在下一部分中,你将发布 Web 前端。

部署前端

  1. 修改 Index.cshtml.cs 中的前端代码文件以引用 Web API 容器应用的新 URL。 这是 Web API 发布屏幕中的 “资源名称 ”下显示的名称。 对于容器到容器通信,可以直接将 HTTP 与容器应用的名称一起使用,而无需指定完全限定的域名(FQDN)和端口号。 在 OnGet 方法中,替换设置 RequestUri 引用 Web API 容器应用名称的现有行,如以下代码所示。

     request.RequestUri = new Uri("http://<mywebapi-container-app-name>/Counter");
    
    
  2. 在解决方案资源管理器中,右键单击 Webfrontend 项目的项目节点,然后选择“ 发布”。 在下一个屏幕上,选择“ 新建 ”以创建新的容器应用。

  3. 在“ 创建新的 Azure 容器应用 ”屏幕上,选择发布 Web API 项目时创建的同一资源组和相同的容器环境。

    显示发布过程中为 Webfrontend 指定现有容器或创建新容器的屏幕的屏幕截图。

  4. 重要! 选择之前创建的同一容器注册表。

    显示在“发布”过程中用于创建 Webfrontend 容器应用的屏幕截图,请确保选择之前创建的相同容器注册表。

  5. 为其他步骤选择与 Web API 相同的选项。 容器生成类型为 Docker Desktop,部署类型为 Publish(生成 pubxml 文件)。

  6. 选择 “完成 ”以完成发布过程,并创建发布配置文件。 你会看到一个页面,其中显示了 Azure 中的活动日志,关闭该页面后,“发布”屏幕现在包含你的容器应用的信息,例如用于 Webfrontend 应用入口的 URL。

在 Azure 门户中查看和配置容器应用

  1. 登录到 Azure 门户。
  2. 搜索容器应用并找到您刚刚创建的应用程序。
  3. 选择 入口 并配置以下选项:
    1. 入口 屏幕上,将 入口流量 设置为 “仅限容器应用环境”。 这意味着只有 Webfrontend 可以发送请求。 即使是 Visual Studio 也无法访问此服务,例如,完成发布过程并且 Visual Studio 尝试加载页面时,会在浏览器中收到错误,而不是访问该服务。 这是预期的。

    2. 检查入口端口(应为 8080)。 使用 HTTP 进行 Web API 调用,可以直接在请求 URI 中按名称引用容器应用。 由 Azure 容器应用生成的完全限定域名(FQDN)使用 HTTPS URL(如在 Visual Studio 的发布屏幕上显示),但内部流量可以绕过 HTTPS。

    3. 对于 Web前端入口,可以接受默认设置。 目标端口为 8080,因为入口使用 FQDN 和 HTTPS(或 HTTP 到 HTTPS 重定向)安全地处理所有请求,并使用容器端口 8080 上的 HTTP 将它们转发到 Webfrontend。

创建 Azure Redis 缓存

按照以下步骤在容器应用所在的同一资源组中创建 Azure Redis 缓存。

  1. 在 Azure 门户中,打开之前创建的 Web API 容器应用。 打开 “服务连接器 ”屏幕,然后选择“ 创建”。 此时会显示 “创建连接 ”部分。

  2. “创建连接 ”屏幕上,输入 服务类型 作为 Redis 缓存,然后选择“ 新建 ”以创建新的 Redis 缓存。

    显示 Web API 容器应用中的“服务连接器”屏幕的屏幕截图。

  3. 选择缓存,或按照 “创建新 ”链接创建缓存。 如果创建新的缓存,可能需要返回到容器应用和服务连接器,并重复前面的步骤来创建连接。

  4. 对于数据库,请选择“0”,为此缓存创建第一个编号的数据库。

  5. 移动到“ 身份验证 ”选项卡。选择 系统分配的托管标识。 接受所有其他默认值,然后选择“ 创建”。 这会创建与缓存的连接。

  6. 返回 Web API 容器应用的 “服务连接器 ”部分,刷新以查看新连接的缓存(如果尚未看到缓存),然后选择缓存旁边的复选框。 选择 “验证” 以检查连接的状态。 可以展开缓存节点以查看该 Azure 缓存的环境变量的值。 在本教程中,您只需要AZURE_REDIS_HOST,但是在实际代码中或为了更完整的配置,您可以使用其他选项。 使用此处的值设置 Dockerfile 中的环境变量,如下一部分所述,以便 Web API 可以连接到缓存。

有关详细信息,请参阅 快速入门:从 Azure 门户为 Azure 容器应用创建服务连接

为托管标识配置角色

在 Azure 门户中,使用 Azure Redis 缓存上的 访问控制(IAM) 授予参与者对容器应用系统分配的托管标识的访问权限。

  1. 在 Azure 门户中,打开 Azure Redis 缓存的页面,然后选择“访问控制”(IAM)。
  2. 选择“添加”“添加角色分配”。> 此时会打开 “添加角色分配 ”页。
  3. 选择“ 成员 ”选项卡,然后选择 托管标识
  4. 选择“选择成员”。 此时会打开“ 选择成员 ”页,然后选择 系统分配的托管标识
  5. 选择 容器应用,然后选择 Web API 容器应用。
  6. 在“ 角色 ”选项卡中,选择 “Redis 缓存参与者”。
  7. 选择“查看并分配”。 系统处理请求。
  8. 打开 角色分配 ,查看 Redis 缓存参与者 角色下系统分配的托管标识。

下一步是修改 Web API 客户端中的缓存配置以使用 DefaultAzureCredential,这是在使用系统分配的托管标识时进行身份验证的建议方法。 外部访问应用程序的任何人都不需要具有特定的用户级角色分配,即可通过这种形式的标识管理访问资源。 有关详细信息,请参阅 集成 Azure Redis 缓存 - 系统分配的托管标识

修改 Web API 项目以引用 Azure Redis 缓存服务

在发布 Web API 项目以在 Azure 中运行之前,请更新它以引用 Azure Redis 缓存,并使用托管标识安全地访问它。 若要适应此要求,可以在 Program.cs中修改缓存配置代码。

对于 Azure Redis 缓存,可以使用连接信息设置环境变量 AZURE_REDIS_HOST ,然后在启动代码中读取它以连接到 Azure Redis 缓存,并配置缓存。

您使用Azure.Identity来获取DefaultAzureCredential,该DefaultAzureCredential负责使用托管标识进行安全身份验证。

  1. 在 Visual Studio 的 Web API 项目中,添加对 NuGet 包 Azure IdentityMicrosoft.Azure.StackExchange.Redis 的引用。

  2. 为刚刚添加的包添加 using 指令。

    using Azure.Identity;
    using Microsoft.Azure.StackExchange.Redis;
    
  3. 更新 Redis 缓存的配置代码。 删除旧代码并将其替换为以下代码。 您可以稍后查看评论,并根据需要取消注释任何可选代码,以适应您自己的更高级场景。

     // Check the environment variable for the Redis cache host name
     var cacheHostName = Environment.GetEnvironmentVariable("AZURE_REDIS_HOST");
     if (string.IsNullOrEmpty(cacheHostName))
     {
         throw new InvalidOperationException("The environment variable 'AZURE_REDIS_HOST' is not set.");
     }
    
     var configurationOptions = ConfigurationOptions.Parse($"{cacheHostName}:6380");
    
     // For system-assigned identity.
     // In the Azure portal, we need to set up Redis service to grant Contributor access to the system-assigned identity
     // for the container app that hosts this Web API service.
     await configurationOptions.ConfigureForAzureWithTokenCredentialAsync(new DefaultAzureCredential());
    
     var connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(configurationOptions);
    
     builder.Services.AddStackExchangeRedisCache(options =>
     {
         options.ConfigurationOptions = configurationOptions;
         options.InstanceName = "SampleInstance";
     });
    
     // Uncomment the following line if you need to use the ConnectionMultiplexer directly
     // (for example, for advanced Redis operations like Pub/Sub or working with Redis data structures).
     // builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
     //     ConnectionMultiplexer.Connect(configurationOptions));
    
    

    创建缓存连接时设置的身份验证方法是系统分配的托管标识,因此此处的代码与该选择一致。 如果还想要使用其他身份验证方法,则需要在此处更改代码。 请参阅 集成 Azure Redis 缓存 - 系统分配的托管标识

    生成 Web API 项目以验证没有错误。

  4. 如果有 Dockerfile,请更新 Dockerfile 的基本阶段以定义环境变量 AZURE_REDIS_HOST。 在创建 Azure Redis 缓存时,或者从门户中 Web API 容器应用页的服务 连接器 部分(请参阅上一部分)获取主机。

    ENV AZURE_REDIS_HOST mycache.redis.cache.windows.net
    

    (可选)可以在环境变量中定义其他配置选项,例如, AZURE_REDIS_PORT 通常为 6380。 为简单起见,此值是硬编码的,而不是使用环境变量。 你可能还希望设置为ASPNETCORE_ENVIRONMENT“开发”。

    如果使用 .NET SDK 容器生成类型(没有 Dockerfile),则可以在 launchSettings.jsonprofiles > http设置环境变量。

     "http": {
       "commandName": "Project",
       "dotnetRunMessages": true,
       "launchBrowser": true,
       "launchUrl": "swagger",
       "applicationUrl": "http://localhost:5107",
       "environmentVariables": {
         "ASPNETCORE_ENVIRONMENT": "Development",
         "AZURE_REDIS_HOST": "cache11.redis.cache.windows.net"
       }
     }
    
  5. 你已准备好发布并验证这些更改。 选择“ 发布 ”屏幕上的 “发布 ”按钮。 Visual Studio 将尝试加载页面,但这失败,因为 Web API 容器应用无法访问容器应用环境外部的请求。

在使用 Azure Redis 缓存运行应用程序之前,需要设置具有访问缓存的适当权限的托管标识。

测试应用程序

返回到 Webfrontend 项目中的 “发布 ”屏幕,然后单击 Webfrontend URL 上的链接。 您应该看到 Webfrontend 应用出现,其中包含在刷新页面时更新的计数器。

小窍门

Azure 容器应用旨在最大程度地提高服务的运行时间。 如果某个服务出现问题,以至于未能通过健康探测,Azure 容器应用不会将其设为活动修订版,也不会使用它来处理请求。 因此,在开发和测试过程中,你可能会偶尔发现你所做的最新更改不会反映在实时站点中。 在 Azure 门户中,选择 “修订”和“副本 ”以查看最新发布的修订的状态。 在此处,可以打开日志来帮助排查问题。

祝贺! 已成功将多容器应用发布到 Azure 容器应用,并验证了容器之间的通信以及应用中 Azure Redis 缓存的使用。

清理资源

若要清理在本教程期间创建的资源,请转到 Azure 门户并删除包含容器应用、缓存和容器注册表的资源组。

后续步骤

  • 详细了解 Azure 容器应用
  • 了解 .NET Aspire,这是一种技术,可帮助你更轻松地开发与 Azure 中各种资源集成的复杂容器化应用和服务。 .NET Aspire 支持开发期间的编排、与各种服务的标准化集成,以及使用 Visual Studio 项目模板的工具支持。
  • 还可以使用 Azure 命令行接口(CLI)来处理容器应用。 安装 Azure CLI,然后通过 az containerapp up 命令部署 Azure 容器应用,开始使用 Azure 容器应用。