다음을 통해 공유


관리 ID를 사용하여 온라인 엔드포인트에서 Azure 리소스에 액세스

적용 대상:Azure CLI ml 확장 v2(현재)Python SDK azure-ai-ml v2(현재)

온라인 엔드포인트와 시스템이 할당한 관리 ID 또는 사용자가 할당한 관리 ID를 사용하여 채점 스크립트에서 Azure 리소스에 액세스하는 방법을 알아봅니다.

관리 엔드포인트 및 Kubernetes 엔드포인트를 사용하면 Azure Machine Learning에서 컴퓨팅 리소스를 프로비전하고 기계 학습 모델을 배포하는 부담을 관리할 수 있습니다. 일반적으로 모델은 추론을 위해 Azure Container Registry 또는 BLOB 스토리지와 같은 Azure 리소스에 액세스해야 합니다. 관리 ID를 사용하면 코드에서 자격 증명을 관리할 필요 없이 이러한 리소스에 액세스할 수 있습니다. 관리 ID에 대해 자세히 알아봅니다.

이 가이드에서는 관리 ID, 스토리지 계정 또는 온라인 엔드포인트가 없다고 가정합니다. 이러한 구성 요소가 이미 있는 경우 관리 ID에 대한 액세스 권한 부여 섹션으로 건너뜁니다.

필수 조건

  • Azure Machine Learning을 사용하려면 Azure 구독이 있어야 합니다. Azure 구독이 없는 경우 시작하기 전에 체험 계정을 만듭니다. 지금 Azure Machine Learning 평가판 또는 유료 버전을 사용해 보세요.

  • Azure CLI 및 ML(v2) 확장을 설치하고 구성합니다. 자세한 내용은 2.0 CLI 설치, 설정 및 사용을 참조하세요.

  • Azure 리소스 그룹. 여기에 사용자(또는 사용하는 서비스 주체)에게 사용자 액세스 관리자기여자 액세스 권한이 있어야 합니다. 이전 문서에 따라 ML 확장을 구성한 경우 이러한 리소스 그룹이 있습니다.

  • Azure Machine Learning 작업 영역 이전 문서에 따라 ML 확장을 구성했다면 작업 영역이 이미 있는 것입니다.

  • 채점 및 배포에 사용할 수 있도록 학습된 기계 학습 모델 샘플을 따라 하면 모델이 제공됩니다.

  • Azure CLI에 대한 기본값을 아직 설정하지 않은 경우 기본 설정을 저장합니다. 구독, 작업 영역 및 리소스 그룹에 대한 값을 여러 번 전달하지 않으려면 다음 코드를 실행하세요.

    az account set --subscription <subscription ID>
    az configure --defaults gitworkspace=<Azure Machine Learning workspace name> group=<resource group>
    
  • 샘플을 따라 하려면 샘플 리포지토리를 복제한 다음 디렉터리를 cli로 변경합니다.

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

제한 사항

  • 엔드포인트의 ID는 변경할 수 없습니다. 엔드포인트를 만드는 동안 시스템 할당 ID(기본값) 또는 사용자 할당 ID와 연결할 수 있습니다. 엔드포인트가 만들어진 후에는 ID를 변경할 수 없습니다.
  • ARC 및 Blob Storage가 프라이빗, 즉 가상 네트워크 뒤에 구성된 경우 Kubernetes 엔드포인트에서의 액세스는 작업 영역이 공용인지 프라이빗인지 여부에 관계없이 프라이빗 링크를 통해 이루어져야 합니다. 프라이빗 링크 설정에 대한 자세한 내용은 작업 영역 Vnet을 보호하는 방법을 참조하세요.

배포에 대한 변수 구성

작업 영역, 작업 영역 위치 및 배포에 사용하기 위해 만들려는 엔드포인트에 대한 변수 이름을 구성합니다.

다음 코드는 이러한 값을 엔드포인트의 환경 변수로 내보냅니다.

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

다음으로 Blob 스토리지 계정, Blob 컨테이너 및 파일의 이름을 지정합니다. 이러한 변수 이름은 여기서 정의하며, 다음 섹션의 az storage account createaz storage container create 명령에서 참조됩니다.

다음 코드는 이러한 값을 환경 변수로 내보냅니다.

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

이러한 변수를 내보낸 후에는 로컬로 텍스트 파일을 만듭니다. 엔드포인트가 배포되면 채점 스크립트는 엔드포인트를 만들 때 생성된 시스템 할당 관리 ID를 사용하여 이 텍스트 파일에 액세스합니다.

배포 구성 정의

CLI를 사용하여 온라인 엔드포인트를 배포하려면 YAML 파일에서 구성을 정의해야 합니다. YAML 스키마에 대한 자세한 내용은 온라인 엔드포인트 YAML 참조 문서를 참조하세요.

다음 예제의 YAML 파일은 온라인 엔드포인트를 만드는 데 사용됩니다.

다음 YAML 예는 endpoints/online/managed/managed-identities/1-sai-create-endpoint에 있습니다. 파일은

  • my-sai-endpoint 엔드포인트를 참조할 이름을 정의합니다.
  • auth-mode: key 엔드포인트에 액세스하는 데 사용할 권한 부여 유형을 지정합니다.
$schema: https://azuremlschemas.azureedge.net/latest/managedOnlineEndpoint.schema.json
name: my-sai-endpoint
auth_mode: key

이 YAML 예, 2-sai-deployment.yml,

  • 만들려는 엔드포인트 유형이 online 엔드포인트임을 지정합니다.
  • 엔드포인트에 blue라는 연결된 배포가 있음을 나타냅니다.
  • 배포할 모델, 사용할 환경 및 채점 스크립트와 같은 배포 세부 정보를 구성합니다.
$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"

관리 ID 만들기

Azure 리소스에 액세스하려면 온라인 엔드포인트에 대해 시스템이 할당한 관리 ID 또는 사용자가 할당한 관리 ID를 만듭니다.

온라인 엔드포인트를 생성하면 시스템이 할당한 관리 ID가 자동으로 생성되므로 별도로 만들 필요가 없습니다.

스토리지 계정 및 컨테이너 만들기

이 예제에서는 BLOB 스토리지 계정 및 BLOB 컨테이너를 만든 다음, 이전에 만든 텍스트 파일을 BLOB 컨테이너에 업로드합니다. 이 스토리지 계정 및 Blob 컨테이너에 대한 온라인 엔드포인트 및 관리 ID 액세스 권한을 부여합니다.

먼저 스토리지 계정을 만듭니다.

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

다음으로, 스토리지 계정에 BLOB 컨테이너를 만듭니다.

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

그런 다음, 텍스트 파일을 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

온라인 엔드포인트 만들기

다음 코드는 배포를 지정하지 않고 온라인 엔드포인트를 만듭니다.

Warning

엔드포인트의 ID는 변경할 수 없습니다. 엔드포인트를 만드는 동안 시스템 할당 ID(기본값) 또는 사용자 할당 ID와 연결할 수 있습니다. 엔드포인트를 만든 후에는 ID를 변경할 수 없습니다.

온라인 엔드포인트를 만들 때 기본적으로 엔드포인트에 대한 시스템이 할당한 관리 ID가 만들어집니다.

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

다음을 사용하여 엔드포인트의 상태를 확인합니다.

az ml online-endpoint show --name $ENDPOINT_NAME

문제가 발생하는 경우 온라인 엔드포인트 배포 및 채점 문제 해결을 참조하세요.

관리 ID에 대한 액세스 권한 부여

Important

온라인 엔드포인트에는 Azure Container Registry 끌어오기 권한, 컨테이너 레지스트리에 대한 AcrPull 권한 및 작업 영역의 기본 데이터 저장소에 대한 Storage Blob 데이터 읽기 권한자 권한이 필요합니다.

온라인 엔드포인트 권한이 시스템이 할당한 관리 ID를 통해 스토리지에 액세스하도록 허용하거나 사용자가 할당한 관리 ID에 이전 섹션에서 만든 스토리지 계정에 액세스할 수 있는 권한을 부여할 수 있습니다.

엔드포인트에 대해 생성된 시스템이 할당한 관리 ID를 검색합니다.

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

여기서 시스템 할당 관리 ID에 스토리지 액세스 권한을 부여할 수 있습니다.

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

Azure 리소스에 액세스하는 채점 스크립트

ID 토큰을 사용하여 Azure 리소스(이 시나리오에서는 이전 섹션에서 만든 스토리지 계정)에 액세스하는 방법을 이해하려면 다음 스크립트를 참조하세요.

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

구성을 사용하여 배포 만들기

온라인 엔드포인트와 연결된 배포를 만듭니다. 온라인 엔드포인트 배포에 대해 자세히 알아봅니다.

Warning

이 배포는 기본 환경/이미지가 처음으로 빌드되는지 여부에 따라 약 8-14분이 걸릴 수 있습니다. 동일한 환경을 사용하는 후속 배포는 더 빨라집니다.

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

참고 항목

--name 인수의 값은 YAML 파일 내부의 name 키를 재정의할 수 있습니다.

배포 상태를 확인합니다.

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

특정 데이터만 반환하도록 위의 쿼리를 구체화하려면 Azure CLI 명령 출력 쿼리를 참조하세요.

참고 항목

채점 스크립트의 init 메서드는 시스템이 할당한 관리 ID 토큰을 사용하여 스토리지 계정에서 파일을 읽습니다.

init 메서드 출력을 확인하려면 다음 코드를 사용하여 배포 로그를 살펴봅니다.

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

배포가 완료되면 모델, 환경 및 엔드포인트가 Azure Machine Learning 작업 영역에 등록됩니다.

엔드포인트 테스트

온라인 엔드포인트가 배포되면 요청을 사용하여 작업을 테스트하고 확인합니다. 추론 세부 정보는 모델마다 다릅니다. 이 가이드의 경우 JSON 쿼리 매개 변수는 다음과 같습니다.

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

엔드포인트를 호출하려면 다음을 실행합니다.

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

엔드포인트 및 스토리지 계정 삭제

배포된 온라인 엔드포인트 및 스토리지를 계속 사용할 계획이 없으면 삭제하여 비용을 절감합니다. 엔드포인트를 삭제하면 연결된 모든 배포도 삭제됩니다.

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