다음을 통해 공유


App Service에 컨테이너화된 Python 앱 배포

자습서 시리즈의 이 부분에서는 컨테이너화된 Python 웹 애플리케이션을 Azure App Service Web App for Containers에 배포하는 방법을 알아봅니다. 이 완전 관리형 서비스를 사용하면 자체 컨테이너 오케스트레이터를 유지 관리하지 않고도 컨테이너화된 앱을 실행할 수 있습니다.

App Service는 Docker Hub, Azure Container Registry, Azure Key Vault 및 기타 DevOps 도구에서 작동하는 CI/CD(지속적인 통합/지속적인 배포) 파이프라인을 통해 배포를 간소화합니다. 이 자습서는 5부로 구성된 자습서 시리즈의 4부입니다.

이 문서의 끝부분에는 Docker 컨테이너 이미지에서 실행되는 안전한 프로덕션 준비 App Service 웹앱이 있습니다. 앱은 시스템 할당 관리 ID 를 사용하여 Azure Container Registry에서 이미지를 가져오고 Azure Key Vault에서 비밀을 검색합니다.

이 서비스 다이어그램은 이 문서에서 다루는 구성 요소를 강조 표시합니다.

Azure에서 컨테이너화된 Python 앱 자습서에 사용되는 서비스의 스크린샷으로, 배포 경로가 강조 표시되어 있습니다.

Azure CLI 명령은 Azure Cloud Shell 또는 AzureCLI가 설치된 로컬 컴퓨터에서 실행할 수 있습니다.

중요하다

이 자습서에서는 다음과 같은 이유로 모든 CLI 기반 단계에 Azure Cloud Shell 을 사용하는 것이 좋습니다.

  • Azure 계정으로 미리 인증되어 로그인 문제를 방지합니다.
  • 모든 필수 Azure CLI 확장을 기본으로 포함합니다.
  • 로컬 OS 또는 환경에 관계없이 일관된 동작을 보장합니다.
  • 로컬 설치가 필요하지 않으며 관리자 권한이 없는 사용자에게 적합합니다.
  • 포털에서 Azure 서비스에 대한 직접 액세스를 제공합니다. 로컬 Docker 또는 네트워크 설정이 필요하지 않습니다.
  • 로컬 방화벽 또는 네트워크 구성 문제를 방지합니다.

RBAC 권한 부여를 사용하여 Key Vault 만들기

Azure Key Vault는 비밀, API 키, 연결 문자열 및 인증서를 저장하기 위한 보안 서비스입니다. 이 스크립트에서는 MongoDB 연결 문자열 과 웹앱의 SECRET_KEY문자열을 저장합니다.

Key Vault는 RBAC(역할 기반 액세스 제어) 를 사용하여 기존 액세스 정책 대신 Azure 역할을 통해 액세스를 관리하도록 구성됩니다. 웹앱은 시스템 할당 관리 ID 를 사용하여 런타임에 비밀을 안전하게 검색합니다.

메모

Key Vault를 일찍 만들면 비밀에 액세스하기 전에 역할을 할당할 수 있습니다. 또한 역할 할당의 전파 지연을 방지하는 데 도움이 됩니다. Key Vault는 App Service에 의존하지 않으므로 초기에 프로비전하면 안정성과 시퀀싱이 향상됩니다.

  1. 이 단계에서는 az keyvault create 명령을 사용하여 RBAC를 사용하도록 설정된 Azure Key Vault를 만듭니다.

    #!/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
    

App Service 계획 및 웹앱 만들기

App Service 계획은 웹앱에 대한 컴퓨팅 리소스, 가격 책정 계층 및 지역을 정의합니다. 웹앱은 컨테이너화된 애플리케이션을 실행하고 ACR(Azure Container Registry) 및 Azure Key Vault에 안전하게 인증하는 데 사용되는 시스템 할당 관리 ID로 프로비전됩니다.

이 단계에서는 다음 작업을 수행합니다.

  • App Service 계획 만들기
  • 관리 ID를 사용하여 웹앱 만들기
  • 특정 컨테이너 이미지를 사용하여 배포하도록 웹앱 구성
  • ACR을 통한 지속적인 배포 준비

메모

관리 ID는 배포 시에만 생성되므로 ACR 또는 Key Vault에 대한 액세스를 할당하기 전에 웹앱을 만들어야 합니다. 또한 만드는 동안 컨테이너 이미지를 할당하면 앱이 의도한 구성으로 올바르게 시작됩니다.

  1. 이 단계에서는 az appservice plan create 명령을 사용하여 앱에 대한 컴퓨팅 환경을 프로비전합니다.

    #!/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. 이 단계에서는 az webapp create 명령을 사용하여 웹앱을 만듭니다. 또한 이 명령은 시스템 할당 관리 ID 를 사용하도록 설정하고 앱이 실행되는 컨테이너 이미지를 설정합니다.

    #!/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" 
    

    메모

    이 명령을 실행할 때 다음 오류가 표시 될 수 있습니다.

    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.'
    

    이 오류는 웹앱이 관리자 자격 증명을 사용하여 기본적으로 사용하지 않도록 설정된 ACR에 액세스하려고 하기 때문에 발생합니다. 이 메시지는 무시해도 안전합니다. 다음 단계에서는 관리 ID를 사용하여 ACR로 인증하도록 웹앱을 구성합니다.

로그인한 사용자에게 비밀 책임자 역할 부여

Azure Key Vault에 비밀을 저장하려면 스크립트를 실행하는 사용자에게 Key Vault 비밀 책임자 역할이 있어야 합니다. 이 역할은 보관소 내에서 비밀을 만들고 관리할 수 있게 합니다.

이 단계에서 스크립트는 현재 로그인한 사용자에게 해당 역할을 할당합니다. 그런 다음, 이 사용자는 MongoDB 연결 문자열 및 앱 SECRET_KEY과 같은 애플리케이션 비밀을 안전하게 저장할 수 있습니다.

이 역할 할당은 두 개의 Key Vault 관련 역할 할당 중 첫 번째 역할 할당입니다. 이후, 웹앱의 시스템 할당된 관리 ID에 비밀 저장소에서 시크릿을 검색할 수 있는 액세스 권한이 부여됩니다.

Azure RBAC를 사용하면 ID에 따라 안전하고 감사 가능한 액세스가 보장되어 하드 코딩된 자격 증명이 필요하지 않습니다.

메모

키 자격 증명 모음에 비밀을 저장하기 전에 사용자에게 Key Vault 비밀 책임자 역할이 지정되어야 합니다. 이 할당은 Key Vault로 범위가 지정된 az role assignment create 명령을 사용하여 수행됩니다.

  1. 이 단계에서는 az role assignment create 명령을 사용하여 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"
    
    

관리 ID를 사용하여 ACR에 대한 웹 액세스 권한 부여

ACR(Azure Container Registry)에서 이미지를 안전하게 끌어오려면 시스템 할당 관리 ID를 사용하도록 웹앱을 구성해야 합니다. 관리 ID를 사용하면 관리자 자격 증명이 필요하지 않으며 보안 자격 증명이 없는 배포를 지원합니다.

이 프로세스에는 다음 두 가지 주요 작업이 포함됩니다.

  • ACR에 액세스할 때 웹앱에서 해당 관리 ID를 사용하도록 설정
  • 대상 ACR에서 해당 ID에 AcrPull 역할 할당
  1. 이 단계에서는 az webapp identity show 명령을 사용하여 웹앱의 관리 ID의 주체 ID(고유 개체 ID)를 검색합니다. 다음으로, acrUseManagedIdentityCreds을 사용하여 true 속성을 로 설정하여 ACR 인증에 관리 ID를 사용할 수 있도록 합니다. 그런 다음 az role assignment create 명령을 사용하여 AcrPull 역할을 웹앱의 관리 ID에 할당합니다. 이 역할은 레지스트리에서 이미지를 끌어올 수 있는 권한을 웹앱에 부여합니다.

    #!/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"
    
    

웹앱의 관리 ID에 대한 키 자격 증명 모음 액세스 권한 부여

웹앱에는 MongoDB 연결 문자열 및 와 같은 비밀에 액세스할 수 있는 SECRET_KEY권한이 필요합니다. 이러한 권한을 부여하려면 Key Vault 비밀 사용자 역할을 웹앱의 시스템 할당 관리 ID에 할당해야 합니다.

  1. 이 단계에서는 웹앱의 시스템 할당 관리 ID의 고유 식별자(주체 ID)를 사용하여 Key Vault Secrets User 역할로 웹앱이 Key Vault에 액세스할 수 있도록 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"
    

Key Vault에 비밀 저장

애플리케이션의 비밀 하드코딩을 방지하기 위해 이 단계에서는 MongoDB 연결 문자열 과 웹앱의 비밀 키를 Azure Key Vault에 저장합니다. 그런 다음, 코드 또는 구성에 자격 증명을 저장하지 않고도 관리 ID를 통해 런타임에 웹앱에서 이러한 비밀에 안전하게 액세스할 수 있습니다.

메모

이 자습서에서는 키 자격 증명 모음에 연결 문자열 및 비밀 키만 저장하지만 필요에 따라 MongoDB 데이터베이스 이름 또는 컬렉션 이름과 같은 다른 애플리케이션 설정도 Key Vault에 저장할 수 있습니다.

  1. 이 단계에서는 az cosmosdb 키 목록 명령을 사용하여 MongoDB 연결 문자열을 검색합니다. 그런 다음 az keyvault secret set 명령을 사용하여 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"
    

Kay Vault 비밀을 사용하도록 웹앱 구성

런타임에 안전하게 비밀에 액세스하려면 Azure Key Vault에 저장된 비밀을 참조하도록 웹앱을 구성해야 합니다. 이 단계는 시스템 할당 관리 ID를 통해 앱의 환경에 비밀 값을 삽입하는 Key Vault 참조를 사용하여 수행됩니다.

이 방법을 사용하면 비밀 하드코딩을 방지하고 실행 중에 MongoDB 연결 문자열 및 비밀 키와 같은 중요한 값을 앱에서 안전하게 검색할 수 있습니다.

  1. 이 단계에서는 az webapp config appsettings set 명령을 사용하여 Key Vault 비밀을 참조하는 애플리케이션 설정을 추가합니다. 특히 MongoConnectionStringMongoSecretKey 앱 설정을 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"
    

ACR에서 연속 배포 활성화

연속 배포를 사용하도록 설정하면 웹앱이 ACR(Azure Container Registry)에 푸시될 때마다 최신 컨테이너 이미지를 자동으로 끌어오고 실행할 수 있습니다. 이렇게 하면 수동 배포 단계가 줄어들고 앱이 최신 상태로 유지됩니다.

메모

다음 단계에서는 새 이미지가 푸시될 때 웹앱에 알리기 위해 ACR에 웹후크를 등록합니다.

  1. 이 단계에서는 az webapp deployment container config 명령을 사용하여 ACR에서 웹앱으로 연속 배포를 사용하도록 설정합니다.

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

지속적인 배포를 위해 ACR 웹후크 등록

배포를 자동화하려면 새 컨테이너 이미지가 푸시될 때마다 웹앱에 알리도록 ACR(Azure Container Registry)에 웹후크를 등록합니다. 웹후크를 사용하면 앱이 자동으로 최신 버전을 끌어오고 실행할 수 있습니다.

ACR(Azure Container Registry)에 구성된 웹후크는 새 이미지가 msdocspythoncontainerwebapp 리포지토리에 푸시될 때마다 웹앱의 SCM 엔드포인트(SERVICE_URI)에 POST 요청을 보냅니다. 이 작업은 ACR과 Azure App Service 간의 연속 배포 파이프라인을 완료하여 업데이트된 이미지를 끌어오고 배포하도록 웹앱을 트리거합니다.

메모

웹후크 URI는 다음 형식을 따라야 합니다.
https://<app-name>.scm.azurewebsites.net/api/registry/webhook

로 끝나/api/registry/webhook. URI 오류가 표시되면 경로가 올바른지 확인합니다.

  1. 이 단계에서는 az acr webhook create 명령을 사용하여 웹후크를 등록하고 이벤트에서 트리거 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
    
    

사이트 둘러보기

웹앱이 실행 중인지 확인하려면, https://<website-name>.azurewebsites.net을(를) App Service의 이름으로 바꿔서 <website-name>을(를) 엽니다. 당신은 식당 리뷰 샘플 앱을 확인해야 합니다. 처음 로드하는 데 몇 분 정도 걸릴 수 있습니다.

사이트가 나타나면 레스토랑을 추가하고 검토를 제출하여 앱이 제대로 작동하는지 확인합니다.

메모

az webapp browse 명령은 Cloud Shell에서 지원되지 않습니다. Cloud Shell을 사용하는 경우 브라우저를 수동으로 열고 사이트 URL로 이동합니다.

Azure CLI를 로컬로 사용하는 경우 az webapp browse 명령을 사용하여 기본 브라우저에서 사이트를 열 수 있습니다.

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

메모

az webapp browse 명령은 Cloud Shell에서 지원되지 않습니다. 브라우저 창을 열고 대신 웹 사이트 URL로 이동합니다.

배포 문제 해결

샘플 앱이 표시되지 않으면 다음 단계를 시도합니다.

  • 컨테이너 배포 및 App Service를 사용할 때는 항상 Azure 포털에서 배포 센터 / 로그 페이지를 확인하세요. 컨테이너가 풀링되고 실행 중인지 확인합니다. 컨테이너의 초기 끌어오기 및 실행은 몇 분 정도 걸릴 수 있습니다.
  • App Service를 다시 시작하고 문제가 해결되는지 확인합니다.
  • 프로그래밍 오류가 있는 경우 해당 오류가 애플리케이션 로그에 표시됩니다. Azure Portal의 App Service 페이지에서 진단 및 문제 해결/애플리케이션 로그를 선택합니다.
  • 샘플 앱은 MongoDB용 Azure Cosmos DB에 대한 연결을 사용합니다. App Service에 올바른 연결 정보가 있는 애플리케이션 설정이 있는지 확인합니다.
  • 관리 ID가 App Service에 대해 사용하도록 설정되어 있고 배포 센터에서 사용되는지 확인합니다. Azure 포털의 App Service 페이지에서 App Service 배포 센터 리소스로 이동하여 인증이/가 관리 ID으로 설정되었는지 확인합니다.
  • 웹후크가 Azure Container Registry에 정의되어 있는지 확인합니다. 웹후크를 사용하면 App Service에서 컨테이너 이미지를 끌어올 수 있습니다. 특히 서비스 URI가 "/api/registry/webhook"로 끝나는지 확인합니다. 그렇지 않은 경우 추가합니다.
  • 다른 Azure Container Registry SKU는 웹후크 수를 포함한 다양한 기능을 가지고 있습니다. 기존 레지스트리를 다시 사용하는 경우 다음과 같은 메시지가 표시될 수 있습니다. "레지스트리 SKU Basic의 리소스 종류 웹후크에 대한 할당량이 초과되었습니다. 다양한 SKU 할당량 및 업그레이드 프로세스에 대해 자세히 알아보세요. https://aka.ms/acr/tiers". 이 메시지가 표시되면 새 레지스트리를 사용하거나 사용 중인 레지스트리 웹후크의 수를 줄입니다.

다음 단계