Share via


Azure Container Apps에서 첫 번째 컨테이너화된 함수 만들기

이 문서에서는 Linux 컨테이너에서 실행되는 함수 앱을 만들고 컨테이너 레지스트리에서 Azure Container Apps 환경에 배포합니다. Container Apps에 배포하면 함수 앱을 클라우드 네이티브 마이크로 서비스에 통합할 수 있습니다. 자세한 내용은 Azure Functions의 Azure Container Apps 호스팅을 참조하세요.

이 문서에서는 Linux 컨테이너에서 실행되는 함수를 만들고 컨테이너를 Container Apps 환경에 배포하는 방법을 보여 줍니다.

이 빠른 시작을 완료하면 Azure 계정에서 몇 USD 몇 센트 이하의 소액이 발생하므로 완료되면 리소스를 정리하여 최소화할 수 있습니다.

Important

Azure Container Apps에서 함수 앱 호스팅에 대한 지원은 현재 미리 보기로 제공됩니다.

개발 언어 선택

먼저 Azure Functions 도구를 사용하여 언어별 Linux 기본 이미지를 사용하여 Docker 컨테이너에서 함수 앱으로 프로젝트 코드를 만듭니다. 문서 상단에서 원하는 언어를 선택하세요.

Core Tools는 함수 언어에 가장 최신 버전의 올바른 기본 이미지를 사용하는 프로젝트에 대한 Dockerfile을 자동으로 생성합니다. 최신 기본 이미지에서 컨테이너를 정기적으로 업데이트하고 업데이트된 버전의 컨테이너에서 다시 배포해야 합니다. 자세한 내용은 컨테이너화된 함수 앱 만들기를 참조하세요.

필수 조건

시작하기 전에 다음과 같은 요구 사항이 있어야 합니다.

Azure를 구독하고 있지 않다면 시작하기 전에 Azure 체험 계정을 만듭니다.

만든 컨테이너화된 함수 앱 이미지를 컨테이너 레지스트리에 게시하려면 로컬 컴퓨터에서 실행되는 Docker ID 및 Docker가 필요합니다. Docker ID가 없는 경우 Docker 계정을 만들 수 있습니다.

또한 Container Registry 빠른 시작의 컨테이너 레지스트리 만들기 섹션을 완료하여 레지스트리 인스턴스를 만들어야 합니다. 정규화된 로그인 서버 이름을 기록해 두세요.

가상 환경 만들기 및 활성화

적절한 폴더에서 다음 명령을 실행하여 .venv라는 가상 환경을 만들고 활성화합니다. Azure Functions에서 지원하는 Python 버전 중 하나를 사용해야 합니다.

python -m venv .venv
source .venv/bin/activate

Python에서 venv 패키지를 Linux 배포에 설치하지 않은 경우 다음 명령을 실행합니다.

sudo apt-get install python3-venv

활성화된 가상 환경에서 이후의 모든 명령을 실행합니다.

로컬 함수 프로젝트 만들기 및 테스트

터미널 또는 명령 프롬프트에서 선택한 언어에 대해 다음 명령을 실행하여 함수 앱 프로젝트를 현재 폴더에 만듭니다.

func init --worker-runtime dotnet-isolated --docker
func init --worker-runtime node --language javascript --docker
func init --worker-runtime powershell --docker
func init --worker-runtime python --docker
func init --worker-runtime node --language typescript --docker

빈 폴더에서 다음 명령을 실행하여 Maven archetype으로부터 Functions 프로젝트를 생성합니다.

mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8 -Ddocker

-DjavaVersion 매개 변수는 함수 런타임에 사용할 Java 버전을 알려줍니다. Java 11에서 함수를 실행하려면 -DjavaVersion=11을 사용합니다. -DjavaVersion을 지정하지 않으면 Maven은 기본적으로 Java 8로 설정됩니다. 자세한 내용은 Java 버전을 참조하세요.

Important

이 문서를 완료하려면 JAVA_HOME 환경 변수를 올바른 버전의 JDK 설치 위치로 설정해야 합니다.

Maven은 배포 시 프로젝트 생성 완료를 위해 필요한 값을 요청합니다. 프롬프트에 따라 다음 정보를 제공합니다.

prompt 설명
groupId com.fabrikam Java에 대한 패키지 명명 규칙에 따라 모든 프로젝트에서 프로젝트를 고유하게 식별하는 값입니다.
artifactId fabrikam-functions 버전 번호가 없는 jar의 이름인 값입니다.
version 1.0-SNAPSHOT 기본값을 선택합니다.
패키지 com.fabrikam.functions 생성된 함수 코드에 대한 Java 패키지인 값입니다. 기본값을 사용하세요.

Y를 입력하거나 Enter 키를 눌러 확인합니다.

Maven은 새 폴더에 artifactId라는 프로젝트 파일을 만드는데, 이 예제에서는 fabrikam-functions입니다.

--docker 옵션은 프로젝트에 대한 Dockerfile을 생성하는데, 이는 Azure Functions 및 선택한 런타임에서 사용하는 데 적합한 컨테이너를 정의합니다.

프로젝트 폴더로 이동합니다.

cd fabrikam-functions

다음 명령을 사용하여 함수를 프로젝트에 추가합니다. 여기서 --name 인수는 함수의 고유한 이름이고, --template 인수는 함수의 트리거를 지정합니다. func new는 프로젝트에 C# 코드 파일을 만듭니다.

func new --name HttpExample --template "HTTP trigger" --authlevel anonymous

다음 명령을 사용하여 함수를 프로젝트에 추가합니다. 여기서 --name 인수는 함수의 고유한 이름이고, --template 인수는 함수의 트리거를 지정합니다. func newfunction.json이라는 구성 파일을 포함하는 함수 이름과 일치하는 하위 폴더를 만듭니다.

func new --name HttpExample --template "HTTP trigger" --authlevel anonymous

함수를 로컬로 테스트하려면 프로젝트 폴더의 루트에서 로컬 Azure Functions 런타임 호스트를 시작합니다.

func start  
func start  
npm install
npm start
mvn clean package  
mvn azure-functions:run

출력에 기록된 HttpExample 엔드포인트를 확인한 후 해당 엔드포인트로 이동합니다. 응답 출력에 환영 메시지가 표시됩니다.

출력에 기록된 HttpExample 엔드포인트를 확인한 후 http://localhost:7071/api/HttpExample?name=Functions로 이동합니다. 브라우저에서 name 쿼리 매개 변수에 제공된 값인 Functions를 다시 에코하는 "hello" 메시지를 표시해야 합니다.

Ctrl+C(macOS의 경우 Command+C)를 눌러 호스트를 중지합니다.

컨테이너 이미지 빌드 및 로컬로 확인

(선택 사항) 프로젝트 폴더의 루트에서 Dockerfile을 검사합니다. Dockerfile은 Linux에서 함수 앱을 실행하는 데 필요한 환경을 설명합니다. Azure Functions에 대해 지원되는 기본 이미지의 전체 목록은 Azure Functions 기본 이미지 페이지에 나와 있습니다.

루트 프로젝트 폴더에서 docker build 명령을 실행하고 이름으로 azurefunctionsimage, 태그로 v1.0.0를 입력합니다. <DOCKER_ID>를 Docker 허브 계정 ID로 바꿉니다. 이 명령은 컨테이너에 대한 Docker 이미지를 빌드합니다.

docker build --tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 .

명령이 완료되면 새 컨테이너를 로컬에서 실행할 수 있습니다.

빌드를 확인하려면 로컬 컨테이너에서 docker run 명령을 사용하여 이미지를 실행합니다. 이때 <DOCKER_ID>를 다시 Docker Hub 계정 ID로 다시 바꾸고 -p 8080:80로 포트 인수를 추가합니다.

docker run -p 8080:80 -it <DOCKER_ID>/azurefunctionsimage:v1.0.0

로컬 컨테이너에서 이미지가 시작되면 http://localhost:8080/api/HttpExample로 이동합니다. 이전과 동일한 인사 메시지가 표시되어야 합니다. 만든 HTTP 트리거 함수에 익명 권한 부여가 사용되기 때문에 액세스 키를 가져올 필요 없이 컨테이너에서 실행되는 함수를 호출할 수 있습니다. 자세한 내용은 권한 부여 키를 참조하세요.

로컬 컨테이너에서 이미지가 시작되면 http://localhost:8080/api/HttpExample?name=Functions로 이동합니다. 이전과 동일한 "hello" 메시지가 표시되어야 합니다. 만든 HTTP 트리거 함수에 익명 권한 부여가 사용되기 때문에 액세스 키를 가져올 필요 없이 컨테이너에서 실행되는 함수를 호출할 수 있습니다. 자세한 내용은 권한 부여 키를 참조하세요.

컨테이너에서 함수 앱을 확인한 후 Ctrl+C(macOS의 경우 Command+C)를 눌러 실행을 중지합니다.

레지스트리에 컨테이너 이미지 게시

컨테이너 이미지를 호스팅 환경에 배포할 수 있도록 하려면 컨테이너 레지스트리에 푸시해야 합니다.

Azure Container Registry는 컨테이너 이미지 및 관련 아티팩트를 빌드, 저장 및 관리하기 위한 프라이빗 레지스트리 서비스입니다. Azure 서비스에 컨테이너를 게시하려면 프라이빗 레지스트리 서비스를 사용해야 합니다.

  1. 다음 명령을 사용하여 레지스트리 인스턴스에 로그인합니다.

    az acr login --name <REGISTRY_NAME>
    

    이전 명령에서 <REGISTRY_NAME>을 Container Registry 인스턴스 이름으로 바꿉니다.

  2. 다음 명령을 사용하여 레지스트리 로그인 서버의 정규화된 이름으로 이미지에 태그를 지정합니다.

    docker tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 
    

    <LOGIN_SERVER>를 레지스트리 로그인 서버의 정규화된 이름으로 바꾸고 <DOCKER_ID>를 Docker ID로 바꿉니다.

  3. 다음 명령을 사용하여 레지스트리 인스턴스에 컨테이너를 푸시합니다.

    docker push <LOGIN_SERVER>/azurefunctionsimage:v1.0.0
    
  4. Functions가 사용자 이름 및 암호를 사용하여 레지스트리에 연결할 수 있도록 다음 명령을 사용하여 기본 제공 관리자 계정을 사용하도록 설정합니다.

    az acr update -n <REGISTRY_NAME> --admin-enabled true
    
  1. 다음 명령을 사용하여 Functions가 레지스트리에 연결해야 하는 관리자 사용자 이름 및 암호를 검색합니다.

    az acr credential show -n <REGISTRY_NAME> --query "[username, passwords[0].value]" -o tsv
    

    Important

    관리자 계정 사용자 이름 및 암호는 중요한 자격 증명입니다. 안전하게 저장하고 퍼블릭 리포지토리 같은 액세스 가능한 위치에 저장하지 않도록 합니다.

함수를 지원하는 Azure 리소스 만들기

컨테이너를 Azure에 배포하기 전에 다음 세 가지 리소스를 만들어야 합니다.

  • 리소스 그룹 - 관련 리소스에 대한 논리 컨테이너입니다.
  • 스토리지 계정 - 함수에 대한 상태 및 기타 정보를 유지 관리합니다.
  • Log Analytics 작업 영역을 사용하여 Azure Container Apps 환경을 만듭니다.

다음 명령을 사용하여 이러한 항목을 만듭니다.

  1. 아직 로그인하지 않은 경우 Azure에 로그인합니다.

    az login 명령을 선택하면 사용자가 Azure 계정에 로그인됩니다. 계정과 연결된 구독이 두 개 이상 있는 경우 az account set를 사용합니다.

  2. 다음 명령을 실행하여 Azure CLI를 최신 버전으로 업데이트합니다.

    az upgrade
    

    Azure CLI 버전이 최신 버전이 아닌 경우 설치가 시작됩니다. 업그레이드 방식은 운영 체제에 따라 달라집니다. 업그레이드가 완료된 후에 진행할 수 있습니다.

  3. Azure Container Apps 확장을 업그레이드하고 Container Apps에 필요한 네임스페이스를 등록하는 다음 명령을 실행합니다.

    az extension add --name containerapp --upgrade -y
    az provider register --namespace Microsoft.Web 
    az provider register --namespace Microsoft.App 
    az provider register --namespace Microsoft.OperationalInsights 
    
  4. AzureFunctionsContainers-rg라는 리소스 그룹을 만듭니다.

    az group create --name AzureFunctionsContainers-rg --location eastus
    

    az group create 명령은 미국 동부 지역에서 리소스 그룹을 만듭니다. 대신 가까운 지역을 사용하려는 경우 az account list-locations 명령에서 반환된 사용 가능한 지역 코드를 사용합니다. eastus 대신 사용자 지정 지역을 사용하도록 후속 명령을 수정해야 합니다. 현재 미리 보기에서 지원되는 지역만 사용할 수 있습니다.

  5. 워크로드 프로필을 사용하도록 설정된 Azure Container App 환경을 만듭니다.

    az containerapp env create --name MyContainerappEnvironment --enable-workload-profiles --resource-group AzureFunctionsContainers-rg --location eastus
    

    이 명령이 완료되려면 최대 10분이 소요될 수 있습니다.

  6. 범용 스토리지 계정을 리소스 그룹 및 지역에 만듭니다.

    az storage account create --name <STORAGE_NAME> --location eastus --resource-group AzureFunctionsContainers-rg --sku Standard_LRS
    

    az storage account create 명령은 스토리지 계정을 만듭니다.

    이전 예제에서 <STORAGE_NAME>을 사용자에게 적절하고 Azure Storage에서 고유한 이름으로 바꿉니다. 스토리지 이름은 3~24자의 숫자와 소문자만 포함해야 합니다. Standard_LRSFunctions에서 지원하는 범용 계정을 지정합니다.

  7. 계속하기 전에 이 명령을 사용하여 환경이 준비되었는지 확인합니다.

    az containerapp env show -n MyContainerappEnvironment -g AzureFunctionsContainers-rg
    

이미지를 사용하여 Azure에서 함수 앱 만들기 및 구성

Azure의 함수 앱은 Azure Container Apps 환경에서 함수 실행을 관리합니다. 이 섹션에서는 이전 섹션의 Azure 리소스를 사용하여 Container Apps 환경의 컨테이너 레지스트리에 있는 이미지에서 함수 앱을 만듭니다. 또한 필요한 Azure Storage 계정에 대한 연결 문자열을 사용하여 새 환경을 구성합니다.

az functionapp create 명령을 사용하여 Azure Container Apps에서 지원되는 새 관리형 환경에서 함수 앱을 만듭니다.

az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --runtime dotnet-isolated --image <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 --registry-server <LOGIN_SERVER> --registry-username <REGISTRY_NAME> --registry-password <ADMIN_PASSWORD> 
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --runtime node --image <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 --registry-server <LOGIN_SERVER> --registry-username <REGISTRY_NAME> --registry-password <ADMIN_PASSWORD> 
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --runtime java --image <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 --registry-server <LOGIN_SERVER> --registry-username <REGISTRY_NAME> --registry-password <ADMIN_PASSWORD> 
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --runtime powershell --image <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 --registry-server <LOGIN_SERVER> --registry-username <REGISTRY_NAME> --registry-password <ADMIN_PASSWORD> 
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --runtime python --image <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 --registry-server <LOGIN_SERVER> --registry-username <REGISTRY_NAME> --registry-password <ADMIN_PASSWORD> 
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --runtime node --image <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 --registry-server <LOGIN_SERVER> --registry-username <REGISTRY_NAME> --registry-password <ADMIN_PASSWORD> 

az functionapp create 명령에서 --environment 매개 변수는 Container Apps 환경을 지정하고 --image 매개 변수는 함수 앱에 사용할 이미지를 지정합니다. 이 예제에서는 <STORAGE_NAME>을 이전 섹션에서 스토리지 계정에 대해 사용한 이름으로 바꿉니다. 또한 <APP_NAME>을(를) 적절한 전역적으로 고유하면서도 적절한 이름으로, <LOGIN_SERVER>을(를) 정규화된 Container Registry 서버로, <REGISTRY_NAME>을(를) 계정에 대한 레지스트리 이름으로, <ADMIN_PASSWORD>을(를) 관리자 계정에 대한 암호로 바꿉니다.

Important

관리자 계정 사용자 이름 및 암호는 중요한 자격 증명입니다. 안전하게 저장하고 퍼블릭 리포지토리 같은 액세스 가능한 위치에 저장하지 않도록 합니다.

--workload-profile-name "Consumption"을(를) 지정하면 기본 Consumption 워크로드 프로필을 사용하여 환경에서 앱을 만듭니다. 이는 Container Apps 사용량 계획에서 실행하는 것과 동일합니다. 함수 앱을 처음 만들 때 레지스트리에서 초기 이미지를 가져옵니다.

이 시점에서 함수는 필요한 애플리케이션 설정이 이미 추가된 Container Apps 환경에서 실행되고 있습니다. 필요한 경우 Functions에 대한 표준 방식으로 함수 앱에 다른 설정을 추가할 수 있습니다. 자세한 내용은 애플리케이션 설정 사용을 참조하세요.

함수 코드를 나중에 변경할 때 컨테이너를 다시 빌드하고, 이미지를 레지스트리에 다시 게시하고, 함수 앱을 새 이미지 버전으로 업데이트해야 합니다. 자세한 내용은 레지스트리에서 이미지 업데이트를 참조하세요.

Azure에서 함수 확인

이미지가 Azure에서 함수 앱에 배포되었으므로 이제 HTTP 요청을 통해 함수를 호출할 수 있습니다.

  1. 다음 az functionapp function show 명령을 실행하여 새 함수의 URL을 가져옵니다.

    az functionapp function show --resource-group AzureFunctionsContainers-rg --name <APP_NAME> --function-name HttpExample --query invokeUrlTemplate 
    

    <APP_NAME>은 함수 앱 이름으로 바꿉니다.

  1. 방금 얻은 URL을 사용하여 HttpExample 함수 엔드포인트를 호출하고 쿼리 문자열 ?name=Functions를 추가합니다.
  1. 방금 얻은 URL을 사용하여 HttpExample 함수 엔드포인트를 호출합니다.

이 URL로 이동하면 브라우저가 함수를 로컬로 실행할 때와 유사한 출력을 표시해야 합니다.

결과 URL은 다음과 같이 표시됩니다.

https://myacafunctionapp.kindtree-796af82b.eastus.azurecontainerapps.io/api/httpexample?name=functions

https://myacafunctionapp.kindtree-796af82b.eastus.azurecontainerapps.io/api/httpexample

리소스 정리

이 문서에서 만든 리소스를 사용하여 Azure Function을 계속 사용하려면 해당 리소스를 모두 그대로 유지할 수 있습니다.

이 함수 앱 배포 작업을 마쳤으면 AzureFunctionsContainers-rg 리소스 그룹을 삭제하여 해당 그룹의 모든 리소스를 정리합니다.

az group delete --name AzureFunctionsContainers-rg

다음 단계