첫 번째 컨테이너화된 Azure Functions 만들기

이 문서에서는 Linux 컨테이너에서 실행되는 함수 앱을 만들고 Azure Functions에 배포합니다.

함수 코드를 컨테이너의 Azure Functions에 배포하려면 프리미엄 플랜 또는 전용(App Service) 플랜 호스팅이 필요합니다. 이 문서를 완료하면 Azure 계정에 몇 달러(미국)의 비용이 발생하며, 이 비용은 완료될 때 리소스 정리를 통해 최소화할 수 있습니다.

함수 앱 컨테이너를 Azure에 배포하기 위한 다른 옵션은 다음과 같습니다.

개발 언어 선택

먼저 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에 배포하기 전에 다음 세 가지 리소스를 만들어야 합니다.

  • 리소스 그룹 - 관련 리소스에 대한 논리 컨테이너입니다.
  • 스토리지 계정 - 함수에 대한 상태 및 기타 정보를 유지 관리합니다.
  • 함수 앱 - 함수 코드를 실행할 수 있는 환경을 제공합니다. 함수 앱은 로컬 함수 프로젝트에 매핑되며, 함수를 논리적 단위로 그룹화하여 리소스를 더 쉽게 관리, 배포 및 공유할 수 있습니다.

다음 명령을 사용하여 이러한 항목을 만듭니다. Azure CLI와 PowerShell이 모두 지원됩니다. Azure PowerShell 사용하여 Azure 리소스를 만들려면 Az PowerShell 모듈 버전 5.9.0 이상도 필요합니다.

  1. 아직 Azure에 로그인하지 않았으면 지금 로그인합니다.

    az login
    

    az login 명령을 선택하면 사용자가 Azure 계정에 로그인됩니다.

  2. 선택한 지역에 AzureFunctionsContainers-rg라는 리소스 그룹을 만듭니다.

    az group create --name AzureFunctionsContainers-rg --location <REGION>
    

    az group create 명령은 리소스 그룹을 만듭니다. 위의 명령에서 az account list-locations 명령에서 반환된 사용 가능한 지역 코드를 사용하여 <REGION>을 가까운 지역으로 바꿉니다.

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

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

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

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

  4. 명령을 사용하여 탄력적 프리미엄 1 가격 책정 계층(--sku EP1), <REGION> 및 Linux 컨테이너(--is-linux)에서 myPremiumPlan라는 Azure Functions 프리미엄 플랜을 만듭니다.

    az functionapp plan create --resource-group AzureFunctionsContainers-rg --name myPremiumPlan --location <REGION> --number-of-workers 1 --sku EP1 --is-linux
    

    여기서는 필요에 따라 확장할 수 있는 프리미엄 요금제를 사용합니다. 호스팅에 대한 자세한 내용은 Azure Functions 호스팅 계획 비교를 참조하세요. 비용을 계산하는 방법에 대한 자세한 내용은 Functions 가격 책정 페이지를 참조하세요.

    또한 이 명령은 동일한 리소스 그룹에 연결된 Azure Application Insights 인스턴스를 만들어 함수 앱을 모니터링하고 로그를 볼 수 있습니다. 자세한 내용은 Azure Functions 모니터링을 참조하세요. 인스턴스를 활성화할 때까지 비용이 발생하지 않습니다.

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

Azure의 함수 앱은 Azure Functions 호스팅 플랜에서 함수 실행을 관리합니다. 이 섹션에서는 이전 섹션의 Azure 리소스를 사용하여 컨테이너 레지스트리의 이미지에서 함수 앱을 만들고 Azure Storage에 대한 연결 문자열을 사용하여 구성합니다.

  1. 컨테이너 레지스트리에 따라 다음 명령을 사용하여 함수 앱을 만듭니다.

    az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --resource-group AzureFunctionsContainers-rg --plan myPremiumPlan --image <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 --registry-username <USERNAME> --registry-password <SECURE_PASSWORD> 
    

    이 예제에서는 <STORAGE_NAME>을 이전 섹션에서 스토리지 계정에 대해 사용한 이름으로 바꿉니다. 또한 <APP_NAME>을 사용자에 적합한 전역적으로 고유한 이름으로 바꾸고 <DOCKER_ID> 또는 <LOGIN_SERVER>를 각각 Docker Hub 계정 ID 또는 컨테이너 레지스트리 서버로 바꿉니다. 사용자 지정 컨테이너 레지스트리에서 배포하는 경우 이미지 이름은 레지스트리의 URL을 나타냅니다.

    함수 앱을 처음 만들 때 Docker Hub에서 초기 이미지를 가져옵니다. 컨테이너 레지스트리에서 Azure로의 연속 배포를 사용하도록 설정할 수도 있습니다.

    host.json 파일의 DisableColor 설정을 사용하여 ANSI 제어 문자가 컨테이너 로그에 기록되지 않도록 할 수 있습니다.

  2. 다음 명령을 사용하여 만든 스토리지 계정에 대한 연결 문자열을 가져옵니다.

    az storage account show-connection-string --resource-group AzureFunctionsContainers-rg --name <STORAGE_NAME> --query connectionString --output tsv
    

    az storage account show-connection-string 명령을 사용하여 스토리지 계정의 연결 문자열이 반환됩니다.

    <STORAGE_NAME>을 앞에서 만든 스토리지 계정 이름으로 바꿉니다.

  3. 다음 명령을 사용하여 함수 앱에 설정을 추가합니다.

    az functionapp config appsettings set --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage=<CONNECTION_STRING>
    

    az functionapp config appsettings set 명령은 설정을 만듭니다.

    이 명령어에서 <APP_NAME>을 함수 앱의 이름으로 바꾸고 <CONNECTION_STRING>을 이전 단계의 연결 문자열로 바꿉니다. 연결은 DefaultEndpointProtocol=로 시작하는 긴 인코딩된 문자열입니다.

  4. 이제 함수에서 이 연결 문자열을 사용하여 스토리지 계정에 액세스할 수 있습니다.

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로 이동하면 브라우저가 함수를 로컬로 실행할 때와 유사한 출력을 표시해야 합니다.

리소스 정리

이 문서에서 만든 리소스를 사용하여 Azure Function을 계속 사용하려면 해당 리소스를 모두 그대로 유지할 수 있습니다. Azure Functions 프리미엄 요금제를 만들었으므로 매일 1~2USD의 지속적인 비용이 발생합니다.

지속적인 비용을 방지하려면 AzureFunctionsContainers-rg 리소스 그룹을 삭제하여 해당 그룹의 모든 리소스를 정리합니다.

az group delete --name AzureFunctionsContainers-rg

다음 단계