Condividi tramite


Ospitare un'app Durable Functions in App contenitore di Azure (.NET isolato)

Azure Functions offre supporto integrato per lo sviluppo, la distribuzione e la gestione di app per funzioni containerizzate su Azure Container Apps. Usare Azure Container Apps per le Function Apps quando è necessario operare nello stesso ambiente di altri microservizi, API, siti web, flussi di lavoro o qualsiasi programma ospitato in contenitori. Altre informazioni sull'esecuzione di Funzioni di Azure in App contenitore.

Annotazioni

Anche se Durable Functions supporta diversi provider di archiviazione o backends, la scalabilità automatica delle app ospitate in Azure Container Apps è disponibile solo con il back-end Microsoft SQL (MSSQL). Se viene usato un altro back-end, è necessario impostare il numero minimo di repliche su maggiore di zero.

In questo articolo vengono illustrate le operazioni seguenti:

  • Creare un'immagine Docker da un progetto Durable Functions locale.
  • Creare un Azure Container App e le risorse correlate.
  • Distribuire l'immagine nell'app Azure Container e configurare l'autenticazione.

Prerequisiti

Creare un progetto Durable Functions locale

In Visual Studio Code crea un progetto di Funzioni Durabili isolate .NET configurato per utilizzare la piattaforma backend MSSQL.

Testare l'app in locale e tornare a questo articolo.

Creare un Dockerfile nella radice del progetto che descrive l'ambiente minimo necessario per eseguire l'app per le funzioni in un contenitore.

  1. Nella directory radice del progetto creare un nuovo file denominato Dockerfile.

  2. Copiare/incollare il contenuto seguente nel 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. Salva il file.

  4. Aggiungere un file con estensione dockerignore con il contenuto seguente:

    local.settings.json
    
  5. Salva il file .dockerignore.

Compilare l'immagine del contenitore

Compilare l'immagine Docker. Trova l'elenco completo delle immagini di base supportate per le Funzioni Azure di Microsoft in Azure Functions Base | Docker Hub

  1. Avviare il daemon Docker.

  2. Accedere a Docker con il docker login comando .

  3. Quando richiesto, accedere con il nome utente e la password. Un messaggio "Accesso Riuscito" conferma che è stato eseguito l'accesso.

  4. Passare alla directory radice del progetto.

  5. Eseguire il comando seguente per compilare l'immagine, sostituendo <DOCKER_ID> con l'ID dell'account Docker Hub:

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

    Annotazioni

    Se stai utilizzando un computer Mac serie M, usa --platform linux/amd64 invece.

  6. Eseguire il push dell'immagine in Docker:

    docker push $dockerId/$imageName:$imageVersion
    

    A seconda della velocità di rete, il push iniziale dell'immagine potrebbe richiedere alcuni minuti. Durante l'attesa, passare alla sezione successiva.

Creare risorse di Azure

Creare le risorse di Azure necessarie per l'esecuzione di Durable Functions in un'app contenitore.

  • Gruppo di risorse di Azure: Gruppo di risorse contenente tutte le risorse create.
  • Ambiente dell'app Azure Container: Ambiente che ospita l'app contenitore.
  • App contenitore di Azure: l'immagine contenente l'app Durable Functions viene distribuita in questa app.
  • Account di archiviazione di Azure: Richiesto dall'app per le funzioni per archiviare i dati correlati all'app, ad esempio il codice dell'applicazione.

Configurazione iniziale

  1. In un nuovo terminale accedere alla sottoscrizione di Azure:

    az login  
    
    az account set -s <subscription_name>
    
  2. Eseguire i comandi necessari per configurare l'estensione CLI di Azure Container Apps.

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

Un profilo del carico di lavoro determina la quantità di risorse di calcolo e memoria disponibili per le app contenitore distribuite in un ambiente. Creare un profilo di carico di lavoro a consumo per il supporto con scalabilità zero e il pagamento in base all'uso.

  1. Impostare le variabili di ambiente.

    location=<REGION>
    resourceGroup=<RESOURCE_GROUP_NAME>
    storage=<STORAGE_NAME>
    containerAppEnv=<CONTAINER_APP_ENVIRONMNET_NAME>
    functionApp=<APP_NAME>
    vnet=<VNET_NAME>
    
  2. Creare un gruppo di risorse.

    az group create --name $resourceGroup --location $location
    
  3. Creare l'ambiente app contenitore.

    az containerapp env create \
      --enable-workload-profiles \
      --resource-group $resourceGroup \
      --name $containerAppEnv \
      --location $location \
    
  4. Creare un'applicazione container basata sull'immagine di 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. Prendere nota dell'URL dell'app, che dovrebbe essere simile a https://<APP_NAME>.<ENVIRONMENT_IDENTIFIER>.<REGION>.azurecontainerapps.io.

Creare dei database

  1. Creare un account di archiviazione di Azure, richiesto dall'app per le funzioni.

    az storage account create --name $storage --location $location --resource-group $resourceGroup --sku Standard_LRS
    
  2. Nel portale di Azure creare un database SQL di Azure per rendere persistenti le informazioni sullo stato. Durante la creazione:

    • Abilitare i servizi e le risorse di Azure per accedere a questo server (in Rete)
    • Impostare il valore per Le regole di confronto del database (in Impostazioni aggiuntive) su Latin1_General_100_BIN2_UTF8.

Annotazioni

Evitare di abilitare l'impostazione Consenti a servizi e risorse di Azure di accedere a questo server per gli scenari di produzione. Le applicazioni di produzione devono implementare approcci più sicuri, ad esempio restrizioni firewall più avanzate o configurazioni di rete virtuale.

Configurare l'autenticazione basata su identità

Le identità gestite rendono l'app più sicura eliminando i segreti dall'app, ad esempio le credenziali nelle stringhe di connessione. Sebbene sia possibile scegliere tra l'identità gestita assegnata dal sistema e l'identità gestita assegnata dall'utente, si consiglia l'identità gestita assegnata dall'utente, poiché non è legata al ciclo di vita dell'app.

In questa sezione viene configurata l'identità gestita assegnata dall'utente per Archiviazione di Azure.

  1. Impostare le variabili di ambiente.

    subscription=<SUBSCRIPTION_ID>
    identity=<IDENTITY_NAME>
    
  2. Creare una risorsa di identità gestita.

    echo "Creating $identity"
    az identity create -g $resourceGroup -n $identity --location "$location"
    
  3. Assegnare l'identità utente all'app contenitore.

    echo "Assigning $identity to app"
    az containerapp identity assign --resource-group $resourceGroup --name $functionApp --user-assigned $identity
    
  4. Impostare l'ambito delle autorizzazioni di controllo degli accessi in base al ruolo.

    scope="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.Storage/storageAccounts/$storage"
    
  5. Ottenere clientId dell'identità utente.

    # Get the identity's ClientId 
    clientId=$(az identity show --name $identity --resource-group $resourceGroup --query 'clientId' --output tsv)
    
  6. Assegnare il ruolo Proprietario dati BLOB di archiviazione per l'accesso all'account di archiviazione.

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

Configurare le impostazioni dell'app

Annotazioni

L'autenticazione nel database MSSQL tramite l'identità gestita non è supportata quando si ospita un'app Durable Functions nelle app contenitore di Azure. Per il momento, questa guida esegue l'autenticazione usando le stringhe di connessione.

  1. Dalla risorsa del database SQL nel portale di Azure passare a Impostazioni>Stringhe di connessione per trovare la stringa di connessione.

    Screenshot che mostra la stringa di connessione del database.

    La stringa di connessione deve avere un formato simile al seguente:

    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;"
    

    Se si dimentica la password dal passaggio di creazione del database precedente, è possibile reimpostarla nella risorsa di SQL Server.

    Screenshot che mostra il pulsante reimpostazione della password.

  2. Archiviare la stringa di connessione del database SQL come segreto denominato sqldbconnection nell'app contenitore.

    az containerapp secret set \
    --resource-group $resourceGroup \
    --name $functionApp \
    --secrets sqldbconnection=$connStr
    
  3. Aggiungere le impostazioni seguenti all'app:

    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
    

Test in locale

  1. Usare uno strumento di test HTTP per inviare una POST richiesta all'endpoint del trigger HTTP, che dovrebbe essere simile a:

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

    La risposta è il risultato iniziale della funzione HTTP che informa che l'orchestrazione di Durable Functions è stata avviata correttamente. Anche se la risposta include alcuni URL utili, non visualizza ancora il risultato finale dell'orchestrazione.

  2. Copiare/incollare il valore url per statusQueryGetUri nella barra degli indirizzi del browser ed eseguire. In alternativa, è possibile continuare a usare lo strumento di test HTTP per inviare la GET richiesta.

    La richiesta esegue una query per determinare lo stato dell'istanza di orchestrazione. Si noterà che l'istanza è stata completata e gli output o i risultati dell'app 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"
    }
    

Passaggi successivi

Altre informazioni su: