Accedere alle risorse di Azure da un endpoint online con un'identità gestita

SI APPLICA A:Estensione per Machine Learning dell'interfaccia della riga di comando di Azure v2 (corrente)Python SDK azure-ai-ml v2 (corrente)

Informazioni su come accedere alle risorse di Azure dallo script di assegnazione dei punteggi con un endpoint online e un'identità gestita assegnata dal sistema o un'identità gestita assegnata dall'utente.

Sia gli endpoint gestiti sia gli endpoint Kubernetes consentono ad Azure Machine Learning di gestire il carico di provisioning della risorsa di calcolo e della distribuzione del modello di Machine Learning. In genere il modello deve accedere alle risorse di Azure, ad esempio il Registro Azure Container o l'archiviazione BLOB per l'inferenza. Con un'identità gestita, è possibile accedere a queste risorse senza dover gestire le credenziali nel codice. Altre informazioni sulle identità gestite.

Questa guida presuppone che non si abbia un'identità gestita, un account di archiviazione o un endpoint online. Se si dispone già di questi componenti, passare alla sezione Concedere l'autorizzazione di accesso per l'identità gestita.

Prerequisiti

  • Per usare Azure Machine Learning, è necessario avere una sottoscrizione di Azure. Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare. Provare la versione gratuita o a pagamento di Azure Machine Learning.

  • Installare e configurare l'estensione dell'interfaccia della riga di comando di Azure e Machine Learning (v2). Per altre informazioni, vedere Installare, configurare e usare l'interfaccia della riga di comando 2.0.

  • Un gruppo di risorse di Azure, in cui l'utente (o l'entità servizio in uso) deve avere accesso a Accesso utenti Amministrazione istrator e Collaboratore. Se l'estensione ml è stata configurata in base all'articolo precedente, si dispone di un gruppo di risorse di questo tipo.

  • Un'area di lavoro di Azure Machine Learning. Se l'estensione ml è stata configurata in base all'articolo precedente, si dispone già di un'area di lavoro.

  • Modello di Machine Learning con training pronto per l'assegnazione di punteggi e la distribuzione. Se si segue l'esempio, viene fornito un modello.

  • Se le impostazioni predefinite per l'interfaccia della riga di comando di Azure non sono già state impostate, salvare le impostazioni predefinite. Per evitare di passare più volte i valori per la sottoscrizione, l'area di lavoro e il gruppo di risorse, eseguire questo codice:

    az account set --subscription <subscription ID>
    az configure --defaults gitworkspace=<Azure Machine Learning workspace name> group=<resource group>
    
  • Per seguire l'esempio, clonare il repository degli esempi e quindi modificare la directory nell'interfaccia della riga di comando.

    git clone https://github.com/Azure/azureml-examples --depth 1
    cd azureml-examples/cli
    

Limiti

  • L'identità per un endpoint non è modificabile. Durante la creazione dell'endpoint, è possibile associarlo a un'identità assegnata dal sistema (impostazione predefinita) o a un'identità assegnata dall'utente. Non è possibile modificare l'identità dopo la creazione dell'endpoint.
  • Se l'archiviazione ARC e BLOB sono configurate come private, ovvero dietro una rete virtuale, l'accesso dall'endpoint Kubernetes deve essere eseguito tramite il collegamento privato indipendentemente dal fatto che l'area di lavoro sia pubblica o privata. Per altre informazioni sull'impostazione del collegamento privato, vedere Come proteggere la rete virtuale dell'area di lavoro.

Configurare le variabili per la distribuzione

Configurare i nomi delle variabili per l'area di lavoro, la posizione dell'area di lavoro e l'endpoint da creare per l'uso con la distribuzione.

Il codice seguente esporta questi valori come variabili di ambiente nell'endpoint:

export WORKSPACE="<WORKSPACE_NAME>"
export LOCATION="<WORKSPACE_LOCATION>"
export ENDPOINT_NAME="<ENDPOINT_NAME>"

Specificare quindi il nome dell'account di Archiviazione BLOB, del contenitore BLOB e del file. Questi nomi di variabile sono definiti qui e vi si fa riferimento nei comandi az storage account create e az storage container create nella sezione successiva.

Il codice seguente esporta tali valori come variabili di ambiente:

export STORAGE_ACCOUNT_NAME="<BLOB_STORAGE_TO_ACCESS>"
export STORAGE_CONTAINER_NAME="<CONTAINER_TO_ACCESS>"
export FILE_NAME="<FILE_TO_ACCESS>"

Dopo l'esportazione di queste variabili, creare un file di testo in locale. Quando l'endpoint viene distribuito, lo script di assegnazione dei punteggi accede a questo file di testo usando l'identità gestita assegnata dal sistema generata al momento della creazione dell'endpoint.

Definire la configurazione della distribuzione

Per distribuire un endpoint online con l'interfaccia della riga di comando, è necessario definire la configurazione in un file YAML. Per altre informazioni sullo schema YAML, vedere il documento di riferimento sull'endpoint YAML online.

I file YAML negli esempi seguenti vengono usati per creare endpoint online.

L'esempio YAML seguente si trova in endpoints/online/managed/managed-identities/1-sai-create-endpoint. Il file

  • Definisce il nome in base al quale si vuole fare riferimento all'endpoint, my-sai-endpoint.
  • Specifica il tipo di autorizzazione da usare per accedere all'endpoint, auth-mode: key.
$schema: https://azuremlschemas.azureedge.net/latest/managedOnlineEndpoint.schema.json
name: my-sai-endpoint
auth_mode: key

Questo esempio YAML, 2-sai-deployment.yml,

  • Specifica che il tipo di endpoint che si vuole creare è un endpoint online.
  • Indica che l'endpoint ha una distribuzione associata denominata blue.
  • Configura i dettagli della distribuzione, ad esempio il modello da distribuire e quale ambiente e script di assegnazione dei punteggi usare.
$schema: https://azuremlschemas.azureedge.net/latest/managedOnlineDeployment.schema.json
name: blue
model:
  path: ../../model-1/model/
code_configuration:
  code: ../../model-1/onlinescoring/
  scoring_script: score_managedidentity.py
environment:
  conda_file: ../../model-1/environment/conda-managedidentity.yaml
  image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
instance_type: Standard_DS3_v2
instance_count: 1
environment_variables:
  STORAGE_ACCOUNT_NAME: "storage_place_holder"
  STORAGE_CONTAINER_NAME: "container_place_holder"
  FILE_NAME: "file_place_holder"

Creare l'identità gestita

Per accedere alle risorse di Azure, creare un'identità gestita assegnata dal sistema o assegnata dall'utente per l'endpoint online.

Quando si crea un endpoint online, viene generata automaticamente un'identità gestita assegnata dal sistema, quindi non è necessario crearne una separata.

Creare un account di archiviazione e un contenitore

Per questo esempio, creare un account di archiviazione BLOB e un contenitore BLOB e quindi caricare il file di testo creato in precedenza nel contenitore BLOB. Si concede all'endpoint online e all'identità gestita l'accesso a questo account di archiviazione e al contenitore BLOB.

Creare prima di tutto un account di archiviazione.

az storage account create --name $STORAGE_ACCOUNT_NAME --location $LOCATION

Creare quindi il contenitore BLOB nell'account di archiviazione.

az storage container create --account-name $STORAGE_ACCOUNT_NAME --name $STORAGE_CONTAINER_NAME

Caricare quindi il file di testo nel contenitore BLOB.

az storage blob upload --account-name $STORAGE_ACCOUNT_NAME --container-name $STORAGE_CONTAINER_NAME --name $FILE_NAME --file endpoints/online/managed/managed-identities/hello.txt

Creare un endpoint online

Il codice seguente crea un endpoint online senza specificare una distribuzione.

Avviso

L'identità per un endpoint non è modificabile. Durante la creazione dell'endpoint, è possibile associarlo a un'identità assegnata dal sistema (impostazione predefinita) o a un'identità assegnata dall'utente. Non è possibile modificare l'identità dopo la creazione dell'endpoint.

Quando si crea un endpoint online, per impostazione predefinita viene creata un'identità gestita assegnata dal sistema per l'endpoint.

az ml online-endpoint create --name $ENDPOINT_NAME -f endpoints/online/managed/managed-identities/1-sai-create-endpoint.yml

Controllare lo stato dell'endpoint con quanto segue.

az ml online-endpoint show --name $ENDPOINT_NAME

Se si verificano problemi, vedere Risoluzione dei problemi di distribuzione e assegnazione dei punteggi per gli endpoint online.

Concedere l'autorizzazione di accesso all'identità gestita

Importante

Gli endpoint online richiedono l'autorizzazione pull di Registro Azure Container, l'autorizzazione AcrPull, per il registro contenitori e l'autorizzazione Lettore dei dati dei BLOB di archiviazione per l'archivio dati predefinito dell'area di lavoro.

È possibile consentire all'endpoint online di accedere all'archiviazione tramite la rispettiva identità gestita assegnata dal sistema o concedere l'autorizzazione all'identità gestita assegnata dall'utente per accedere all'account di archiviazione creato nella sezione precedente.

Recuperare l'identità gestita assegnata dal sistema creata per l'endpoint.

system_identity=`az ml online-endpoint show --name $ENDPOINT_NAME --query "identity.principal_id" -o tsv`

Da qui è possibile concedere all'identità gestita assegnata dal sistema l'autorizzazione per accedere all'archiviazione.

az role assignment create --assignee-object-id $system_identity --assignee-principal-type ServicePrincipal --role "Storage Blob Data Reader" --scope $storage_id

Script di assegnazione dei punteggi per accedere alla risorsa di Azure

Fare riferimento allo script seguente per comprendere come usare il token di identità per accedere alle risorse di Azure, ovvero, in questo scenario, l'account di archiviazione creato nelle sezioni precedenti.

import os
import logging
import json
import numpy
import joblib
import requests
from azure.identity import ManagedIdentityCredential
from azure.storage.blob import BlobClient


def access_blob_storage_sdk():
    credential = ManagedIdentityCredential(client_id=os.getenv("UAI_CLIENT_ID"))
    storage_account = os.getenv("STORAGE_ACCOUNT_NAME")
    storage_container = os.getenv("STORAGE_CONTAINER_NAME")
    file_name = os.getenv("FILE_NAME")

    blob_client = BlobClient(
        account_url=f"https://{storage_account}.blob.core.windows.net/",
        container_name=storage_container,
        blob_name=file_name,
        credential=credential,
    )
    blob_contents = blob_client.download_blob().content_as_text()
    logging.info(f"Blob contains: {blob_contents}")


def get_token_rest():
    """
    Retrieve an access token via REST.
    """

    access_token = None
    msi_endpoint = os.environ.get("MSI_ENDPOINT", None)
    msi_secret = os.environ.get("MSI_SECRET", None)

    # If UAI_CLIENT_ID is provided then assume that endpoint was created with user assigned identity,
    # # otherwise system assigned identity deployment.
    client_id = os.environ.get("UAI_CLIENT_ID", None)
    if client_id is not None:
        token_url = (
            msi_endpoint + f"?clientid={client_id}&resource=https://storage.azure.com/"
        )
    else:
        token_url = msi_endpoint + f"?resource=https://storage.azure.com/"

    logging.info("Trying to get identity token...")
    headers = {"secret": msi_secret, "Metadata": "true"}
    resp = requests.get(token_url, headers=headers)
    resp.raise_for_status()
    access_token = resp.json()["access_token"]
    logging.info("Retrieved token successfully.")
    return access_token


def access_blob_storage_rest():
    """
    Access a blob via REST.
    """

    logging.info("Trying to access blob storage...")
    storage_account = os.environ.get("STORAGE_ACCOUNT_NAME")
    storage_container = os.environ.get("STORAGE_CONTAINER_NAME")
    file_name = os.environ.get("FILE_NAME")
    logging.info(
        f"storage_account: {storage_account}, container: {storage_container}, filename: {file_name}"
    )
    token = get_token_rest()

    blob_url = f"https://{storage_account}.blob.core.windows.net/{storage_container}/{file_name}?api-version=2019-04-01"
    auth_headers = {
        "Authorization": f"Bearer {token}",
        "x-ms-blob-type": "BlockBlob",
        "x-ms-version": "2019-02-02",
    }
    resp = requests.get(blob_url, headers=auth_headers)
    resp.raise_for_status()
    logging.info(f"Blob contains: {resp.text}")


def init():
    global model
    # AZUREML_MODEL_DIR is an environment variable created during deployment.
    # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)
    # For multiple models, it points to the folder containing all deployed models (./azureml-models)
    # Please provide your model's folder name if there is one
    model_path = os.path.join(
        os.getenv("AZUREML_MODEL_DIR"), "model/sklearn_regression_model.pkl"
    )
    # deserialize the model file back into a sklearn model
    model = joblib.load(model_path)
    logging.info("Model loaded")

    # Access Azure resource (Blob storage) using system assigned identity token
    access_blob_storage_rest()
    access_blob_storage_sdk()

    logging.info("Init complete")


# note you can pass in multiple rows for scoring
def run(raw_data):
    logging.info("Request received")
    data = json.loads(raw_data)["data"]
    data = numpy.array(data)
    result = model.predict(data)
    logging.info("Request processed")
    return result.tolist()

Creare una distribuzione con la configurazione

Creare una distribuzione associata all'endpoint online. Altre informazioni sulla distribuzione in endpoint online.

Avviso

Questa distribuzione può richiedere circa 8-14 minuti a seconda che l'ambiente o l'immagine sottostante venga compilata per la prima volta. Le distribuzioni successive che usano lo stesso ambiente saranno più rapide.

az ml online-deployment create --endpoint-name $ENDPOINT_NAME --all-traffic --name blue --file endpoints/online/managed/managed-identities/2-sai-deployment.yml --set environment_variables.STORAGE_ACCOUNT_NAME=$STORAGE_ACCOUNT_NAME environment_variables.STORAGE_CONTAINER_NAME=$STORAGE_CONTAINER_NAME environment_variables.FILE_NAME=$FILE_NAME

Nota

Il valore dell'argomento --name può eseguire l'override della chiave name all'interno del file YAML.

Controllare lo stato della distribuzione.

az ml online-deployment show --endpoint-name $ENDPOINT_NAME --name blue

Per perfezionare la query precedente in modo da restituire solo dati specifici, vedere Query sull'output del comando dell'interfaccia della riga di comando di Azure.

Nota

Il metodo init nello script di assegnazione dei punteggi legge il file dall'account di archiviazione usando il token dell'identità gestita assegnata dal sistema.

Per controllare l'output del metodo init, vedere il log di distribuzione con il codice seguente.

# Check deployment logs to confirm blob storage file contents read operation success.
az ml online-deployment get-logs --endpoint-name $ENDPOINT_NAME --name blue

Al termine della distribuzione, il modello, l'ambiente e l'endpoint vengono registrati nell'area di lavoro di Azure Machine Learning.

Testare l'endpoint

Dopo aver distribuito l'endpoint online, testare e confermare l'operazione con una richiesta. I dettagli dell'inferenza variano da modello a modello. Per questa guida, i parametri di query JSON sono simili ai seguenti:

{"data": [
    [1,2,3,4,5,6,7,8,9,10], 
    [10,9,8,7,6,5,4,3,2,1]
]}

Per chiamare l'endpoint, eseguire:

az ml online-endpoint invoke --name $ENDPOINT_NAME --request-file endpoints/online/model-1/sample-request.json

Eliminare l'endpoint e l'account di archiviazione

Se non si prevede di continuare a usare l'endpoint online e la risorsa di archiviazione distribuiti, eliminarli per ridurre i costi. Quando si elimina l'endpoint, vengono eliminate anche tutte le distribuzioni associate.

az ml online-endpoint delete --name $ENDPOINT_NAME --yes
az storage account delete --name $STORAGE_ACCOUNT_NAME --yes