Azure 容器应用上的 .NET 概述

若要将 .NET 应用程序部署到 Azure 容器应用等云原生环境,你需要进行一些决策来确保应用程序顺畅安全地运行。 本指南介绍了将 .NET 应用程序部署到 Azure 容器应用所涉及的关键概念。

Azure 容器应用是一项完全托管的无服务器容器服务,可用于运行容器化应用程序,而无需管理底层基础结构。 容器应用包括对自动缩放、运行状况检查和传输层安全性 (TLS) 证书等功能的内置支持。

本文详细介绍了在 Azure 容器应用上部署 .NET 应用程序时对你而言非常重要的概念和问题。

选择资源类型

容器应用支持两种类型的资源:应用和作业。 应用是持续运行的服务,而作业则是旨在运行到完成的短期任务。

在准备部署应用时,请考虑这两种应用程序类型之间的差异,因为它们的行为会影响你管理 .NET 应用程序的方式。 下表描述了应用和作业之间的用例差异。

用例 资源类型
服务于 HTTP 请求的 ASP.NET 核心 Web API 应用
处理某些数据然后退出的 .NET Core 控制台应用程序 作业
持续运行的后台服务,用于处理来自队列的消息 应用
仅在将大型映像保存到存储帐户时运行的映像优化服务。 作业
使用 Hangfire、Quartz.NET 或 Azure WebJobs SDK 等框架的应用程序 应用

容器化和部署 .NET 应用程序

对于应用或作业,你需要生成容器映像来打包 .NET 应用程序。 有关生成容器映像的详细信息,请参阅适用于 ASP.NET Core 的 Docker 映像

设置后,可以按照以下指南将应用程序部署到 Azure 容器应用:

使用 HTTP 入口

Azure 容器应用包括一个内置的 HTTP 入口,可用于向来自容器外部的流量公开应用。 容器应用入口位于你的应用和最终用户之间。 由于该入口起着中介的作用,因此最终用户看到的一切都在该入口结束,你的应用看到的一切都从该入口开始。

该入口将管理 TLS 终止和自定义域,因此你无需在应用中手动配置它们。 通过该入口,端口 443 将针对 HTTPS 流量公开,并可以选择为 HTTP 流量公开端口 80。 该入口会将请求转发到应用的目标端口。

如果应用需要有关原始请求的元数据,则可以使用 X 转发标头

定义目标端口

若要接收流量,请在供应用侦听流量的目标端口上配置入口。

当 ASP.NET Core 在容器中运行时,应用程序将按照容器映像中的配置侦听端口。 使用官方 ASP.NET Core 映像时,应用将配置为在默认端口上侦听 HTTP。 默认端口取决于 ASP.NET Core 版本。

运行时 目标端口
ASP.NET Core 7 及更低版本 80
ASP.NET Core 8 及更高版本 8080

配置入口时,请将目标端口设置为与正在使用的容器映像对应的编号。

定义 X 转发标头

当入口处理原始 HTTP 请求时,应用会将入口视为客户端。 在某些情况下,应用需要知道原始客户端的 IP 地址或原始协议(HTTP 或 HTTPS)。 你可以通过请求的 X-Forwarded-* 标头访问协议和 IP 信息。

你可以通过访问 ForwardedHeaders 对象来从这些标头读取原始值。

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
});

有关使用请求标头的详细信息,请参阅配置 ASP.NET Core 以使用代理服务器和负载均衡器

生成云原生 .NET 应用程序

部署到容器应用的应用程序通常在基于云原生原则的基础上构建时效果最佳。 以下部分有助于详细说明有关云原生应用程序的常见问题。

应用程序配置

将 .NET 应用程序部署到 Azure 容器应用时,请使用环境变量来存储配置信息,而不是使用 appsettings.json。 通过这种做法,你可以在不同的环境中以不同方式配置应用程序。 此外,使用环境变量可以更轻松地管理配置值,而无需重新生成和重新部署容器映像。

在 Azure 容器应用中,你可以在定义应用或作业的容器时设置环境变量。 请将敏感值存储在机密中,并将其作为环境变量引用。 若要详细了解如何管理机密,请参阅在 Azure 容器应用中管理机密

托管的标识

Azure 容器应用支持托管标识,这允许应用访问其他 Azure 服务,而无需交换凭据。 若要详细了解如何在 Azure 服务之间安全通信,请参阅 Azure 容器应用中的托管标识

日志记录

在云原生环境中,日志记录对于监视和排查应用程序的问题至关重要。 默认情况下,Azure 容器应用使用 Azure Log Analytics 来从容器收集日志。 你也可以配置其他日志记录提供程序。

配置将日志写入控制台的日志记录提供程序后,Azure 容器应用会为你收集并存储日志消息。

运行状况探测

Azure 容器应用包括对运行状况探测的内置支持,可用于监视应用程序的运行状况。 如果某次探测确定应用程序处于不正常状态,则会自动重启容器。 若要详细了解运行状况探测,请参阅 Azure 容器应用中的运行状况探测

为了有机会实现用于确定应用程序运行状况的自定义逻辑,你可以配置运行状况检查终结点。 若要详细了解运行状况检查终结点,请参阅 ASP.NET Core 中的运行状况检查

自动缩放注意事项

默认情况下,Azure 容器应用会根据传入的 HTTP 请求数自动缩放 ASP.NET Core 应用。 你还可以根据其他指标(例如 CPU 或内存使用情况)配置自定义自动缩放规则。 若要了解有关缩放的详细信息,请参阅在 Azure 容器应用中设置缩放规则

在 .NET 8.0.4 及更高版本中,使用数据保护的 ASP.NET Core 应用会自动进行配置,以在应用程序缩放时,所有副本都能访问受保护的数据。 当应用开始缩放时,密钥管理器处理跨多个修订的写入和共享密钥。 部署应用时,环境变量 autoConfigureDataProtection 会自动设置为 true 以启用此功能。 有关此自动配置的详细信息,请参阅此 GitHub 拉取请求

自动缩放会根据定义的规则更改应用的副本数。 默认情况下,容器应用会将传入流量随机路由到 ASP.NET Core 应用的不同副本。 由于流量可以在不同的副本之间拆分,因此你的应用应该是无状态的,也就是说应用程序不会遇到与状态相关的问题。

防伪、身份验证、SignalR、Blazor Server 和 Razor Pages 等功能依赖于数据保护,在扩展到多个副本时,需要进行额外的配置才能正常使用。

配置数据保护

ASP.NET Core 具有保护和取消保护数据的特殊功能,例如会话数据和防伪令牌。 默认情况下,数据保护密钥存储在文件系统上,这不适合云原生环境。

如果要部署 .NET Aspire 应用程序,系统会自动为你配置数据保护。 在所有其他情况下,你需要手动配置数据保护

配置 ASP.NET Core SignalR

ASP.NET Core SignalR 需要使用一个底板来将消息分发到多个服务器副本。 将使用 SignalR 的 ASP.NET Core 应用部署到 Azure 容器应用时,必须配置受支持的底板之一,例如 Azure SignalR 服务或 Redis。 若要了解有关底板的详细信息,请参阅 ASP.NET Core SignalR 托管和缩放

配置 Blazor Server

ASP.NET Core Blazor Server 应用会将状态存储在服务器上,这意味着每个客户端在会话期间都必须连接到同一服务器副本。 将 Blazor Server 应用部署到 Azure 容器应用时,必须启用粘滞会话,以确保客户端路由到同一副本。 若要了解详细信息,请参阅 Azure 容器应用中的会话亲和性