Azure Container Apps에서 첫 번째 컨테이너화된 함수 만들기
이 문서에서는 Linux 컨테이너에서 실행되는 함수 앱을 만들고 컨테이너 레지스트리에서 Azure Container Apps 환경에 배포합니다. Container Apps에 배포하면 함수 앱을 클라우드 네이티브 마이크로 서비스에 통합할 수 있습니다. 자세한 내용은 Azure Functions의 Azure Container Apps 호스팅을 참조하세요.
이 문서에서는 Linux 컨테이너에서 실행되는 함수를 만들고 컨테이너를 Container Apps 환경에 배포하는 방법을 보여 줍니다.
이 빠른 시작을 완료하면 Azure 계정에서 몇 USD 몇 센트 이하의 소액이 발생하므로 완료되면 리소스를 정리하여 최소화할 수 있습니다.
개발 언어 선택
먼저 Azure Functions 도구를 사용하여 언어별 Linux 기본 이미지를 사용하여 Docker 컨테이너에서 함수 앱으로 프로젝트 코드를 만듭니다. 문서 상단에서 원하는 언어를 선택하세요.
Core Tools는 함수 언어에 가장 최신 버전의 올바른 기본 이미지를 사용하는 프로젝트에 대한 Dockerfile을 자동으로 생성합니다. 최신 기본 이미지에서 컨테이너를 정기적으로 업데이트하고 업데이트된 버전의 컨테이너에서 다시 배포해야 합니다. 자세한 내용은 컨테이너화된 함수 앱 만들기를 참조하세요.
필수 조건
시작하기 전에 다음과 같은 요구 사항이 있어야 합니다.
.NET 8.0 SDK를 설치합니다.
Azure Functions Core Tools 버전 4.0.5198 이상을 설치합니다.
- Azure Functions Core Tools 버전 4.x를 설치합니다.
- Azure Functions에서 지원하는Node.js 버전을 설치합니다.
- Azure Functions에서 지원하는 Python 버전을 설치합니다.
- .NET 6 SDK를 설치합니다.
Azure Functions에서 지원하는Java 개발자 키트 버전을 설치합니다.
Apache Maven 버전 3.0 이상을 설치합니다.
- Azure CLI 버전 2.4 이상.
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"
다음 명령을 사용하여 함수를 프로젝트에 추가합니다. 여기서 --name
인수는 함수의 고유한 이름이고, --template
인수는 함수의 트리거를 지정합니다.
func new
는 function.json이라는 구성 파일을 포함하는 함수 이름과 일치하는 하위 폴더를 만듭니다.
func new --name HttpExample --template "HTTP trigger"
함수를 로컬로 테스트하려면 프로젝트 폴더의 루트에서 로컬 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 인스턴스를 사용하고 관리 ID 기반 연결을 적용해야 합니다. Docker Hub를 사용하려면 공유 비밀을 사용하여 인증해야 하므로 배포가 더 취약합니다.
Azure Container Registry는 컨테이너 이미지 및 관련 아티팩트를 빌드, 저장 및 관리하기 위한 프라이빗 레지스트리 서비스입니다. Azure 서비스에 컨테이너를 게시하려면 프라이빗 레지스트리 서비스를 사용해야 합니다.
이 명령을 사용하여 현재 Azure 자격 증명을 사용한 레지스트리 인스턴스에 로그인합니다.
az acr login --name <REGISTRY_NAME>
이전 명령에서
<REGISTRY_NAME>
을 Container Registry 인스턴스 이름으로 바꿉니다.이 명령을 사용한 레지스트리 로그인 서버의 정규화된 이름으로 이미지에 태그를 지정합니다.
docker tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 <LOGIN_SERVER>/azurefunctionsimage:v1.0.0
<LOGIN_SERVER>
를 레지스트리 로그인 서버의 정규화된 이름으로 바꾸고<DOCKER_ID>
를 Docker ID로 바꿉니다.이 명령을 사용한 레지스트리 인스턴스에 컨테이너를 푸시합니다.
docker push <LOGIN_SERVER>/azurefunctionsimage:v1.0.0
함수를 지원하는 Azure 리소스 만들기
컨테이너를 Azure에 배포하기 전에 다음 세 가지 리소스를 만들어야 합니다.
- 리소스 그룹 - 관련 리소스에 대한 논리 컨테이너입니다.
- 스토리지 계정 - 함수에 대한 상태 및 기타 정보를 유지 관리합니다.
- Log Analytics 작업 영역을 사용하여 Azure Container Apps 환경을 만듭니다.
- 사용자가 할당한 관리 ID로, 함수 앱이 공유 비밀을 사용하지 않고도 Azure 리소스에 안전하게 연결할 수 있습니다. Azure Storage 계정과 Azure Container Registry 인스턴스에 대한 연결은 대신 이 시나리오에 권장되는 ID로 Microsoft Entra 인증을 사용하여 이루어집니다.
참고 항목
Docker Hub는 관리 ID를 지원하지 않습니다.
다음 명령을 사용하여 필요한 Azure 리소스를 만듭니다.
필요한 경우 Azure에 로그인합니다.
az login
명령을 선택하면 사용자가 Azure 계정에 로그인됩니다. 계정과 연결된 구독이 두 개 이상 있는 경우az account set
를 사용합니다.다음 명령을 실행하여 Azure CLI를 최신 버전으로 업데이트합니다.
az upgrade
Azure CLI 버전이 최신 버전이 아닌 경우 설치가 시작됩니다. 업그레이드 방식은 운영 체제에 따라 달라집니다. 업그레이드가 완료된 후에 진행할 수 있습니다.
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
AzureFunctionsContainers-rg
라는 리소스 그룹을 만듭니다.az group create --name AzureFunctionsContainers-rg --location eastus
az group create
명령은 미국 동부 지역에서 리소스 그룹을 만듭니다. 대신 가까운 지역을 사용하려는 경우 az account list-locations 명령에서 반환된 사용 가능한 지역 코드를 사용합니다.eastus
대신 사용자 지정 지역을 사용하도록 후속 명령을 수정해야 합니다.워크로드 프로필을 사용하도록 설정된 Azure Container App 환경을 만듭니다.
az containerapp env create --name MyContainerappEnvironment --enable-workload-profiles --resource-group AzureFunctionsContainers-rg --location eastus
이 명령을 완료하는 데 몇 분이 걸릴 수 있습니다.
공유 키 액세스 없이 리소스 그룹 및 지역에 범용 스토리지 계정을 만듭니다.
az storage account create --name <STORAGE_NAME> --location eastus --resource-group AzureFunctionsContainers-rg --sku Standard_LRS --allow-blob-public-access false --allow-shared-key-access false
이
az storage account create
명령은 특정 리소스에 대한 권한이 부여된 Microsoft Entra 인증 ID를 사용해야만 액세스할 수 있는 스토리지 계정을 만듭니다.이전 예제에서
<STORAGE_NAME>
을 사용자에게 적절하고 Azure Storage에서 고유한 이름으로 바꿉니다. 스토리지 이름은 3~24자의 숫자와 소문자만 포함해야 합니다.Standard_LRS
는 Functions에서 지원하는 범용 계정을 지정합니다.관리 ID를 만들고 반환
principalId
된 ID를 사용하여 스토리지 계정에 대한 액세스 권한과 레지스트리 인스턴스의 끌어오기 권한을 모두 부여합니다.principalId=$(az identity create --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --location eastus --query principalId -o tsv) acrId=$(az acr show --name <REGISTRY_NAME> --query id --output tsv) az role assignment create --assignee-object-id $principalId --assignee-principal-type ServicePrincipal --role acrpull --scope $acrId storageId=$(az storage account show --resource-group AzureFunctionsContainers-rg --name glengatestaca2 --query 'id' -o tsv) az role assignment create --assignee-object-id $principalId --assignee-principal-type ServicePrincipal --role "Storage Blob Data Owner" --scope $storageId
이
az identity create
명령은 사용자 할당 관리 IDaz role assignment create
를 만들고 명령은 필요한 역할에 ID를 추가합니다.<USER_IDENTITY_NAME>
<STORAGE_NAME>
기존 컨테이너 레지스트리 이름, 관리 ID의 이름 및 스토리지 계정 이름을 각각 바꿉<REGISTRY_NAME>
니다. 이제 앱에서 관리 ID를 사용하여 공유 비밀을 사용하지 않고 스토리지 계정과 Azure Container Registry 모두에 액세스할 수 있습니다.
이미지를 사용하여 Azure에서 함수 앱 만들기 및 구성
Azure의 함수 앱은 Azure Container Apps 환경에서 함수 실행을 관리합니다. 이 섹션에서는 이전 섹션의 Azure 리소스를 사용하여 Container Apps 환경의 컨테이너 레지스트리에 있는 이미지에서 함수 앱을 만듭니다. 또한 필요한 Azure Storage 계정에 대한 연결 문자열을 사용하여 새 환경을 구성합니다.
명령을 az functionapp create
사용하여 Azure Container Apps에서 지원되는 새 관리형 환경에서 함수 앱을 만듭니다. 에서 az functionapp create
매개 변수는 --environment
Container Apps 환경을 지정합니다.
팁
함수 앱이 레지스트리 인스턴스에 대한 관리 ID 기반 연결을 사용하는지 확인하려면 매개 변수az functionapp create
를 --image
설정하지 마세요. 리포지토리에서 이미지의 정규화된 이름으로 설정 --image
하면 공유 비밀 자격 증명이 레지스트리에서 가져오고 앱 설정에 저장됩니다.
먼저 레지스트리에 대한 끌어오기 액세스 사용하여 사용자 할당 관리 ID의 정규화된 ID 값을 가져와야 하며, 이 명령을 사용하여 az functionapp create
기본 이미지와 이 ID를 할당하여 함수 앱을 만들어야 합니다.
UAMI_RESOURCE_ID=$(az identity show --name $uami_name --resource-group $group --query id -o tsv)
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --assign-identity $UAMI_RESOURCE_ID
--assign-identity
에서 az functionapp create
관리 ID를 새 앱에 할당합니다. 매개 변수az functionapp create
를 --image
설정하지 않았기 때문에 자리 표시자 이미지를 사용하여 애플리케이션이 만들어집니다.
이 예제에서는 새 함수 앱의 이름과 스토리지 계정 및 ID의 이름으로 바꿉 <APP_NAME>
<STORAGE_NAME>
<USER_IDENTITY_NAME>
니다.
마지막으로 사이트 설정을 리포지토리에 있는 이미지의 정규화된 이름으로 업데이트 linuxFxVersion
해야 합니다. 또한 레지스트리에서 이미지를 가져올 때 관리 ID가 사용되도록 및 acrUserManagedIdentityID
사이트 설정을 업데이트 acrUseManagedIdentityCreds
해야 합니다.
UAMI_RESOURCE_ID=$(az identity show --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --query id -o tsv)
az resource patch --resource-group AzureFunctionsContainers-rg --name <APP_NAME> --resource-type "Microsoft.Web/sites" --properties "{ \"siteConfig\": { \"linuxFxVersion\": \"DOCKER|<REGISTRY_NAME>.azurecr.io/azurefunctionsimage:v1.0.0\", \"acrUseManagedIdentityCreds\": true, \"acrUserManagedIdentityID\":\"$UAMI_RESOURCE_ID\", \"appSettings\": [{\"name\": \"DOCKER_REGISTRY_SERVER_URL\", \"value\": \"<REGISTRY_NAME>.azurecr.io\"}]}}"
이 명령은 필요한 사이트 설정 az resource patch
외에도 앱 설정을 레지스트리 서버의 URL로 업데이트합니다 DOCKER_REGISTRY_SERVER_URL
.
이 예제에서는 각각 함수 앱, 컨테이너 레지스트리 및 <USER_IDENTITY_NAME>
ID의 이름으로 바꿉<APP_NAME>
<REGISTRY_NAME>
니다.
--workload-profile-name "Consumption"
을(를) 지정하면 기본 Consumption
워크로드 프로필을 사용하여 환경에서 앱을 만듭니다. 이는 Container Apps 사용량 계획에서 실행하는 것과 동일합니다. 함수 앱을 처음 만들 때 레지스트리에서 초기 이미지를 가져옵니다.
애플리케이션 설정 업데이트
Functions 호스트가 공유 비밀을 사용하여 기본 스토리지 계정에 연결할 수 있도록 하려면 연결 문자열 설정을 사용자 할당 관리 ID를 사용하여 스토리지 계정에 연결하는 동등한 설정으로 바꿔 AzureWebJobsStorage
야 합니다.
기존 연결 문자열 설정을 제거합니다.
AzureWebJobsStorage
az functionapp config appsettings delete --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --setting-names AzureWebJobsStorage
az functionapp config appsettings delete 명령은 앱에서 이 설정을 제거합니다.
<APP_NAME>
은 함수 앱 이름으로 바꿉니다.기본 스토리지 계정에 대한 사용자 할당 관리 ID 연결을 정의하는 접두사를 사용하여 동등한 설정을
AzureWebJobsStorage__
추가합니다.clientId=$(az identity show --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --query 'clientId' -o tsv) az functionapp config appsettings set --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage__accountName=<STORAGE_NAME> AzureWebJobsStorage__credential=managedidentity AzureWebJobsStorage__clientId=$clientId
이 예제에서는 각각 함수 앱 이름, ID 이름 및 스토리지 계정 이름으로 바
<USER_IDENTITY_NAME>
<STORAGE_NAME>
꿉<APP_NAME>
니다.
이 시점에서 함수는 필요한 애플리케이션 설정이 이미 추가된 Container Apps 환경에서 실행되고 있습니다. 필요한 경우 Functions에 대한 표준 방식으로 함수 앱에 다른 설정을 추가할 수 있습니다. 자세한 내용은 애플리케이션 설정 사용을 참조하세요.
팁
함수 코드를 나중에 변경할 때 컨테이너를 다시 빌드하고, 이미지를 레지스트리에 다시 게시하고, 함수 앱을 새 이미지 버전으로 업데이트해야 합니다. 자세한 내용은 레지스트리에서 이미지 업데이트를 참조하세요.
Azure에서 함수 확인
이미지가 Azure에서 함수 앱에 배포되었으므로 이제 HTTP 요청을 통해 함수를 호출할 수 있습니다.
다음
az functionapp function show
명령을 실행하여 새 함수의 URL을 가져옵니다.az functionapp function show --resource-group AzureFunctionsContainers-rg --name <APP_NAME> --function-name HttpExample --query invokeUrlTemplate
<APP_NAME>
은 함수 앱 이름으로 바꿉니다.
- 방금 얻은 URL을 사용하여
HttpExample
함수 엔드포인트를 호출하고 쿼리 문자열?name=Functions
를 추가합니다.
- 방금 얻은 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