다음을 통해 공유


자습서: Azure Container Apps에서 Python 웹앱에 대한 지속적인 배포 구성

이 기사는 Azure Container Apps에 Python 웹앱을 컨테이너화하고 배포하는 방법에 관한 자습서 시리즈의 일부입니다. Container Apps를 사용하면 복잡한 인프라를 관리하지 않고 컨테이너화된 앱을 배포할 수 있습니다.

이 자습서에서는 다음을 수행합니다.

  • GitHub Actions 워크플로를 사용하여 컨테이너 앱에 대한 지속적인 배포를 구성합니다.
  • 샘플 리포지토리의 복사본을 변경하여 GitHub Actions 워크플로를 트리거합니다.
  • 지속적인 배포를 구성하는 데 발생할 수 있는 문제를 해결합니다.
  • 자습서 시리즈를 완료할 때 필요하지 않은 리소스를 제거합니다.

지속적인 배포는 앱 개발 워크플로의 자동화인 CI/CD(지속적인 통합 및 지속적인 업데이트)의 DevOps 사례와 관련이 있습니다.

다음 다이어그램에서는 이 자습서의 작업을 강조 표시합니다.

지속적인 배포에 대한 부분이 강조 표시된 Azure Container Apps에서 Python 앱을 배포하는 데 관련된 서비스의 다이어그램입니다.

필수 구성 요소

지속적인 배포를 설정하려면 다음이 필요합니다.

  • 이전 자습서에서 만든 리소스(및 해당 구성)Azure Container Registry 인스턴스와 Azure Container Apps의 컨테이너 앱을 포함합니다.

  • GitHub 계정에서 샘플 코드를 포크(Django 또는 Flask )하여 Azure Container Apps에서 연결할 수 있는 계정입니다. ("포크하는 대신 샘플 코드를 다운로드한 경우, 로컬 리포지토리를 GitHub 계정에 푸시해야 합니다.")

  • 필요에 따라, 개발 환경에 Git을 설치하여 코드 변경을 하고 GitHub의 리포지토리로 푸시할 수 있습니다. 또는 GitHub에서 직접 변경할 수 있습니다.

컨테이너에 대한 지속적인 배포 구성

이전 자습서에서는 Azure Container Apps에서 컨테이너 앱을 만들고 구성했습니다. 구성의 일부는 Azure Container Registry 인스턴스에서 Docker 이미지를 끌어와는 것이었습니다. 컨테이너 앱을 처음 설정하거나 컨테이너 수정을 생성할 때, 레지스트리에서 컨테이너 이미지를 가져옵니다.

이 섹션에서는 GitHub Actions 워크플로를 사용하여 지속적인 배포를 설정합니다. 연속 배포를 사용하면 트리거를 기반으로 새 Docker 이미지 및 컨테이너 수정 버전이 만들어집니다. 이 자습서의 트리거는 끌어오기 요청과 같이 리포지토리의 기본 분기에 대한 변경 내용입니다. 워크플로가 트리거되면 새 Docker 이미지를 만들고, Azure Container Registry 인스턴스로 푸시하고, 새 이미지를 사용하여 컨테이너 앱을 새 수정 버전으로 업데이트합니다.

Azure Cloud Shell 또는 Azure CLI 설치된 워크스테이션에서 Azure CLI 명령을 실행할 수 있습니다.

Windows 컴퓨터의 Git Bash 셸에서 명령을 실행하는 경우 계속하기 전에 다음 명령을 입력합니다.

export MSYS_NO_PATHCONV=1
  1. az ad sp create-for-rbac 명령을 사용하여 서비스 주체를 생성하세요.

    az ad sp create-for-rbac \
    --name <app-name> \
    --role Contributor \
    --scopes "/subscriptions/<subscription-ID>/resourceGroups/<resource-group-name>"
    

    명령에서:

    • <앱 이름> 서비스 주체의 선택적 표시 이름입니다. --name 옵션을 해제하면 GUID가 표시 이름으로 생성됩니다.
    • <구독 ID> Azure에서 구독을 고유하게 식별하는 GUID입니다. 구독 ID를 모르는 경우 az account show 명령을 실행하고 출력의 id 속성에서 복사할 수 있습니다.
    • <리소스 그룹 이름> Azure Container Apps 컨테이너를 포함하는 리소스 그룹의 이름입니다. RBAC(역할 기반 액세스 제어)는 리소스 그룹 수준에 있습니다. 이전 자습서의 단계를 수행한 경우 리소스 그룹의 이름은 pythoncontainer-rg.

    다음 단계를 위해 이 명령의 출력을 저장합니다. 특히 클라이언트 ID(appId 속성), 클라이언트 암호(password 속성) 및 테넌트 ID(tenant 속성)를 저장합니다.

  2. GitHub Actions를 구성하려면 az containerapp github-action add 명령을 사용하세요.

    az containerapp github-action add \
    --resource-group <resource-group-name> \
    --name python-container-app \
    --repo-url <https://github.com/userid/repo> \
    --branch main \
    --registry-url <registry-name>.azurecr.io \
    --service-principal-client-id <client-id> \
    --service-principal-tenant-id <tenant-id> \
    --service-principal-client-secret <client-secret> \
    --login-with-github
    

    명령에서:

    • <리소스 그룹 이름> 리소스 그룹의 이름입니다. 이 자습서에서는 pythoncontainer-rg이(가) 주제입니다.
    • <https://github.com/userid/repo> GitHub 리포지토리의 URL입니다. 이 자습서에서는 https://github.com/userid/msdocs-python-django-azure-container-apps 또는 https://github.com/userid/msdocs-python-flask-azure-container-apps중 하나입니다. 이러한 URL에서 userid GitHub 사용자 ID입니다.
    • <레지스트리 이름> 이전 자습서에서 만든 기존 Azure Container Registry 인스턴스이거나 사용할 수 있는 인스턴스입니다.
    • <클라이언트 ID> 이전 appId 명령의 az ad sp create-for-rbac 속성 값입니다. ID는 00000000-0000-0000-0000-00000000형식의 GUID입니다.
    • <tenant-id>는 이전 tenant 명령의 az ad sp create-for-rbac 속성 값입니다. ID는 클라이언트 ID와 유사한 GUID이기도 합니다.
    • <클라이언트 시크릿>은 이전 password 명령어에서 az ad sp create-for-rbac 속성의 값입니다.

연속 배포 구성에서 서비스 주체 GitHub Actions가 Azure 리소스에 액세스하고 수정할 수 있도록 합니다. 서비스 주체에 할당된 역할은 리소스에 대한 액세스를 제한합니다. 서비스 주체에게 컨테이너 앱을 포함한 리소스 그룹에 대해 내장된 기여자 역할을 할당했습니다.

포털에 대한 단계를 따른 경우 서비스 원칙이 자동으로 생성되었습니다. Azure CLI에 대한 단계를 수행한 경우 연속 배포를 구성하기 전에 서비스 주체를 명시적으로 만들었습니다.

GitHub Actions를 사용하여 웹앱 다시 배포

이 섹션에서는 샘플 리포지토리의 포크된 복사본을 변경합니다. 그런 다음 변경 내용이 웹 사이트에 자동으로 배포되는 것을 확인할 수 있습니다.

아직 하지 않았다면, 샘플 리포지토리(Django 또는 Flask)의 포크를 생성하세요. GitHub에서 또는 명령줄을 통해 개발 환경에서 Git을(를) 사용하여 코드를 직접 변경할 수 있습니다.

  1. 샘플 리포지토리의 본인 포크로 이동하여 main 브랜치에서 시작합니다.

    샘플 리포지토리의 포크에 있는 메인 브랜치를 보여 주는 스크린샷

  2. 변화를 주세요.

    1. /templates/base.html 파일로 이동합니다. (Django의 경우 경로는 restaurant_review/templates/restaurant_review/base.html.)
    2. 을 선택하고를 편집한 다음 구 Azure Restaurant ReviewAzure Restaurant Review - Redeployed으로 변경합니다.

    샘플 리포지토리의 포크에서 템플릿 파일을 변경하는 방법을 보여 주는 스크린샷

  3. 편집 중인 페이지 아래쪽에서 주요 분기에 직접 커밋이 선택되어 있는지 확인합니다. 그런 다음 변경 내용 적용 단추를 선택합니다.

    샘플 리포지토리의 포크에 있는 템플릿 파일의 변경 내용을 커밋하기 위한 선택 항목을 보여 주는 스크린샷

커밋은 GitHub Actions 워크플로를 시작합니다.

메모

이 자습서에서는 메인 브랜치에서 직접 변경하는 방법을 보여줍니다. 일반적인 소프트웨어 워크플로에서는 메인 외의 분기에서 변경을 하고, 그런 다음 끌어오기 요청을 만들어 변경 사항을 메인에 병합합니다. Pull 요청도 워크플로를 시작합니다.

GitHub Actions을 이해하기 위한 가이드

워크플로 기록 보기

워크플로 기록을 확인해야 하는 경우 다음 절차 중 하나를 사용합니다.

GitHub에서 샘플 리포지토리의 포크로 이동하여 Actions 탭을 엽니다.

리포지토리의 작업 탭에서 워크플로를 보여주는 스크린샷

워크플로 비밀

리포지토리에 추가된 .github/workflows/<워크플로 이름>.yml 워크플로 파일에는 워크플로의 빌드 및 컨테이너 앱 업데이트 작업에 필요한 자격 증명에 대한 자리 표시자가 포함됩니다. 자격 증명 정보는 암호화되어 리포지토리의 설정 영역, 보안>비밀 및 변수>작업에 저장됩니다.

자격 증명을 GitHub Actions 비밀로 보여주는 스크린샷

자격 증명 정보가 변경되면 여기에서 업데이트할 수 있습니다. 예를 들어 Azure Container Registry 암호가 다시 생성되는 경우 REGISTRY_PASSWORD 값을 업데이트해야 합니다. 자세한 내용은 GitHub 설명서의 암호화된 비밀 참조하세요.

OAuth 권한 있는 앱

지속적인 배포를 설정할 때 Azure Container Apps를 GitHub 계정에 대한 권한 있는 OAuth 앱으로 지정합니다. Container Apps는 권한 있는 액세스를 사용하여 .github/workflows/<워크플로 이름>.ymlGitHub Actions YAML 파일을 만듭니다. Integrations>애플리케이션에서 허가된 앱을 확인하고 계정에서 권한을 취소할 수 있습니다.

GitHub에서 사용자에 대한 권한 있는 앱의 위치를 보여 주는 스크린샷

문제 해결

Azure CLI를 통해 서비스 주체를 설정하는 동안 오류가 발생합니다.

이 섹션에서는 Azure CLI az ad sp create-for-rba 명령을 사용하여 서비스 주체를 설정하는 동안 발생하는 오류를 해결하는 데 도움이 될 수 있습니다.

"InvalidSchema: 연결 어댑터를 찾을 수 없음"이 포함된 오류가 발생하는 경우:

  • 실행 중인 셸을 확인하세요. Bash 셸을 사용하는 경우 MSYS_NO_PATHCONV 변수를 export MSYS_NO_PATHCONV=1로 설정합니다.

    자세한 내용은 GitHub 문제 Git Bash 셸Azure CLI를 사용하여 서비스 주체를 만들 수 없음을 참조하세요.

"둘 이상의 애플리케이션에 동일한 표시 이름이 있습니다."가 포함된 오류가 발생하는 경우:

  • 서비스 주체에 대한 이 이름은 이미 사용 중입니다. 다른 이름을 선택하거나 --name 인수를 그대로 둡니다. GUID는 표시 이름으로 자동으로 생성됩니다.

GitHub Actions 워크플로 실패

워크플로의 상태를 확인하려면 리포지토리의 작업 탭으로 이동합니다.

  • 실패한 워크플로가 있는 경우 워크플로 파일을 자세히 살펴봅니다. 빌드 및 배포의 두 가지 작업이 있어야 합니다. 실패한 작업의 경우 작업의 출력을 확인하여 문제를 찾습니다.
  • "TLS 핸드셰이크 시간 제한"이 포함된 오류 메시지가 있는 경우 워크플로를 수동으로 실행합니다. 리포지토리의 작업 탭에서 자동 배포 시작을 선택하여 시간 제한 문제가 일시적인지 확인합니다.
  • 이 자습서와 같이 컨테이너 앱에 대한 지속적인 배포를 설정하는 경우 워크플로 파일(.github/workflows/<workflow-name>.yml)이 자동으로 만들어집니다. 이 자습서에서는 이 파일을 수정할 필요가 없습니다. 그렇게 한 경우에, 변경 내용을 되돌리고 워크플로를 시도해 보세요.

웹 사이트에 메인 브랜치에서 병합한 변경 내용이 표시되지 않습니다.

GitHub에서:

  • GitHub Actions 워크플로가 실행되었고 워크플로를 트리거하는 분기에 변경 내용이 있는지 확인합니다.

Azure Portal에서 다음을 수행합니다.

  • 브랜치를 변경한 후 새 Docker 이미지가 생성되었는지 확인하려면, 변경 후의 타임스탬프를 확인하여 Azure Container Registry 인스턴스를 점검하십시오.

  • 컨테이너 앱의 로그를 확인하여 프로그래밍 오류가 있는지 확인합니다.

    1. 컨테이너 앱으로 이동한 다음, 수정 관리><활성 컨테이너로 이동하여>>수정 버전 세부 정보와>콘솔 로그를 확인합니다.
    2. 시간 생성, Stream_sLog_s표시할 열의 순서를 선택합니다.
    3. 로그를 가장 최근으로 정렬하고 stderr 열에서 Python stdout 메시지를 찾습니다. Python print 출력은 stdout 메시지입니다.

Azure CLI에서:

지속적인 배포를 중지하려고 합니다.

지속적인 배포 중지는 리포지토리에서 컨테이너 앱의 연결을 끊는 것을 의미합니다.

Azure Portal에서 다음을 수행합니다.

  • 컨테이너 앱으로 이동합니다. 서비스 메뉴에서 연속 배포선택한 다음 연결 끊기선택합니다.

Azure CLI에서:

연결을 끊은 후:

  • .github/workflows/<워크플로 이름>.yml 파일이 리포지토리에서 제거됩니다.
  • 비밀 키는 리포지토리에서 제거되지 않습니다.
  • Azure Container Apps는 GitHub 계정에 대한 권한 있는 OAuth 앱으로 유지됩니다.
  • Azure에서 컨테이너는 마지막으로 배포된 컨테이너와 함께 남아 있습니다. 새 컨테이너 수정 버전이 최신 이미지를 선택하게 되도록 컨테이너 앱을 Azure Container Registry 인스턴스와 다시 연결할 수 있습니다.
  • Azure에서 연속 배포에 만들고 사용한 서비스 주체는 삭제되지 않습니다.

리소스 제거

자습서 시리즈를 마쳤으며 추가 비용이 발생하지 않으려면 사용한 리소스를 제거합니다.

리소스 그룹을 제거하면 그룹의 모든 리소스가 제거되며 리소스를 제거하는 가장 빠른 방법입니다. 리소스 그룹을 제거하는 방법의 예는 Containerize 튜토리얼 정리참조하십시오.

이 자습서를 빌드하려는 경우 수행할 수 있는 다음 단계는 다음과 같습니다.