Condividi tramite


Distribuire un'app Python containerizzata nel Servizio App

In questa parte della serie di esercitazioni si apprenderà come distribuire un'applicazione Web Python containerizzata su Azure App Service Web App per contenitori. Questo servizio completamente gestito consente di eseguire app in contenitori senza dover gestire il proprio agente di orchestrazione dei contenitori.

Il servizio app semplifica la distribuzione tramite pipeline di integrazione continua/distribuzione continua (CI/CD) che funzionano con l'hub Docker, Registro Azure Container, Azure Key Vault e altri strumenti DevOps. Questa esercitazione è la parte 4 di una serie di esercitazioni in 5 parti.

Alla fine di questo articolo, avrai un'app Web di App Service sicura e pronta per l'ambiente di produzione, in esecuzione da un'immagine Docker del contenitore. L'app usa un'identità gestita assegnata dal sistema per eseguire il pull dell'immagine dal Registro Azure Container e recuperare i segreti da Azure Key Vault.

Questo diagramma dei servizi evidenzia i componenti trattati in questo articolo.

Screenshot dei servizi utilizzati nell'esercitazione - App Python containerizzata in Azure con il percorso di distribuzione evidenziato.

I comandi dell'interfaccia della riga di comando di Azure possono essere eseguiti in Azure Cloud Shell o in un computer locale con l'interfaccia della riga di comando di Azure installata.

Importante

È consigliabile usare Azure Cloud Shell per tutti i passaggi basati sull'interfaccia della riga di comando in questa esercitazione perché:

  • Viene fornito pre-autenticato con l'account Azure, evitando problemi di accesso
  • Includono tutte le estensioni necessarie di Azure CLI pronte all'uso.
  • Garantisce un comportamento coerente indipendentemente dal sistema operativo o dall'ambiente locale
  • Non richiede alcuna installazione locale, ideale per gli utenti senza diritti di amministratore
  • Fornisce l'accesso diretto ai servizi di Azure dal portale: non è richiesta alcuna configurazione locale di Docker o di rete
  • Evitare problemi di configurazione del firewall locale o di rete

Creare uno Spazio delle Chiavi con autorizzazione RBAC

Azure Key Vault è un servizio sicuro per l'archiviazione di segreti, chiavi API, stringhe di connessione e certificati. In questo script vengono archiviati la stringa di connessione MongoDB e l'applicazione SECRET_KEY.

Key Vault è configurato per l'uso del controllo degli accessi in base al ruolo per gestire l'accesso tramite i ruoli di Azure anziché i criteri di accesso tradizionali. L'app Web usa l'identità gestita assegnata dal sistema per recuperare i segreti in modo sicuro in fase di esecuzione.

Nota

La creazione anticipata del Key Vault garantisce che i ruoli possano essere assegnati prima di qualsiasi tentativo di accedere ai segreti. Consente inoltre di evitare ritardi di propagazione nelle assegnazioni di ruolo. Poiché Key Vault non dipende dal Servizio App, effettuare il provisioning in anticipo migliora l'affidabilità e la sequenziazione.

  1. In questo passaggio si usa il comando az keyvault create per creare un Azure Key Vault con RBAC abilitato.

    #!/bin/bash
    RESOURCE_GROUP_NAME="msdocs-web-app-rg"
    LOCATION="westus"
    KEYVAULT_NAME="${RESOURCE_GROUP_NAME}-kv"
    
    az keyvault create \
      --name "$KEYVAULT_NAME" \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --location "$LOCATION" \
      --enable-rbac-authorization true
    

Creare il piano di servizio app e l'app Web

Il piano di servizio app definisce le risorse di calcolo, il piano tariffario e l'area per l'app Web. L'applicazione web esegue l'applicazione in contenitori ed è fornita con un'identità gestita assegnata dal sistema, utilizzata per autenticarsi in modo sicuro a Registro Azure Container e Azure Key Vault.

In questo passaggio vengono eseguite le attività seguenti:

  • Creare un piano di Servizio app
  • Crea l'app web con l'identità gestita
  • Configurare l'app Web per la distribuzione usando un'immagine del contenitore specifica
  • Preparati per la distribuzione continua tramite il Registro Azure Container

Nota

L'app Web deve essere creata prima di assegnare l'accesso all'Azure Container Registry o al Key Vault perché l'identità gestita viene creata solo in fase di distribuzione. Inoltre, l'assegnazione dell'immagine del contenitore durante la creazione garantisce che l'app venga avviata correttamente con la configurazione prevista.

  1. In questo passaggio si usa il comando az appservice plan create per effettuare il provisioning dell'ambiente di calcolo per l'app.

    #!/bin/bash
    APP_SERVICE_PLAN_NAME="msdocs-web-app-plan"
    
    az appservice plan create \
        --name "$APP_SERVICE_PLAN_NAME" \
        --resource-group "$RESOURCE_GROUP_NAME" \
        --sku B1 \
        --is-linux
    
  2. In questo passaggio si usa il comando az webapp create per creare l'app Web. Questo comando abilita anche un'identità gestita assegnata dal sistema e imposta l'immagine del contenitore in cui l'app viene eseguita.

    #!/bin/bash
    APP_SERVICE_NAME="msdocs-website-name" #APP_SERVICE_NAME must be globally unique as it becomes the website name in the URL `https://<website-name>.azurewebsites.net`.
    # Use the same registry name as in part 2 of this tutorial series.
    REGISTRY_NAME="msdocscontainerregistryname" #REGISTRY_NAME is the registry name you used in part 2 of this tutorial.
    CONTAINER_NAME="$REGISTRY_NAME.azurecr.io/msdocspythoncontainerwebapp:latest" #CONTAINER_NAME is of the form "yourregistryname.azurecr.io/repo_name:tag".
    
    az webapp create \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --plan "$APP_SERVICE_PLAN_NAME" \
      --name "$APP_SERVICE_NAME" \
      --assign-identity '[system]' \
      --deployment-container-image-name "$CONTAINER_NAME" 
    

    Nota

    Quando si esegue questo comando, è possibile che venga visualizzato l'errore seguente:

    No credential was provided to access Azure Container Registry. Trying to look up...
    Retrieving credentials failed with an exception:'Failed to retrieve container registry credentials. Please either provide the credentials or run 'az acr update -n msdocscontainerregistryname --admin-enabled true' to enable admin first.'
    

    Questo errore si verifica perché l'app Web tenta di usare le credenziali di amministratore per accedere al Registro Azure Container, che per impostazione predefinita sono disabilitate. È possibile ignorare questo messaggio: il passaggio successivo configura l'app Web per l'uso della sua identità gestita per l'autenticazione con Azure Container Registry.

Concedere il ruolo del responsabile dei segreti all'utente connesso

Per archiviare i segreti in Azure Key Vault, l'utente che esegue lo script deve avere il ruolo Key Vault Secrets Officer . Questo ruolo consente di creare e gestire segreti all'interno dell'archivio.

In questo passaggio lo script assegna tale ruolo all'utente attualmente connesso. Questo utente può quindi archiviare in modo sicuro i segreti dell'applicazione, ad esempio la stringa di connessione MongoDB e l'oggetto dell'app SECRET_KEY.

Questa assegnazione di ruolo è la prima delle due assegnazioni di ruolo correlate al Key Vault. Successivamente, all'identità gestita assegnata dal sistema dell'app web viene concesso l'accesso per recuperare i segreti dal vault.

L'uso del controllo degli accessi in base al ruolo di Azure garantisce l'accesso sicuro e verificabile in base all'identità, eliminando la necessità di credenziali codificate staticamente.

Nota

All'utente deve essere assegnato il ruolo di Ufficiale dei Segreti di Key Vaultprima di tentare di archiviare qualsiasi segreto nel key vault. Questa assegnazione viene eseguita usando il comando az role assignment create con ambito key vault.

  1. In questo passaggio si usa il comando az role assignment create per assegnare il ruolo nell'ambito di Key Vault.

    #!/bin/bash
    CALLER_ID=$(az ad signed-in-user show --query id -o tsv)
    echo $CALLER_ID # Verify this value retrieved successfully. In production, poll to verify this value is retrieved successfully.
    
    az role assignment create \
      --role "Key Vault Secrets Officer" \
      --assignee "$CALLER_ID" \
      --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.KeyVault/vaults/$KEYVAULT_NAME"
    
    

Concedere l'accesso Web ad ACR facendo uso dell'identità gestita

Per eseguire il pull sicuro delle immagini dal Registro Azure Container, l'app Web deve essere configurata per l'uso dell'identità gestita assegnata dal sistema. L'uso dell'identità gestita evita la necessità di credenziali di amministratore e supporta la distribuzione sicura senza credenziali.

Questo processo prevede due azioni chiave:

  • Abilitazione dell'app web a utilizzare la propria identità gestita durante l'accesso al Registro dei Contenitori di Azure
  • Assegnazione del ruolo AcrPull a tale identità nell'ACR (Azure Container Registry) di destinazione
  1. In questo passaggio recuperi l'ID principale (ID oggetto univoco) dell'identità gestita dell'app Web usando il comando az webapp identity show. Successivamente, abilita l'uso dell'identità gestita per l'autenticazione di Azure Container Registry impostando la acrUseManagedIdentityCreds proprietà su true utilizzando az webapp config set. Assegnare quindi il ruolo AcrPull all'identità gestita dell'app Web usando il comando az role assignment create . Questo ruolo concede all'app Web l'autorizzazione per eseguire il pull delle immagini dal Registro di sistema.

    #!/bin/bash
    PRINCIPAL_ID=$(az webapp identity show \
      --name "$APP_SERVICE_NAME" \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --query principalId \
      -o tsv)
    echo $PRINCIPAL_ID # Verify this value retrieved successfully. In production, poll for successful 'AcrPull' role assignment using `az role assignment list`.    
    
    az webapp config set \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --name "$APP_SERVICE_NAME" \
      --generic-configurations '{"acrUseManagedIdentityCreds": true}'
    
    az role assignment create \
    --role "AcrPull" \
    --assignee "$PRINCIPAL_ID" \
    --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.ContainerRegistry/registries/$REGISTRY_NAME"
    
    

Concedi l'accesso all'insieme di credenziali all'identità gestita dell'applicazione web

L'app Web deve disporre dell'autorizzazione per accedere ai segreti, ad esempio la stringa di connessione MongoDB e .SECRET_KEY Per concedere queste autorizzazioni, è necessario assegnare il ruolo Utente dei segreti dell'insieme di credenziali delle chiavi all'identità gestita assegnata dal sistema dell'app Web.

  1. In questo passaggio, si utilizza l'identificatore univoco (ID principale) dell'identità gestita assegnata dal sistema dell'app Web per concedere all'app Web l'accesso al Key Vault con il ruolo Utente dei segreti utilizzando il comando az role assignment create.

    #!/bin/bash
    
    az role assignment create \
    --role "Key Vault Secrets User" \
    --assignee "$PRINCIPAL_ID" \
    --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.KeyVault/vaults/$KEYVAULT_NAME"
    

Archiviare segreti in Key Vault

Per evitare la codifica dei segreti nell'applicazione, questo passaggio archivia la stringa di connessione MongoDB e la chiave privata dell'app Web in Azure Key Vault. Questi segreti possono quindi essere accessibili in modo sicuro dall'app Web in fase di esecuzione tramite l'identità gestita, senza la necessità di archiviare le credenziali nel codice o nella configurazione.

Nota

Anche se questa esercitazione archivia solo la stringa di connessione e la chiave segreta nel Key Vault, è possibile archiviare anche altre impostazioni dell'applicazione, come il nome del database MongoDB o il nome della raccolta, sempre nel Key Vault.

  1. In questo passaggio si usa il comando az cosmosdb keys list per recuperare la stringa di connessione mongoDB. Usare quindi il comando az keyvault secret set per archiviare sia la stringa di connessione che una chiave privata generata in modo casuale in Key Vault.

    #!/bin/bash
    ACCOUNT_NAME="msdocs-cosmos-db-account-name"
    
    MONGO_CONNECTION_STRING=$(az cosmosdb keys list \
      --name "$ACCOUNT_NAME" \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --type connection-strings \
      --query "connectionStrings[?description=='Primary MongoDB Connection String'].connectionString" -o tsv)
    
    SECRET_KEY=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9')
    # This key is cryptographically secure, using OpenSSL’s strong random number generator.
    
    az keyvault secret set \
      --vault-name "$KEYVAULT_NAME" \
      --name "MongoConnectionString" \
      --value "$MONGO_CONNECTION_STRING"
    
    az keyvault secret set \
      --vault-name "$KEYVAULT_NAME" \
      --name "MongoSecretKey" \
      --value "$SECRET_KEY"
    

Configurare l'app Web per l'uso dei segreti di Kay Vault

Per accedere ai segreti in modo sicuro in fase di esecuzione, l'app Web deve essere configurata per fare riferimento ai segreti archiviati in Azure Key Vault. Questo passaggio viene eseguito usando i riferimenti a Key Vault, che inserisce i valori dei segreti nell'ambiente dell'app tramite l'identità gestita assegnata dal sistema.

Questo approccio evita i segreti hardcoding e consente all'app di recuperare in modo sicuro valori sensibili come la stringa di connessione MongoDB e la chiave privata durante l'esecuzione.

  1. In questo passaggio si usa il comando az webapp config appsettings set per aggiungere le impostazioni dell'applicazione che fanno riferimento ai segreti di Key Vault. In particolare, questa operazione imposta le impostazioni dell'app MongoConnectionString e MongoSecretKey per fare riferimento ai segreti corrispondenti memorizzati in Key Vault.

    #!/bin/bash
    MONGODB_NAME="restaurants_reviews"
    MONGODB_COLLECTION_NAME="restaurants_reviews"
    
    az webapp config appsettings set \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --name "$APP_SERVICE_NAME" \
      --settings \
          CONNECTION_STRING="@Microsoft.KeyVault(SecretUri=https://$KEYVAULT_NAME.vault.azure.net/secrets/MongoConnectionString)" \
          SECRET_KEY="@Microsoft.KeyVault(SecretUri=https://$KEYVAULT_NAME.vault.azure.net/secrets/MongoSecretKey)" \
          DB_NAME="$MONGODB_NAME" \
          COLLECTION_NAME="$MONGODB_COLLECTION_NAME"
    

Abilitare la distribuzione continua da ACR

L'abilitazione della distribuzione continua permette all'app Web di recuperare ed eseguire automaticamente l'immagine del contenitore più recente ogni volta che viene eseguito un push su Azure Container Registry. In questo modo si riducono i passaggi di distribuzione manuali e si garantisce che l'app rimanga aggiornata.

Nota

Nel passaggio successivo, registrerai un webhook in ACR per notificare all'app web quando viene effettuato il push di una nuova immagine.

  1. In questo passaggio, si utilizza il comando az webapp deployment container config per abilitare la distribuzione continua da ACR (Azure Container Registry) all'app web.

    #!/bin/bash
    az webapp deployment container config \
      --name "$APP_SERVICE_NAME" \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --enable-cd true
    

Registrare un webhook per Azure Container Registry per la distribuzione continua

Per automatizzare le distribuzioni, registrare un webhook in Azure Container Registry che notifica all'applicazione web ogni volta che viene eseguito il push di una nuova immagine del container. Il webhook consente all'app di scaricare ed eseguire automaticamente la versione più recente.

Il webhook configurato in Registro Azure Container invia una richiesta POST all'endpoint SCM dell'app Web (SERVICE_URI) ogni volta che viene eseguito il push di una nuova immagine nel repository msdocspythoncontainerwebapp. Questa azione attiva l'app Web per scaricare e distribuire l'immagine aggiornata, completando la pipeline di distribuzione continua tra Azure Container Registry e Servizio app di Azure.

Nota

L'URI del webhook deve seguire questo formato:
https://<app-name>.scm.azurewebsites.net/api/registry/webhook

Deve terminare con /api/registry/webhook. Se viene visualizzato un errore URI, verificare che il percorso sia corretto.

  1. In questo passaggio, utilizzare il comando az acr webhook create per registrare il webhook e configurarlo affinché venga attivato dagli eventi push.

    #!/bin/bash
    CREDENTIAL=$(az webapp deployment list-publishing-credentials \
        --resource-group "$RESOURCE_GROUP_NAME" \
        --name "$APP_SERVICE_NAME" \
        --query publishingPassword --output tsv)
    # Web app publishing credentials may not be available immediately. In production, poll until non-empty.   
    
    SERVICE_URI="https://$APP_SERVICE_NAME:$CREDENTIAL@$APP_SERVICE_NAME.scm.azurewebsites.net/api/registry/webhook"
    
    az acr webhook create \
      --name webhookforwebapp \
      --registry "$REGISTRY_NAME" \
      --scope msdocspythoncontainerwebapp:* \
      --uri "$SERVICE_URI" \
      --actions push
    
    

Esplorare il sito

Per verificare che l'app Web sia in esecuzione, aprire https://<website-name>.azurewebsites.net, sostituendo <website-name> con il nome del servizio app. Dovresti vedere l'app di esempio per le recensioni del ristorante. Il caricamento della prima volta potrebbe richiedere alcuni istanti.

Una volta visualizzato il sito, provare ad aggiungere un ristorante e inviare una recensione per verificare che l'app funzioni correttamente.

Nota

Il comando az webapp browse non è supportato in Cloud Shell. Se si usa Cloud Shell, aprire manualmente un browser e passare all'URL del sito.

Se si usa l'interfaccia della riga di comando di Azure in locale, è possibile usare il comando az webapp browse per aprire il sito nel browser predefinito:

az webapp browse --name $APP_SERVICE_NAME --resource-group $RESOURCE_GROUP_NAME

Nota

Il comando az webapp browse non è supportato in Cloud Shell. Apri una finestra del browser e naviga invece all'URL del sito web.

Risoluzione dei problemi di distribuzione

Se l'app di esempio non viene visualizzata, provare i passaggi seguenti.

  • Con la distribuzione dei container e App Service, controllare sempre la pagina dei log Centro Distribuzione / nel portale di Azure. Verificare che il contenitore sia stato effettuato il pull e che sia in esecuzione. L'estrazione iniziale e l'esecuzione del contenitore possono richiedere alcuni istanti.
  • Provare a riavviare il servizio app e verificare se il problema viene risolto.
  • In caso di errori di programmazione, questi errori vengono visualizzati nei log applicazioni. Nella pagina del portale di Azure per l'App Service, selezionare Diagnostica e risolvi i problemi/log delle applicazioni.
  • L'app di esempio si basa su una connessione ad Azure Cosmos DB per MongoDB. Verificare che l'App Service disponga di impostazioni applicative con le informazioni di connessione corrette.
  • Verificare che l'identità gestita sia abilitata per il Servizio App e che venga usata nel Centro di distribuzione. Nella pagina del portale di Azure per l'App Service, passare alla risorsa App Service Centro distribuzione e confermare che autenticazione sia impostata su Identità Gestita.
  • Verificare che il webhook sia definito nel Registro Azure Container. Il webhook consente al Servizio App di recuperare l'immagine del contenitore. In particolare, verificare che l'URI del servizio termini con "/api/registry/webhook". Se no, aggiungilo.
  • I diversi SKU del Registro Azure Container offrono funzionalità differenti, incluso il numero di webhook. Nel caso in cui si riutilizzi un registro esistente, è possibile visualizzare il messaggio "Quota superata per i webhook del tipo di risorsa per lo SKU Basic. Altre informazioni sulle diverse quote di SKU e sul processo di aggiornamento: https://aka.ms/acr/tiers". Se viene visualizzato questo messaggio, utilizzare un nuovo Registro di sistema o ridurre il numero di webhook del Registro di sistema attualmente in uso.

Passaggio successivo