news 2026/9/17 21:46:12

Aspire Azure Container Apps 托管集成:环境建模、计算资源编排与发布部署实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Aspire Azure Container Apps 托管集成:环境建模、计算资源编排与发布部署实战指南

Aspire Azure Container Apps 托管集成:环境建模、计算资源编排与发布部署实战指南

【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire

导读

Aspire.Hosting.Azure.AppContainers是 Aspire 用于建模、配置和编排 Azure Container Apps 环境的托管集成。本文基于该集成在仓库中的 README.md 展开,并结合 AzureContainerAppExtensions.cs、AzureContainerAppContainerExtensions.cs 等源码实现与 AzureContainerAppEnvironmentExtensionsTests.cs 测试用例,系统讲解如何用一行 API 在 Aspire 解决方案中声明 Container Apps 环境、把 Dockerfile/项目/可执行程序发布为容器应用、定制入站流量与命名约定,并通过aspire publish/aspire deploy完成从 Bicep 生成到真实资源预配的完整链路。读完本文,你将掌握该集成的全部核心 API、默认基础设施模型、常见定制手段及部署/清理的实战方法。

一、集成概览:一条语句构建云原生应用环境

该集成允许在 Aspire AppHost 的编程模型中"声明式"地定义一个 Azure Container Apps 环境,并把解决方案中的计算资源(Dockerfile 容器、.NET 项目、可执行程序)自动映射为该环境内的 Container App。它位于 src/Aspire.Hosting.Azure.AppContainers/ 目录,核心类型包括:

文件职责
AzureContainerAppExtensions.cs环境资源的入口AddAzureContainerAppEnvironment,以及命名、Dashboard、日志、拉取身份等定制 API
AzureContainerAppEnvironmentResource.cs环境资源模型,实现IAzureComputeEnvironmentResourceIContainerRegistry等接口
AzureContainerAppContainerExtensions.cs将容器资源发布为 Container App
AzureContainerAppProjectExtensions.cs将项目资源发布为 Container App
AzureContainerAppExecutableExtensions.cs将可执行程序资源发布为 Container App
ContainerAppContext.cs单个 Container App 的构建逻辑:端点、环境变量、密钥、卷、探针
ContainerAppEnvironmentContext.cs环境级上下文:为每个计算资源创建 Container App
AzureContainerAppScaleConfig.cs缩放配置模型
AzureContainerAppJobCustomizationAnnotation.csContainer App Job 定制标注

从源码结构看,该集成基于 Azure.Provisioning(CDK)构建:环境资源继承自AzureProvisioningResource,通过回调把 Azure 资源(托管环境、容器注册表、Log Analytics 工作区、托管标识等)编译为 Bicep 模块,再交由 Aspire 的部署管线执行。

二、快速开始:前置条件与安装集成

2.1 前置条件

  • 一个 Aspire AppHost 项目,以及可用的容器运行时(如 Docker),用于构建和运行容器镜像;
  • 若要部署到 Azure:需要一个有权创建资源并分配角色的 Azure 订阅,并且已通过az login完成 Azure CLI 登录。

2.2 添加集成

在 AppHost 目录下使用 Aspire CLI 添加集成包:

aspire add Aspire.Hosting.Azure.AppContainers

添加完成后,AppHost 项目中即可引用Aspire.Hosting.Azure.AppContainers命名空间下(对外暴露于Aspire.Hosting命名空间)的扩展方法。

三、最小可用示例:一个环境 + 一个 Web 应用

README 给出的最小示例用核心AddDockerfileAPI 声明一个 HTTP 应用(监听8080端口),并放入一个名为env的 Container Apps 环境。前提是 AppHost 目录下存在web子目录,其中包含构建该 HTTP 应用的 Dockerfile。

C#(AppHost/Program.cs)

using Aspire.Hosting; var builder = DistributedApplication.CreateBuilder(args); builder.AddAzureContainerAppEnvironment("env"); builder.AddDockerfile("web", "web") .WithHttpEndpoint(targetPort: 8080) .WithExternalHttpEndpoints(); builder.Build().Run();

TypeScript(apphost.mts)

import { createBuilder } from './.aspire/modules/aspire.mjs'; const builder = await createBuilder(); await builder.addAzureContainerAppEnvironment("env"); await builder.addDockerfile("web", "web") .withHttpEndpoint({ targetPort: 8080 }) .withExternalHttpEndpoints(); await builder.build().run();

3.1 行为要点

  • 自动归属:当解决方案中存在一个环境时,受支持的计算资源会被自动分配到该环境,无需显式指定;
  • PublishAsAzureContainerApp是可选的:它只用于"定制"生成的 Container App(见下文第五节)。如果无需定制,声明 Dockerfile/项目后就会自动以默认方式发布;
  • 默认内网:HTTP 端点默认是内部(internal)的,WithExternalHttpEndpoints显式把该 Web 应用纳入公共入站(ingress)流量;
  • 本地运行不预配:本地dotnet run时不会创建真实的 Container Apps 环境(源码中AddAzureContainerAppEnvironment在 Run 模式下仅返回资源构建器,不把资源加入模型,见 AzureContainerAppExtensions.cs)。

从实现看,AddAzureContainerAppEnvironment("env")会同步创建默认的 Azure Container Registry(命名为env-acr)并绑定到环境(AzureContainerAppExtensions.cs),后续发布的计算资源镜像都推送到该注册表。

四、AddAzureContainerAppEnvironment的默认基础设施模型

调用AddAzureContainerAppEnvironment(name)时,Aspire 会在生成 Bicep 时自动预配以下整套 Azure 基础设施(见 AzureContainerAppExtensions.cs):

资源默认命名说明
Azure Container Registry{env}-acr存放所有容器镜像,同时输出AZURE_CONTAINER_REGISTRY_NAME/AZURE_CONTAINER_REGISTRY_ENDPOINT
User-Assigned 托管标识{env}_mi用于从 ACR 拉取镜像(AcrPull),输出AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID
ACR AcrPull 角色分配ContainerRegistryBuiltInRole.AcrPull授予上述标识
Log Analytics 工作区{env}_lawSku 为PerGB2018,供环境日志收集,输出AZURE_LOG_ANALYTICS_WORKSPACE_NAME/AZURE_LOG_ANALYTICS_WORKSPACE_ID
Container App 托管环境{env}Workload Profiles 默认仅含Consumption档;日志目标为 log-analytics
Aspire Dashboard 组件aspire-dashboard类型AspireDashboard,版本2025-10-02-preview,默认启用

4.1 关键输出参数

环境模块统一输出以下标准参数,供下游 Container App 与 azd 消费(见AddSharedContainerAppEnvironmentOutputs,AzureContainerAppExtensions.cs):

  • AZURE_CONTAINER_REGISTRY_NAME
  • AZURE_CONTAINER_REGISTRY_ENDPOINT
  • AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID
  • AZURE_CONTAINER_APPS_ENVIRONMENT_NAME
  • AZURE_CONTAINER_APPS_ENVIRONMENT_ID
  • AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN(azd 输出 Dashboard 地址时使用)

4.2 每个 Container App 的构建流程

AzureContainerAppEnvironmentResource注册了两个管线步骤:prepare-azure-container-apps-{name}(在 BeforeStart 阶段为所有计算资源物化部署目标)和可选的print-dashboard-url-{name}(部署成功后打印 Dashboard 地址),见 AzureContainerAppEnvironmentResource.cs。

对每个计算资源,ContainerAppEnvironmentContext.CreateContainerAppAsync会创建对应的ContainerAppContext(ContainerAppEnvironmentContext.cs),随后在ContainerAppContext.BuildContainerApp中完成:

  • 解析所有端点并生成 ingress 配置;
  • 注入环境变量与命令行参数(含密钥映射);
  • 若资源带有AppIdentityAnnotation,为 Container App 附加用户分配的托管标识;
  • 挂载卷(Azure Files 存储);
  • 映射探针(Startup/Readiness/Liveness);
  • 最后执行用户通过PublishAsAzureContainerApp提供的定制回调。

五、发布计算资源:Project / Container / Executable 三种载体

当解决方案中有多个环境,或需要对默认生成的 Container App 做定制时,使用PublishAsAzureContainerApp。该系列 API 有三个重载,分别面向不同类型的资源:

项目资源(ProjectResource)

builder.AddProject<Projects.Api>() .PublishAsAzureContainerApp((infrastructure, app) => { // 在这里定制生成的 ContainerApp });

容器资源(ContainerResource)

builder.AddContainer("name", "image") .PublishAsAzureContainerApp((infrastructure, app) => { // 例如配置自定义环境变量、缩放规则等 });

可执行程序资源(ExecutableResource,通常与 Dockerfile 配合)

builder.AddDockerfile("web", "web") .PublishAsAzureContainerApp((infrastructure, app) => { // 定制 ContainerApp });

5.1 实现要点

从源码看,这三个扩展方法的行为完全一致(AzureContainerAppProjectExtensions.cs):

  1. 仅在发布模式生效if (!project.ApplicationBuilder.ExecutionContext.IsPublishMode) return project;——本地运行(run 模式)时调用该方法不会产生任何副作用;
  2. 调用AddAzureContainerAppsInfrastructureCore()注册基础设施(幂等,多次调用只注册一次全局校验步骤,见 AzureContainerAppExtensions.cs);
  3. 把定制回调封装为AzureContainerAppCustomizationAnnotation标注附加到资源上,最终在ContainerAppContext.BuildContainerApp末尾执行(ContainerAppContext.cs)。

5.2 项目资源的默认行为

  • 对 .NET 项目,Aspire 默认启用AutoConfigureDataProtection(需要2025-10-02-preview资源版本),见 ContainerAppContext.cs;
  • 对带AzureFunctionsAnnotation的资源,默认将Kind设为Functionapp,适配 Azure Functions 部署。

六、端点与入站流量控制

6.1 HTTP 端点默认升级为 HTTPS

默认情况下,环境会把所有 HTTP 端点升级为 HTTPS(443 端口)。原因在源码注释中说明:HTTP 到 HTTPS 的重定向会破坏 WebSocket 升级(ContainerAppContext.cs)。部署时日志会汇总被升级的端点(如web:http),提示可通过.WithHttpsUpgrade(false)关闭(ContainerAppEnvironmentContext.cs)。

关闭 HTTPS 升级(保留 HTTP 80)

builder.AddAzureContainerAppEnvironment("env") .WithHttpsUpgrade(upgrade: false);

注意:即便关闭升级,显式指定的开发端口(如 8080)仍会按 Azure Container Apps 的要求规范化为标准端口 80/443(见 AzureContainerAppExtensions.cs 的 XML 注释)。

6.2 端点类型约束

ContainerAppContext.ProcessEndpoints会校验端点定义(ContainerAppContext.cs):

  • 仅支持httphttp2tcp三种传输层协议,其他传输会抛出NotSupportedException
  • 最多一个外部端点,且外部端点必须为 HTTP(S)(外部 TCP 端点不支持);
  • 同一目标端口上不允许混用 HTTP 与 TCP;
  • 有多个 HTTP 端点时,优先选择外部端点作为 ingress,其余作为附加 TCP 端口映射(AdditionalPortMappings,内网);
  • 附加端口超过 5 个时会输出警告(参考 Azure 关于 TCP ingress 的文档)。

6.3 内部/外部地址表达式

环境实现了GetHostAddressExpression,为内部端点生成<name>.internal.<domain>形式的地址、外部端点生成<name>.<domain>形式(AzureContainerAppEnvironmentResource.cs),应用之间可通过标准 Aspire 端点引用互访。

七、命名约定:azd 对齐、唯一命名与紧凑命名

当应用最初由 azd 部署、或需要把多个环境部署到同一资源组时,命名策略至关重要。源码中针对 managed environment 名称做了专门的碰撞防护(详见 AzureContainerAppExtensions.cs 及 ManagedEnvironmentNameResolver)。

7.1 WithAzdResourceNaming

让环境资源与 azd 使用完全相同的命名约定,从而复用 azd 已部署的资源:

builder.AddAzureContainerAppEnvironment("env") .WithAzdResourceNaming();

启用后,托管环境命名为cae-${uniqueString(resourceGroup().id)},标识为mi-${resourceToken}、注册表为acr-…、Log Analytics 为law-${resourceToken}(AzureContainerAppExtensions.cs)。

7.2 WithUniqueResourceNaming

解决同一资源组内多个环境命名塌缩的问题。默认情况下 Azure.Provisioning 对ContainerAppManagedEnvironment只保留小写字母,cae1cae2会被清洗成同一个cae,进而碰撞到同一个物理环境(对应 issue #18722)。启用该方法后,名称算法改为"清洗后的资源名 + 连字符 + uniqueString,截断到 60 字符",例如cae1生成take('cae1-${uniqueString(resourceGroup().id)}', 60),保留数字从而区分彼此:

var env1 = builder.AddAzureContainerAppEnvironment("cae1").WithUniqueResourceNaming(); var env2 = builder.AddAzureContainerAppEnvironment("cae2").WithUniqueResourceNaming();

该方法为可选(opt-in),因为它会改变已部署单环境的名称并导致 Azure 重建环境;通常只对"多个环境共享一个资源组"的部署使用,或用于全新部署。若两个环境最终解析到相同名称,publish/deploy 阶段会以明确的错误提示要求调用此方法。

7.3 WithCompactResourceNaming

针对卷相关存储资源(Storage Account / File Share)的命名优化。默认生成的名称使用较长的静态后缀(如storageVolumemanagedStorage),会吃掉存储账号 24 字符名称上限的大部分空间,截断提供跨部署唯一性的uniqueString。启用后缩短静态部分,完整保留 13 字符的uniqueString,避免向不同资源组部署多个环境时发生命名冲突:

builder.AddAzureContainerAppEnvironment("env") .WithCompactResourceNaming();

该方法仅影响卷相关存储资源的命名,不改变托管环境、注册表、Log Analytics 或托管标识的名称;该 API 带有Experimental("ASPIREACANAMING001")实验性标记,接口可能在未来版本调整。

八、高级定制选项

8.1 控制 Aspire Dashboard

环境中默认附带 Aspire Dashboard(aspire-dashboard组件,2025-10-02-preview)。可通过以下方式开关:

builder.AddAzureContainerAppEnvironment("env") .WithDashboard(enable: false); // 默认 true

部署后 Dashboard 地址为https://aspire-dashboard.ext.<default-domain>,仅在 Dashboard 启用时才会注册打印 URL 的摘要步骤(AzureContainerAppEnvironmentResource.cs)。

8.2 使用现有的 Log Analytics 工作区

默认环境会新建{env}_law工作区。若希望复用已有工作区:

builder.AddAzureLogAnalyticsWorkspace("logs"); builder.AddAzureContainerAppEnvironment("env") .WithAzureLogAnalyticsWorkspace(logsBuilder);

实现上通过AzureLogAnalyticsWorkspaceReferenceAnnotation标注引用现有工作区(AzureContainerAppExtensions.cs)。

8.3 自定义 ACR 拉取身份(WithAcrPullIdentity)

默认环境会创建新的用户分配标识并授予 AcrPull。若希望使用自己提供的用户分配标识(例如配合AsExisting复用既有资源,且不产生任何新的标识/角色资源):

builder.AddAzureUserAssignedIdentity("acrPullIdentity") .WithRoleAssignments(acr, ContainerRegistryBuiltInRole.AcrPull); builder.AddAzureContainerAppEnvironment("env") .WithAcrPullIdentity(acrPullIdentityBuilder);

注意:该方法中的标识仅用于 ACR 拉取(AcrPull 角色),并不会被附加到环境中的单个 Container App 上;调用方需自行保证该标识已具备 AcrPull 权限(AzureContainerAppExtensions.cs)。

8.4 引用已存在的环境(AsExisting / PublishAsExisting)

当环境被标记为AsExisting时,Aspire 不会生成新的托管环境、Log Analytics 工作区或 Dashboard 组件,而是生成一个引用现有环境的薄模块,并只补充新部署 Container App 所需的 ACR 拉取标识(AzureContainerAppExtensions.cs)。此时以下组合不被允许,会直接抛错:

  • 声明了卷挂载(卷需要在托管环境上预配存储);
  • 通过WithDelegatedSubnet配置了 VNet 集成(VNet 是环境自身的属性,无法对已存在环境重新配置);
  • 通过WithAzureLogAnalyticsWorkspace指定工作区(已存在环境已拥有自己的日志工作区)。

8.5 卷挂载与探针

  • :资源通过标准挂载 API(BindMount / Volume)声明后,环境会自动创建 Storage Account(StandardLRS、StorageV2、启用大文件共享、最低 TLS 1.2)与 Azure Files 文件共享,并以ContainerAppManagedEnvironmentStorage(AzureFile,读写模式)挂载到环境(AzureContainerAppExtensions.cs);
  • 探针ContainerAppContext.AddProbes会把ProbeAnnotation(Startup/Readiness/Liveness)映射为 ACA 探针;关联到 ingress 端点的探针强制使用http协议、目标端口(BaseContainerAppContext.cs)。

8.6 环境变量与密钥

BaseContainerAppContext.ProcessValue负责把值转换为 Bicep 表达式(BaseContainerAppContext.cs):

  • 普通字符串直接作为环境变量值;
  • 端点引用解析为容器应用域名地址;
  • ParameterResource若标记为 Secret,则注册为 Container App 密钥(SecretRef),密钥名由_-并小写;
  • Key Vault 引用注册为 Key Vault 密钥引用,并可选附加标识用于访问;
  • 不支持的引用类型(如自动 Key Vault 生成)会明确抛错,提示手动创建 Key Vault 资源。

九、发布与部署:publish / deploy / destroy 完整闭环

9.1 aspire publish:生成部署产物(不触碰 Azure)

aspire publish
  • 生成 Bicep 模板与参数化的部署产物,但不会预配任何 Azure 资源;
  • 产物默认写入 AppHost 的aspire-output目录;
  • 交互式部署过程中可提示选择订阅、位置与资源组。

9.2 aspire deploy:实际预配与部署

aspire deploy
  • 解析 Azure 设置与参数;
  • 预配 Container Apps 环境及其默认容器注册表;
  • 构建并推送镜像;
  • 部署应用。

9.3 aspire destroy:清理

aspire destroy

注意:该命令会删除整个部署资源组,包括并非由 Aspire 创建的资源!请仅在确认无误后执行。

9.4 安全提示

  • 本地运行不会预配 Container Apps 环境;
  • 部署后的应用通过托管标识(managed identity)拉取镜像,不依赖明文凭证;
  • 敏感配置应放在 secret 参数或 Azure Key Vault 引用中,而不是明文环境变量。

十、测试验证与延伸阅读

该集成的行为在仓库中有较完整的测试覆盖,可作为自定义配置时的参考依据:

  • AzureContainerAppEnvironmentExtensionsTests.cs:覆盖环境资源默认生成、WithAzdResourceNaming/WithCompactResourceNaming/WithUniqueResourceNaming命名策略、AsExisting引用现有环境等场景;
  • AzureContainerAppsTests.cs:覆盖 Container App 发布与 Bicep 生成。

更多相关背景可继续阅读仓库内文档:docs/specs/aks-support.md(多计算环境编排的设计背景)、docs/azure.md(Azure 相关概览)。若需在生产中落地,请以当前仓库版本的 API 签名与实验性标记为准(部分命名 API 标有Experimental特性,后续版本可能调整)。

【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 21:43:11

五分钟搭起 C++ HTTP 服务:单文件库 cpp-httplib 实战

五分钟搭起 C HTTP 服务&#xff1a;单文件库 cpp-httplib 实战 【免费下载链接】cpp-httplib A C header-only HTTP/HTTPS server and client library 项目地址: https://gitcode.com/GitHub_Trending/cp/cpp-httplib cpp-httplib 是一个单文件、header-only 的 C11 HT…

作者头像 李华
网站建设 2026/9/17 21:42:11

LoRA微调DeepSeek实现医疗辅助诊断的完整指南

简介&#xff1a;面向医疗AI工程师、算法研究员与医疗信息化从业者&#xff0c;这份技术文档聚焦如何利用LoRA低成本微调DeepSeek模型&#xff0c;打造高精度医疗辅助诊断系统。压缩包内仅包含1个PDF文件&#xff0c;共26页&#xff0c;体积约1.84MB&#xff0c;页面文字、图表…

作者头像 李华
网站建设 2026/9/17 21:37:41

Windows批量重命名实战:用bat脚本一键处理跨目录同名文件

做素材整理的时候&#xff0c;我经常遇到这种局面&#xff1a;几十个项目文件夹里都躺着一个config.ini或者readme.txt&#xff0c;内容各不相同&#xff0c;但文件名永远一样。平时看没问题&#xff0c;真要批量归档、统一管理的时候就头大了——总不能一个一个文件夹点进去手…

作者头像 李华