Aspire 发布和部署概述

Aspire 将 生成部署资产 的行为与 执行部署分开。 Aspire CLI (aspire) 提供两个高级入口点:

  • aspire publish:为实现发布语义的一项或多项托管集成生成中间参数化资产。
  • aspire deploy:通过解析参数并将更改应用到目标环境来执行部署(集成实现部署语义时)。

这些命令提供对发布和部署功能的直接访问。 实际行为(生成的内容、部署发生方式)来自所引用 的托管集成 (例如: Docker、 Kubernetes、 Azure)。 系统 可扩展 - 可以生成插入同一模型的自己的发布或部署集成。

aspire publish 命令生成包含未解析的参数(占位符)的部署项目。 该 aspire deploy 命令使用这些工件,在目标集成支持时解析参数,然后执行部署。 某些集成不支持 deploy 该命令。

Aspire CLI 命令(概念性行为)

Command 它的作用是什么 输出 参数状态 需要集成功能
aspire publish 将应用程序模型转换为特定于集成的资产(撰写文件、清单、规范等)。 中间产物(不是直接生产最终成品)。 未解析(占位符,例如 ${VAR} 或类似)。 发布支持
aspire deploy 使用一个或多个集成运行部署(构建、参数解析、执行)。 实际资源/应用更改。 已解决 部署支持

如果集成未实现部署功能,aspire deploy 则不会部署该目标(可能会发出警告或不会执行操作)。

在没有支持发布的任何集成的情况下运行 aspire publish 时,你将看到:

Step 1: Analyzing model.

       ✗ FAILED: Analyzing the distributed application model for publishing and deployment capabilities. 00:00:00
           No resources in the distributed application model support publishing.

❌ FAILED: Analyzing model. completed with errors

同样,在没有支持部署的任何集成的情况下运行 aspire deploy 时,将看到此错误:

Step 1: Analyzing model.

       ✗ FAILED: Analyzing the distributed application model for publishing and deployment capabilities. 00:00:00
           No resources in the distributed application model support deployment.

❌ FAILED: Analyzing model. completed with errors

这些消息表示需要向 AppHost 项目添加托管集成。 托管集成是 NuGet 包(例如 Aspire.Hosting.DockerAspire.Hosting.KubernetesAspire.Hosting.Azure)为特定目标平台提供发布和部署功能。

参数占位符

已发布的资产特意包含占位符而非具体的数值。 对于 Docker 基于 Compose 的发布输出,参数化显示为标准环境变量引用。 例如,发布项目可能包括:

services:
  pg:
    image: "docker.io/library/postgres:17.6"
    environment:
      POSTGRES_HOST_AUTH_METHOD: "scram-sha-256"
      POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256 --auth-local=scram-sha-256"
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "${PG_PASSWORD}"
    ports:
      - "8000:5432"
    networks:
      - "aspire"
  dbsetup:
    image: "${DBSETUP_IMAGE}"
    environment:
      OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES: "true"
      OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES: "true"
      OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY: "in_memory"
      ASPNETCORE_FORWARDEDHEADERS_ENABLED: "true"
      HTTP_PORTS: "8001"
      ConnectionStrings__db: "Host=pg;Port=5432;Username=postgres;Password=${PG_PASSWORD};Database=db"
    ports:
      - "8002:8001"
      - "8004:8003"
    depends_on:
      pg:
        condition: "service_started"
    networks:
      - "aspire"

要点:

  • ${PG_PASSWORD}${DBSETUP_IMAGE} (和相似) 是已发布资产中的 占位符
  • aspire publish 期间,它们不会被解决。
  • 部署引擎(可能包括aspire deploydocker compose以及导出变量的脚本、CI/CD变量注入等功能)随后提供它们的值。
  • 这会使机密和环境特定的值与生成的结构分离。

不同的集成可能使用不同的占位符约定(环境变量、令牌或参数元数据),但原则保持不变:发布保留 形状,部署注入

发布者模型和计算环境

Aspire 使用灵活的发布者模型,用于在应用程序图中分发发布行为。 资源通过注释支持发布和部署:

此设计可实现混合部署和异类部署,其中同一应用中的不同服务可以部署到不同的目标(云、边缘、本地)。

计算环境

计算环境是一个核心部署概念,Aspire表示将部署应用程序资源的目标平台。 计算环境定义应如何转换资源以及应生成哪些部署项目。 内置计算环境的示例包括 Azure Container Apps 环境和 Docker Compose 环境。

计算资源 是应用程序的可运行部分,例如 .NET 需要部署到计算环境的项目、容器和可执行文件。

添加计算环境(如 Docker Compose 或 Kubernetes)时,Aspire 会将正确的发布行为自动应用于您的应用模型中的所有兼容计算资源,无需额外配置。

在多个环境中需要进行消除歧义的工作

如果添加多个计算环境, Aspire 则需要知道哪个资源将转到何处。 计算环境将其转换应用于所有适用的计算资源(项目、容器、可执行文件)。 如果多个环境与给定资源匹配, Aspire 则发布时引发不明确的环境异常。

可以使用 WithComputeEnvironment

var k8s = builder.AddKubernetesEnvironment("k8s-env");
var compose = builder.AddDockerComposeEnvironment("docker-env");

builder.AddProject<Projects.Frontend>("frontend")
    .WithComputeEnvironment(k8s);

builder.AddProject<Projects.Backend>("backend")
    .WithComputeEnvironment(compose);

此示例演示如何将服务显式映射到不同的计算环境。 例如,在Kubernetes的前端和在Docker Compose 的后端。

托管集成支持矩阵

集成包 目标 发布 Deploy 注释
Aspire.托管。Docker Docker / Docker Compose ✅ 是 ❌ 否 将生成的 Compose 与你自己的脚本或工具配合使用。
Aspire.托管。Kubernetes Kubernetes ✅ 是 ❌ 否 适用于 kubectl、GitOps 或其他控制器。
Aspire.Hosting.Azure.AppContainers Azure Container Apps ✅ 是 ✅ 是(预览版) 部署功能处于预览状态,可能会更改。
Aspire.Hosting.Azure.AppService Azure 应用服务 ✅ 是 ✅ 是(预览版) 部署功能处于预览状态,可能会更改。

小窍门

部署支持与集成相关。 缺乏部署支持意味着需要使用外部工具处理发布的制品。

典型工作流

1.生成工件(任何集成)

aspire publish -o artifacts/

查看 构件/ 的内容 (例如: Docker Compose文件、 Kubernetes 清单文件、 Azure 规范文档等)。

2.在本地运行(Docker 示例)

# Provide or export required environment variables, then:
docker compose -f artifacts/docker-compose.yml up --build

缺少的变量(如 PG_PASSWORD)必须在 shell、 .env 文件中设置,或由您选择的运行器注入。

3. 使用 aspire deploy

如果集成支持部署,可以运行:

aspire deploy

这会解析参数,并为支持部署的集成应用部署更改。

可扩展性

命令aspire publishaspire deploy通过可添加到资源的批注支持可扩展工作流。 此功能以预览版提供,将来的版本中可能会更改。

自定义发布和部署回调

资源通过注释支持自定义发布和部署行为:

以下示例演示如何使用 DeployingCallbackAnnotation 注册自定义部署行为:

#pragma warning disable ASPIREPUBLISHERS001
#pragma warning disable ASPIREINTERACTION001

using Aspire.Hosting.Publishing;
using Microsoft.Extensions.DependencyInjection;

var builder = DistributedApplication.CreateBuilder(args);

// Custom deployment step defined below
builder.AddDataSeedJob("SeedInitialData", seedDataPath: "data/seeds");

builder.Build().Run();

internal class DataSeedJobResource([ResourceName] string name, string seedDataPath)
    : Resource(name)
{
    public string SeedDataPath { get; } = seedDataPath;
}

internal static class DataSeedJobResourceBuilderExtensions
{
    public static IResourceBuilder<DataSeedJobResource> AddDataSeedJob(
        this IDistributedApplicationBuilder builder,
        string name,
        string seedDataPath = "data/seeds")
    {
        var job = new DataSeedJobResource(name, seedDataPath);
        var resourceBuilder = builder.AddResource(job);

        // Attach a DeployingCallbackAnnotation that will be invoked on `aspire deploy`
        job.Annotations.Add(new DeployingCallbackAnnotation(async ctx =>
        {
            CancellationToken ct = ctx.CancellationToken;

            // Prompt the user for a confirmation using the interaction service
            var interactionService = ctx.Services.GetRequiredService<IInteractionService>();

            var envResult = await interactionService.PromptInputAsync(
                "Environment Configuration",
                "Please enter the target environment name:",
                new InteractionInput
                {
                    Label = "Environment Name",
                    InputType = InputType.Text,
                    Required = true,
                    Placeholder = "dev, staging, prod"
                },
                cancellationToken: ct);

            // Custom deployment logic here
            var reporter = ctx.ActivityReporter;
            await using (var deployStep = await reporter.CreateStepAsync(
                $"Deploying data seed job to {envResult.Value}", ct))
            {
                // Simulate deployment work
                await Task.Delay(2000, ct);
                await deployStep.SucceedAsync("Data seed job deployed successfully", ct);
            }
        }));

        return resourceBuilder;
    }
}

此自定义部署逻辑与aspire deploy命令无缝集成,提供交互式提示和进度报告。 有关详细信息,请参阅 .. 中的Aspire资源注释

诊断和审核

发布使您能够在机密数据出现前获取预期结构的不可变快照。 您可以:

  • 在提交之间比较已发布输出的差异。
  • 扫描不被允许的图像或配置。
  • 保留合规性记录,然后单独记录部署时应用的已解决集合。

其他工具

Azure Developer CLI(azd

Azure Developer CLI (azd) 对部署 Aspire 项目具有一流的支持。 它可以预配基础结构、管理环境并协调机密/值注入。 可以将发布项目合并 Aspire 到 azd 工作流中,也可以直接使用 Azure 集成(预览版)。

部署清单

从 Aspire 9.2 开始,清单格式逐步被淘汰,转而支持Aspire 使用 CLI 发布和部署命令以及 API,以定义发布和部署功能。 早期工作流强调从专用 AppHost 目标生成的单个“部署清单”。 新式方法以 + 集成扩展性为 aspire publish 中心。 旧清单格式 不会进一步演变,但仍可以生成它进行检查或调试:

aspire publish --publisher manifest -o diagnostics/

这:

  • 生成可用于了解资源图或故障排除的清单快照。
  • 不应被视为主部署协定。
  • 仅用于保证向后兼容和提高调试可见性。

关键结论

首先发布,然后是部署,它将结构与值分开。 发布过程中生成的工件是参数化的,解析工作将在稍后进行。 特定的集成决定了发布和部署的实际行为,并且系统设计为可扩展,使你能够生成面向新平台或内部工具的自定义集成。 虽然旧清单仍可生成,但它仍然是静态的,并且不再不断发展。

另请参阅