你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Azure 容器应用中托管 Durable Functions 应用(.NET 隔离)

Azure Functions 为在 Azure 容器应用中开发、部署和管理容器化函数应用提供集成支持。 如果需要与其他微服务、API、网站、工作流或任何容器托管程序在同一环境中运行,请使用 Functions 应用的 Azure 容器应用。 详细了解 如何在容器应用中运行 Azure Functions

注释

虽然 Durable Functions 支持多个 存储提供程序后端,但 Azure 容器应用中托管的自动缩放应用仅适用于 Microsoft SQL (MSSQL) 后端。 如果使用另一个后端,则必须将最小副本计数设置为大于零。

在这篇文章中,你将学会如何:

  • 从本地 Durable Functions 项目创建 Docker 镜像。
  • 创建 Azure 容器应用和相关资源。
  • 将映像部署到 Azure 容器应用并设置身份验证。

先决条件

创建本地 Durable Functions 项目

在 Visual Studio Code 中, 创建配置为使用 MSSQL 后端的 .NET 隔离 Durable Functions 项目

在本地测试应用 并返回到本文。

在项目根目录中创建 Dockerfile ,描述在容器中运行函数应用所需的最低环境。

  1. 在项目根目录中,创建名为 Dockerfile 的新文件。

  2. 将以下内容复制/粘贴到 Dockerfile 中。

    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS installer-env
    
    COPY . /src/dotnet-function-app
    RUN cd /src/dotnet-function-app && \
    mkdir -p /home/site/wwwroot && \
    dotnet publish *.csproj --output /home/site/wwwroot
    
    # To enable ssh & remote debugging on app service change the base image to the one below
    # FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0-appservice
    FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0
    ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
        AzureFunctionsJobHost__Logging__Console__IsEnabled=true
    
    COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]
    
  3. 保存文件。

  4. 添加包含以下内容的 .dockerignore 文件:

    local.settings.json
    
  5. 保存 .dockerignore 文件。

构建容器映像

生成 Docker 映像。 在Microsoft 的 Docker Hub 中找到 Azure Functions 支持的基础映像的完整列表 | Azure Functions Base

  1. 启动 Docker 守护程序。

  2. 使用 docker login 命令登录到 Docker。

  3. 出现提示时,请使用用户名和密码登录。 “登录成功”消息确认已登录。

  4. 导航到项目根目录。

  5. 运行以下命令以生成映像,并将其 <DOCKER_ID> 替换为 Docker 中心帐户 ID:

    dockerId=<DOCKER_ID>
    imageName=IMAGE_NAME>
    imageVersion=v1.0.0
    
    docker build --tag $dockerId/$imageName:$imageVersion .
    

    注释

    如果要在 M 系列 Mac 上运行,请改用 --platform linux/amd64

  6. 将映像推送到 Docker:

    docker push $dockerId/$imageName:$imageVersion
    

    根据网络速度,初始映像推送可能需要几分钟时间。 在等待时,请转到下一部分。

创建 Azure 资源

创建在容器应用上运行 Durable Functions 所需的 Azure 资源。

  • Azure 资源组: 包含所有已创建资源的资源组。
  • Azure 容器应用环境: 托管容器应用的环境。
  • Azure 容器应用: 包含 Durable Functions 应用的图像将部署到此应用。
  • Azure 存储帐户: 函数应用需要存储与应用相关的数据,例如应用程序代码。

初始设置

  1. 在新终端中,登录到 Azure 订阅:

    az login  
    
    az account set -s <subscription_name>
    
  2. 运行所需的命令以设置 Azure 容器应用 CLI 扩展:

    az upgrade
    
    az extension add --name containerapp --upgrade
    
    az provider register --namespace Microsoft.App
    
    az provider register --namespace Microsoft.OperationalInsights
    

工作负荷配置文件确定可用于环境中部署的容器应用的计算和内存资源量。 创建消耗载荷配置文件,用于缩放到零的支持和按使用付费。

  1. 设置环境变量。

    ___location=<REGION>
    resourceGroup=<RESOURCE_GROUP_NAME>
    storage=<STORAGE_NAME>
    containerAppEnv=<CONTAINER_APP_ENVIRONMNET_NAME>
    functionApp=<APP_NAME>
    vnet=<VNET_NAME>
    
  2. 创建资源组。

    az group create --name $resourceGroup --___location $___location
    
  3. 创建容器应用环境。

    az containerapp env create \
      --enable-workload-profiles \
      --resource-group $resourceGroup \
      --name $containerAppEnv \
      --___location $___location \
    
  4. 基于 Durable Functions 映像创建容器应用。

    az containerapp create --resource-group $resourceGroup \
    --name $functionApp \
    --environment $containerAppEnv \
    --image $dockerId/$imageName:$imageVersion \
    --ingress external \
    --kind functionapp \
    --query properties.outputs.fqdn
    
  5. 记下应用 URL,该 URL 应类似于 https://<APP_NAME>.<ENVIRONMENT_IDENTIFIER>.<REGION>.azurecontainerapps.io

创建数据库

  1. 创建函数应用所需的 Azure 存储帐户。

    az storage account create --name $storage --___location $___location --resource-group $resourceGroup --sku Standard_LRS
    
  2. 在 Azure 门户中, 创建一个 Azure SQL 数据库 来保存状态信息。 在创建过程中:

    • 启用 Azure 服务和资源以访问此服务器(在 网络下)
    • 数据库排序规则 的值(在 “其他设置”下)设置为 Latin1_General_100_BIN2_UTF8

注释

不要为生产方案启用 “允许 Azure 服务和资源”访问此服务器 设置。 生产应用程序应实现更安全的方法,例如更强的防火墙限制或虚拟网络配置。

配置基于标识的身份验证

托管标识通过消除应用中的机密(例如连接字符串中的凭据)使应用更安全。 虽然可以在 系统分配的托管标识和用户分配的托管标识之间进行选择,但建议使用用户分配的托管标识,因为它未绑定到应用生命周期。

在本部分中,为 Azure 存储设置 用户分配的托管标识

  1. 设置环境变量。

    subscription=<SUBSCRIPTION_ID>
    identity=<IDENTITY_NAME>
    
  2. 创建托管标识资源。

    echo "Creating $identity"
    az identity create -g $resourceGroup -n $identity --___location "$___location"
    
  3. 将用户标识分配给容器应用。

    echo "Assigning $identity to app"
    az containerapp identity assign --resource-group $resourceGroup --name $functionApp --user-assigned $identity
    
  4. 设置基于角色的访问控制(RBAC)权限的范围。

    scope="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.Storage/storageAccounts/$storage"
    
  5. 获取用户标识的 clientId

    # Get the identity's ClientId 
    clientId=$(az identity show --name $identity --resource-group $resourceGroup --query 'clientId' --output tsv)
    
  6. 分配“存储 Blob 数据所有者”角色以访问存储帐户

    echo "Assign Storage Blob Data Owner role to identity"
    az role assignment create --assignee "$clientId" --role "Storage Blob Data Owner" --scope "$scope"
    

设置应用设置

注释

在 Azure 容器应用中托管 Durable Functions 应用时,不支持使用托管标识对 MSSQL 数据库进行身份验证。 目前,本指南使用连接字符串进行身份验证。

  1. 在 Azure 门户中的 SQL 数据库资源中,导航到“设置>”以查找连接字符串。

    显示数据库连接字符串的屏幕截图。

    连接字符串的格式应类似于:

    dbserver=<SQL_SERVER_NAME>
    sqlDB=<SQL_DB_NAME>
    username=<DB_USER_LOGIN>
    password=<DB_USER_PASSWORD>
    
    connStr="Server=tcp:$dbserver.database.windows.net,1433;Initial Catalog=$sqlDB;Persist Security Info=False;User ID=$username;Password=$password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
    

    如果忘记了上一个数据库创建步骤中的密码,则可以在 SQL Server 资源上重置密码。

    显示重置密码按钮的屏幕截图。

  2. 将 SQL 数据库的连接字符串存储为容器应用中名为 sqldbconnection机密

    az containerapp secret set \
    --resource-group $resourceGroup \
    --name $functionApp \
    --secrets sqldbconnection=$connStr
    
  3. 将以下设置添加到应用:

    az containerapp update \
    -n $functionApp \
    -g $resourceGroup \
    --set-env-vars SQLDB_Connection=secretref:sqldbconnection \
    AzureWebJobsStorage__accountName=$storage \
    AzureWebJobsStorage__clientId=$clientId \
    AzureWebJobsStorage__credential=managedidentity \
    FUNCTIONS_WORKER_RUNTIME=dotnet-isolated
    

本地测试

  1. 使用 HTTP 测试工具将请求发送到 POST HTTP 触发器终结点,该终结点应类似于:

    https://<APP NAME>.<ENVIRONMENT_IDENTIFIER>.<REGION>.azurecontainerapps.io/api/DurableFunctionsOrchestrationCSharp1_HttpStart
    

    响应是 HTTP 函数的初始结果,让你知道 Durable Functions 业务流程已成功启动。 虽然响应包含一些有用的 URL,但它尚未显示业务流程的最终结果。

  2. 将 URL 值 statusQueryGetUri 复制/粘贴到浏览器的地址栏中并执行。 或者,可以继续使用 HTTP 测试工具发出 GET 请求。

    请求将查询业务流程实例的状态。 应会看到实例已完成以及 Durable Functions 应用的输出或结果。

    {
        "name":"HelloCities",
        "instanceId":"7f99f9474a6641438e5c7169b7ecb3f2",
        "runtimeStatus":"Completed",
        "input":null,
        "customStatus":null,
        "output":"Hello, Tokyo! Hello, London! Hello, Seattle!",
        "createdTime":"2023-01-31T18:48:49Z",
        "lastUpdatedTime":"2023-01-31T18:48:56Z"
    }
    

后续步骤

了解有关以下方面的详细信息: