Acceso a recursos de Azure desde un punto de conexión en línea con una identidad administrada

SE APLICA A:Extensión ML de la CLI de Azure v2 (actual)SDK de Python azure-ai-ml v2 (actual)

Aprenda a acceder de forma segura a los recursos de Azure desde el script de puntuación con un punto de conexión en línea y una identidad administrada asignada por el sistema o una identidad administrada asignada por el usuario.

Los puntos de conexión administrados y los puntos de conexión de Kubernetes permiten que Azure Machine Learning pueda administrar la carga que conlleva aprovisionar el recurso de proceso e implementar el modelo de Machine Learning. Normalmente, el modelo necesita acceder a recursos de Azure, como Azure Container Registry o el almacenamiento de blobs para la inferencia. Con una identidad administrada puede acceder a estos recursos sin necesidad de administrar las credenciales en el código. Más información sobre las identidades administradas.

En esta guía se da por supuesto que no tiene una identidad administrada, una cuenta de almacenamiento o un punto de conexión en línea. Si ya tiene estos componentes, vaya a la sección Concesión de permiso de acceso a la identidad administrada.

Requisitos previos

  • Para usar Azure Machine Learning, es preciso tener una suscripción a Azure. Si no tiene una suscripción de Azure, cree una cuenta gratuita antes de empezar. Pruebe hoy mismo la versión gratuita o de pago de Azure Machine Learning.

  • Instale y configure la CLI de Azure y la extensión ML (v2). Para más información, consulte Instalación, configuración y uso de la CLI 2.0.

  • Un grupo de recursos de Azure, donde usted (o la entidad de servicio que utiliza) deben tener el acceso Administrador de acceso de usuario y el de Colaborador. Tiene un grupo de recursos de este tipo si configuró la extensión de ML según el artículo anterior.

  • Un área de trabajo de Azure Machine Learning. Ya tiene un área de trabajo si configuró la extensión de ML según el artículo anterior.

  • Un modelo de Machine Learning listo para la puntuación y la implementación. Si sigue el ejemplo, se proporciona un modelo.

  • Si aún no ha establecido los valores predeterminados de la CLI de Azure, guarde la configuración predeterminada. Para evitar pasar los valores de la suscripción, el área de trabajo y el grupo de recursos varias veces, ejecute este código:

    az account set --subscription <subscription ID>
    az configure --defaults gitworkspace=<Azure Machine Learning workspace name> group=<resource group>
    
  • Para seguir el ejemplo, clone el repositorio de ejemplos y luego cambie el directorio a CLI.

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

Limitaciones

  • La identidad de un punto de conexión es inmutable. Durante la creación del punto de conexión, puede asociarlo a una identidad asignada por el sistema (valor predeterminado) o a una identidad asignada por el usuario. No se puede cambiar la identidad después de crear el punto de conexión.
  • Si el almacenamiento de blobs y ARC están configurados como privados, es decir, detrás de una red virtual, el acceso desde el punto de conexión de Kubernetes debe estar a través del vínculo privado, independientemente de si el área de trabajo es pública o privada. Para más información sobre la configuración del vínculo privado, consulte Cómo proteger la red virtual del área de trabajo.

Configuración de variables para la implementación

Configure los nombres de las variables para el área de trabajo, la ubicación del área de trabajo y el punto de conexión que desea crear para usar con la implementación.

El código siguiente exporta estos valores como variables de entorno en el punto de conexión:

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

A continuación, especifique el nombre que desea para la cuenta de almacenamiento de blobs, el contenedor de blobs y el archivo. Estos nombres de variable se definen aquí y se hace referencia a ellos en los comandos az storage account create y az storage container create de la sección siguiente.

El código siguiente exporta esos valores como variables de entorno:

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

Una vez exportadas estas variables, cree un archivo de texto localmente. Cuando se implementa el punto de conexión, el script de puntuación accede a este archivo de texto mediante la identidad administrada asignada por el sistema que se genera al crear el punto de conexión.

Definición de la configuración de la implementación

Para implementar un punto de conexión en línea con la CLI, debe definir la configuración en un archivo YAML. Para más información sobre el esquema de YAML, consulte el documento de referencia de YAML del punto de conexión en línea.

Los archivos YAML de los ejemplos siguientes se usan para crear puntos de conexión en línea.

El siguiente ejemplo de YAML se encuentra en endpoints/online/managed/managed-identities/1-sai-create-endpoint. El archivo

  • Define el nombre por el que se desea hacer referencia al punto de conexión, my-sai-endpoint.
  • Especifica el tipo de autorización que se usará para acceder al punto de conexión, auth-mode: key.
$schema: https://azuremlschemas.azureedge.net/latest/managedOnlineEndpoint.schema.json
name: my-sai-endpoint
auth_mode: key

Este ejemplo de YAML, 2-sai-deployment.yml,

  • Especifica que el tipo de punto de conexión que desea crear es un punto de conexión online.
  • Indica que el punto de conexión tiene una implementación asociada llamada blue.
  • Configura los detalles de la implementación como, por ejemplo, qué modelo se va a implementar y qué entorno y script de puntuación se usarán.
$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"

Creación de la identidad administrada

Para acceder a los recursos de Azure, cree una identidad administrada asignada por el sistema o asignada por el usuario para el punto de conexión en línea.

Cuando se crea un punto de conexión en línea, se genera automáticamente una identidad administrada asignada por el sistema, por lo que no es necesario crear una independiente.

Creación de una cuenta de almacenamiento y un contenedor

En este ejemplo, creará una cuenta de almacenamiento de blobs y un contenedor de blobs y, a continuación, cargará el archivo de texto creado anteriormente en el contenedor de blobs. El punto de conexión en línea y la identidad administrada tienen acceso a esta cuenta de almacenamiento y al contenedor de blob.

Primero, cree una cuenta de almacenamiento.

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

A continuación, cree el contenedor de blobs en la cuenta de almacenamiento.

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

Después, cargue el archivo de texto en el contenedor de blobs.

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

Creación de un punto de conexión en línea

El código siguiente crea un punto de conexión en línea sin especificar una implementación.

Advertencia

La identidad de un punto de conexión es inmutable. Durante la creación del punto de conexión, puede asociarlo a una identidad asignada por el sistema (valor predeterminado) o a una identidad asignada por el usuario. No puede cambiar la identidad una vez creado el punto de conexión.

Al crear un punto de conexión administrado, se crea de forma predeterminada una identidad administrada asignada por el sistema para el punto de conexión en línea.

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

Compruebe el estado del punto de conexión con lo siguiente.

az ml online-endpoint show --name $ENDPOINT_NAME

Si experimenta algún problema, consulte Solución de problemas de implementación y puntuación de puntos de conexión en línea.

Concesión de permiso a la identidad administrada

Importante

Los puntos de conexión en línea requieren permiso de extracción de Azure Container Registry y permiso de AcrPull en el registro de contenedor, y permiso de lector de datos de Storage Blob en el almacén de datos predeterminado del área de trabajo.

Puede hacer que el permiso de punto de conexión en línea acceda al almacenamiento a través de su identidad administrada asignada por el sistema o conceder permiso a la identidad administrada asignada por el usuario para acceder a la cuenta de almacenamiento creada en la sección anterior.

Recupere la identidad administrada asignada por el sistema que se creó para el punto de conexión.

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

Desde aquí, puede conceder a la identidad administrada asignada por el sistema permiso para acceder al almacenamiento.

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

Script de puntuación para acceder al recurso de Azure

Consulte el siguiente script para saber cómo usar el token de identidad para acceder a los recursos de Azure, en este escenario, la cuenta de almacenamiento creada en las secciones anteriores.

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()

Creación de una implementación con la configuración

Cree una implementación asociada al punto de conexión en línea. Obtenga más información sobre la implementación en puntos de conexión en línea.

Advertencia

Esta implementación puede tardar aproximadamente entre 8 y 14 minutos, dependiendo de si el entorno o la imagen subyacentes se están creando por primera vez. Las implementaciones subsiguientes que usen el mismo entorno serán más rápidas.

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

El valor del argumento --name puede invalidar la clave name dentro del archivo YAML.

Compruebe el estado de la implementación.

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

Para refinar la consulta anterior para que solo devuelva datos específicos, consulte Resultados de los comandos de consulta de la CLI de Azure.

Nota

El método init del script de puntuación lee el archivo de la cuenta de almacenamiento mediante el token de identidad administrada asignado por el sistema.

Para comprobar la salida del método init, consulte el registro de implementación con el código siguiente.

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

Una vez completada la implementación, el modelo, el entorno y el punto de conexión se registran en el área de trabajo de Azure Machine Learning.

Prueba del punto de conexión

Una vez implementado el punto de conexión en línea, pruebe y confirme su operación con una solicitud. Los detalles de la inferencia varían de un modelo a otro. En esta guía, los parámetros de la consulta JSON son parecidos a los siguientes:

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

Para llamar al punto de conexión, ejecute:

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

Eliminación del punto de conexión y la cuenta de almacenamiento

Si no tiene previsto seguir usando el punto de conexión en línea y el almacenamiento implementados, elimínelos para reducir los costos. Al eliminar el punto de conexión, también se eliminan todas sus implementaciones asociadas.

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