Acessar os recursos do Azure de um ponto de extremidade online com uma identidade gerenciada

APLICA-SE A:Extensão de ML da CLI do Azure v2 (atual)SDK do Python azure-ai-ml v2 (atual)

Saiba como acessar os recursos do Azure do seu script de pontuação com um ponto de extremidade online e uma identidade gerenciada atribuída pelo sistema ou identidade gerenciada atribuída pelo usuário.

Os pontos de extremidade gerenciados e do Kubernetes permitem que o Azure Machine Learning gerencie a carga de provisionamento do recurso de computação e implantação do modelo de machine learning. Normalmente, o modelo precisa acessar os recursos do Azure, como o Registro de Contêiner do Azure ou o armazenamento de blobs para inferência. Com uma identidade gerenciada, é possível acessar esses recursos sem precisar gerenciar credenciais no código. Saiba mais sobre as identidades gerenciadas.

Este guia pressupõe que você não tem uma identidade gerenciada, uma conta de armazenamento ou um ponto de extremidade online. Se já tiver estes componentes, avance para a seção Conceder permissão de acesso à identidade gerenciada.

Pré-requisitos

  • Para usar o Azure Machine Learning, você precisa ter uma assinatura do Azure. Caso não tenha uma assinatura do Azure, crie uma conta gratuita antes de começar. Experimente hoje mesmo a versão gratuita ou paga do Azure Machine Learning.

  • Instale e configure a CLI do Azure e a extensão de ML (v2). Para obter mais informações, consulte Instalar, configurar e usar a CLI 2.0.

  • Um grupo de recursos do Azure, no qual você (ou a entidade de serviço que você usa) precisa ter acesso de Administrador de acesso do usuário e de Colaborador. Você terá esse grupo de recursos se tiver configurado a extensão de ML de acordo com o artigo anterior.

  • Um Workspace do Azure Machine Learning. Você já terá um workspace se tiver configurado a extensão de ML de acordo com o artigo anterior.

  • Um modelo de machine learning treinado pronto para pontuação e implantação. Se você estiver utilizando a amostra, um modelo será fornecido.

  • Se você ainda não definiu os padrões da CLI do Azure, salve as configurações padrão. Para evitar passar os valores para sua assinatura, espaço de trabalho e grupo de recursos várias vezes, execute este código:

    az account set --subscription <subscription ID>
    az configure --defaults gitworkspace=<Azure Machine Learning workspace name> group=<resource group>
    
  • Para utilizar a amostra, clone o repositório de amostras e altere o diretório para cli.

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

Limitações

  • A identidade de um ponto de extremidade é imutável. Durante a criação do ponto de extremidade, você pode associá-lo a uma identidade atribuída pelo sistema (padrão) ou a uma identidade atribuída pelo usuário. Não é possível alterar a identidade após a criação do ponto de extremidade.
  • Se o ARC e o armazenamento de blobs estiverem configurados como particulares, ou seja, protegidos por uma rede virtual, o acesso do ponto de extremidade do Kubernetes deverá ser feito por meio do link privado, independentemente do workspace ser público ou particular. Confira mais detalhes sobre a configuração do link privado em Como proteger a VNet do workspace.

Configurar variáveis para implantação

Configurar os nomes de variáveis para o workspace, a localização do workspace e o ponto de extremidade que você deseja criar para usar com sua implantação.

O seguinte código exporta esses valores como variáveis de ambiente no seu ponto de extremidade:

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

Em seguida, especifique como você deseja nomear a sua conta de armazenamento de blobs, o contêiner de blobs e o arquivo. Esses nomes de variáveis são definidos aqui e são referenciados nos comandos az storage account create e az storage container create na próxima seção.

O seguinte código exporta esses valores como variáveis de ambiente:

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

Depois que essas variáveis forem exportadas, crie um arquivo de texto localmente. Quando o ponto de extremidade é implantado, o script de pontuação acessa esse arquivo de texto utilizando a identidade gerenciada atribuída pelo sistema, que é gerada ao criar o ponto de extremidade.

Definir a configuração de implantação

Para implantar um ponto de extremidade online com a CLI, defina a configuração em um arquivo YAML. Para obter mais informações sobre o esquema YAML, confira o documento de referência YAML do ponto de extremidade online.

Os arquivos YAML são usados para criar pontos de extremidade online nos exemplos a seguir.

O YAML de exemplo a seguir está em endpoints/online/managed/managed-identities/1-sai-create-endpoint. O arquivo,

  • Define o nome que você deseja atribuir ao ponto de extremidade my-sai-endpoint.
  • Especifica o tipo de autorização a ser usado para acessar o ponto de extremidade auth-mode: key.
$schema: https://azuremlschemas.azureedge.net/latest/managedOnlineEndpoint.schema.json
name: my-sai-endpoint
auth_mode: key

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

  • Especifica que o tipo de ponto de extremidade que você deseja criar é um ponto de extremidade online.
  • Indica que o ponto de extremidade tem uma implantação associada chamada blue.
  • Configura os detalhes da implantação, como qual modelo implantar e qual script de pontuação e ambiente usar.
$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"

Criar a identidade gerenciada

Para acessar os recursos do Azure, crie uma identidade gerenciada atribuída pelo sistema ou pelo usuário para o ponto de extremidade online.

Quando você cria um ponto de extremidade online, uma identidade gerenciada atribuída pelo sistema é gerada automaticamente para você, portanto, não é necessário criar uma a parte.

Criar uma conta e um contêiner de armazenamento

Neste exemplo, crie uma conta de armazenamento de blobs, um contêiner de blob e carregue o arquivo de texto criado anteriormente no contêiner de blobs. Você concede ao ponto de extremidade online e à identidade gerenciada acesso a essa conta de armazenamento e ao contêiner de blobs.

Primeiro, crie uma conta de armazenamento.

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

Em seguida, crie o contêiner de blob na conta de armazenamento.

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

Em seguida, carregue o arquivo de texto no contêiner de 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

Criar um ponto de extremidade online

O código a seguir cria um ponto de extremidade online sem especificar uma implantação.

Aviso

A identidade de um ponto de extremidade é imutável. Durante a criação do ponto de extremidade, você pode associá-lo a uma identidade atribuída pelo sistema (padrão) ou a uma identidade atribuída pelo usuário. Após a criação do banco de dados, não é possível alterar a identidade.

Quando você cria um ponto de extremidade online, uma identidade gerenciada atribuída pelo sistema é criada para o ponto de extremidade por padrão.

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

Verifique o status do ponto de extremidade com as etapas a seguir.

az ml online-endpoint show --name $ENDPOINT_NAME

Se você encontrar algum problema, consulte Solucionar problemas de implantação e pontuação de pontos de extremidade online.

Conceder permissão de acesso para a identidade gerenciada

Importante

Os pontos de extremidade online necessitam de permissão de pull do Registro de Contêiner do Azure, permissão de AcrPull, para o registro de contêiner e permissão do Leitor de Dados de Armazenamento de Blobs para o armazenamento de dados padrão do workspace.

Você pode fazer com que a permissão de ponto de extremidade online acesse o seu armazenamento por meio da identidade gerenciada atribuída pelo sistema ou conceder permissão à identidade gerenciada atribuída pelo usuário para acessar a conta de armazenamento criada na seção anterior.

Recuperar a identidade gerenciada atribuída ao sistema que foi criada para o seu ponto de extremidade.

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

Deste ponto em diante, você pode dar à identidade gerenciada atribuída ao sistema permissão para acessar o seu armazenamento.

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

Script de pontuação para acessar o recurso do Azure

Consulte o script a seguir para entender como usar seu token de identidade para acessar os recursos do Azure, nesse cenário, a conta de armazenamento criada nas seções 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()

Criar uma implantação com sua configuração

Crie uma implantação associada ao ponto de extremidade online. Saiba mais sobre a implantação em pontos de extremidade online.

Aviso

Essa implantação pode levar cerca de 8 a 14 minutos, dependendo se o ambiente ou a imagem subjacente está sendo criada pela primeira vez. As próximas implantações que usarem o mesmo ambiente serão mais 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

Observação

O valor do argumento --name pode substituir a chave name dentro do arquivo YAML.

Verifique o status da implantação.

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

A fim de refinar a consulta acima para retornar apenas dados específicos, confira Consultar a saída de comandos da CLI do Azure.

Observação

O método init no script de pontuação lê o arquivo na conta de armazenamento usando o token de identidade gerenciada atribuída pelo sistema.

Para verificar a saída do método init, confira o log de implantação com o código a seguir.

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

Quando a implantação for concluída, o modelo, o ambiente e o ponto de extremidade serão registrados em seu workspace do Azure Machine Learning.

Testar o ponto de extremidade

Depois que o ponto de extremidade online for implantado, teste e confirme sua operação com uma solicitação. Os detalhes de inferência variam de modelo para modelo. Neste guia, os parâmetros de consulta JSON são semelhantes a:

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

Para chamar o seu ponto de extremidade, execute:

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

Excluir o ponto de extremidade e a conta de armazenamento

Se você não pretende continuar usando o armazenamento e o ponto de extremidade online implantados, exclua-os para reduzir os custos. Quando você exclui o ponto de extremidade, todas as implantações associadas a ele também são excluídas.

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