在 Azure 容器應用中,創建一個在自訂容器中的函數應用

本文中,你會建立一個在 Linux 容器中執行的 Azure Functions 應用程式,並從容器登錄檔部署到 Azure 容器應用程式環境。 藉由部署至容器應用程式,您可以將函式應用程式整合至雲端原生微服務中。 如需詳細資訊,請參閱 Azure Functions 的 Azure 容器應用程式裝載。

完成此快速入門會在你的 Azure 帳號中產生一筆小成本,完成後可透過 清理資源 來減少成本。

選擇您的開發語言

首先,你使用 Azure Functions 工具,透過語言專用的 Linux 基礎映像,在 Docker 容器中建立專案程式碼作為函式應用程式。 務必在文章頂端選取您所選擇的語言。

Core Tools 會自動為您的專案產生 Dockerfile,其會針對您的函式語言使用最新版的正確基礎映像。 您應該定期從最新的基礎映像更新容器,並從容器的更新版本重新部署。 欲了解更多資訊,請參閱 建立容器化函式應用程式。

先決條件

開始之前,您必須符合下列需求:

如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。

要將你建立的容器化函式應用程式映像檔發佈到容器登錄檔,你需要在本地電腦上運行 Docker ID 和 Docker 桌面 。 如果您沒有 Docker 識別碼,則可以建立 Docker 帳戶。

你也需要完成容器登錄快速入門中建立 容器登錄 的部分。 記下完整的登入伺服器名稱。

建立並啟用虛擬環境

在適用的資料夾中執行下列命令,以建立並啟用名為 .venv 的虛擬環境。 請務必使用 Azure Functions 支援的其中一個 Python 版本 。

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

如果 Python 未在您的 Linux 發行版本上安裝 venv 套件,請執行下列命令:

sudo apt-get install python3-venv

您將在這個已啟用的虛擬環境中執行所有後續命令。

建立和測試本機 Functions 專案

在終端機或命令提示字元中,針對您選擇的語言執行下列命令,以在目前的資料夾中建立函式應用程式專案:

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原型產生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 版本。

這很重要

JAVA_HOME 環境變數必須設定為正確 JDK 版本的安裝位置,才能完成本文。

Maven 會要求您提供在部署時完成產生專案所需的值。 依照提示操作並提供下列資訊:

Prompt 價值觀 Description
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 執行階段主機。 為了確保該函式在 Docker 中架設時能被呼叫,請檢查授權層級是否設定為 AuthorizationLevel.Anonymous,若尚未設定,請設定。

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

看到 HttpExample 端點寫入輸出之後,瀏覽至該端點。 您應該會在回應輸出中看到歡迎訊息。

看到 HttpExample 端點寫入輸出之後,請瀏覽至 http://localhost:7071/api/HttpExample?name=Functions。 瀏覽器必須顯示 "hello" 訊息,回應 Functions,這是提供給 name 查詢參數的值。

按 Ctrl+C (macOS 上的 Command+C ) 停止主機。

建立容器映像並在本機驗證

(選用)檢查專案資料夾根目錄中的 Dockerfile 。 Dockerfile 描述在 Linux 上執行函式應用程式所需的環境。 在 Azure Functions 基底映像頁面中可找到針對 Azure Functions 支援的完整基底映像清單。

在根專案資料夾中,執行 docker build 命令,提供名稱為 azurefunctionsimage,並將標籤提供為 v1.0.0。 將 <DOCKER-ID> 取代為 Docker Hub 帳戶識別碼。 此命令會建置容器的 Docker 映像。

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

當命令完成時,您就能在本機執行新容器。

若要驗證組建,請使用 docker run 命令在本機容器中執行映像,再次取代 <DOCKER-ID> 為您的 Docker Hub 帳戶 ID,並將 ports 引數新增為 -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 上的命令+C ) 以停止執行。

將容器映像發佈至登錄

若要讓您的容器映像可供部署至主控環境,您必須將其推送至容器登錄。 作為安全性最佳做法,建議您使用 Azure Container Registry 執行個體,並強制執行受控識別型連線。 Docker Hub 要求您使用共用秘密進行驗證,這會讓您的部署更容易受到攻擊。

Azure Container Registry 是私人登錄服務,可用來建置、儲存和管理容器映射和相關成品。 您應該使用私人登錄服務,將容器發佈至 Azure 服務。

  1. 使用這個指令,使用你目前的 Azure 憑證登入你的登錄實例。 請將 Container 登錄實例的名稱替換 <REGISTRY-NAME> 。

    az acr login --name <REGISTRY-NAME>
    
  2. 使用此命令,以登錄伺服器的完整名稱為您的映像加上標籤。 以登錄登入伺服器的完整名稱取代 <LOGIN-SERVER>,並以 Docker 識別碼取代 <DOCKER-ID>。

    docker tag <DOCKER-ID>/azurefunctionsimage:v1.0.0 <LOGIN-SERVER>/azurefunctionsimage:v1.0.0 
    
  3. 使用此命令將容器推送至您的登錄執行個體:

    docker push <LOGIN-SERVER>/azurefunctionsimage:v1.0.0
    

為您的函式建立支援的 Azure 資源

若要將容器部署至 Azure,您必須建立三個資源:

  • 資源群組,這是相關資源的邏輯容器。

  • 一個 Azure 儲存帳號,用來維護你的狀態和其他功能資訊。

  • 具有 Log Analytics 工作區的 Azure 容器應用程式環境。

  • 使用者指派的受控識別,這可讓您的函式應用程式在不使用共用秘密的情況下,安全地連線到 Azure 資源。 若要連接至 Azure 儲存帳戶和 Azure 容器登錄實例,建議使用 Microsoft Entra 認證與身分識別進行連接,這是在此情境中建議的做法。

    備註

    Docker Hub 不支援受控識別。

使用這些命令建立所需的 Azure 資源:

  1. 如有必要,請登入 Azure:

    az login 命令會將您登入 Azure 帳戶。 當您有一個以上的訂用帳戶與您的帳戶相關聯時,請使用 az account set。

  2. 執行下列命令,以將 Azure CLI 更新至最新版本:

    az upgrade
    

    如果你的 Azure CLI 版本不是最新版本,安裝就會開始。 升級方式取決於您的作業系統。 您可以在升級完成之後繼續進行。

  3. 執行下列命令,以升級 Azure 容器應用程式擴充功能,並註冊容器應用程式所需的命名空間:

    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 容器應用程式環境。

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

    此命令可能需要幾分鐘才能完成。

  6. 在資源群組和區域中建立一般用途的儲存體帳戶,而不使用共用金鑰存取。 在指令中,請替換 <STORAGE-NAME> 成一個適合你且在 Azure 儲存體 中唯一存在的名稱。 儲存體名稱只能包含 3 到 24 個字元的數字和小寫字母。

    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 認證的身份,並被賦予特定資源權限才能存取。

    Standard_LRS 會指定 受 Functions 支援的一般用途帳戶。

  7. 建立受控識別,並使用傳回的 principalId,向受控識別授與儲存體帳戶的存取權和登錄執行個體中的提取權限。 將 <REGISTRY-NAME>、<USER-IDENTITY-NAME> 和 <STORAGE-NAME> 分別取代為現有容器登錄的名稱、受控識別的名稱和儲存體帳戶名稱。

    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 <STORAGE-NAME> --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 建立一個由使用者指派的受管理身份,指令會 az role assignment create將你的身份加入所需的角色中。

    現在,應用程式可以使用管理身份,無需使用共享秘密即可存取儲存帳號和 Azure 容器登錄檔。

使用映像在 Azure 上建立及設定函式應用程式

Azure 上的函數應用程式可管理 Azure 容器應用程式環境中函式的執行。 在本節中,您會使用上一節中的 Azure 資源,從容器應用程式環境中的容器登錄中的映像建立函數應用程式。 您也可以使用所需 Azure 儲存體帳戶的連線字串來設定新環境。

使用 az containerapp create --kind=functionapp (部分機器翻譯) 命令,在 Azure 容器應用程式支援的新受控環境中建立函式應用程式。 在 az containerapp create --kind-functionapp (部分機器翻譯) 中,,--environment 參數會指定容器應用程式環境。

小提示

若要確保您的函式應用程式使用受控識別型的登錄執行個體連線,請勿在 --image 中設定 az containerapp create --kind=functionapp 參數。 當您將 --image 設定為存放庫中映像的完整名稱時,系統會從登錄取得共用祕密認證,並儲存到應用程式設定中。

首先,您必須取得具有登錄提取存取權的使用者指派受控識別的完整識別碼值,然後使用 az containerapp create --kind=functionapp 命令,使用預設映像建立函數應用程式,並將此識別碼指派給它。

UAMI_RESOURCE_ID=$(az identity show --name $uami_name --resource-group $group --query id -o tsv)

az containerapp 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

在 az containerapp create --kind=functionapp (部分機器翻譯) 中,--assign-identity 會將受控識別指派給新的應用程式。 由於您未在 --image 中設定 az functionapp create 參數,因此系統會使用預留位置映像建立應用程式。

在這個例子中,將<APP-NAME>替換為你的新功能應用程式名稱,將<STORAGE-NAME>替換為儲存帳號名稱。

最後,您必須將 linuxFxVersion (部分機器翻譯) 網站設定更新為存放庫中映像的完整名稱。 您也必須更新 acrUseManagedIdentityCreds 和 acrUserManagedIdentityID 網站設定,以便在從登錄取得映像時使用受控識別。

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 (部分機器翻譯) 命令也會將 DOCKER_REGISTRY_SERVER_URL (部分機器翻譯) 應用程式設定更新為登錄伺服器的 URL。

在此範例中,請分別將 <APP-NAME>、<REGISTRY-NAME> 和 <USER-IDENTITY-NAME> 取代為函式應用程式、容器登錄和身分識別的名稱。

指定 --workload-profile-name "Consumption" 會在使用預設 Consumption 工作負載設定檔的環境中建立您的應用程式,其成本與在容器應用程式取用方案中執行的成本相同。 當您第一次建立函數應用程式時,會從您的登錄中提取初始映像。

更新應用程式設定

若要讓 Functions 主機能夠使用共用祕密連線到預設儲存體帳戶,您必須將 AzureWebJobsStorage 連接字串設定取代為會使用使用者指派的受控識別來連線到儲存體帳戶的對等設定。

  1. 移除現有的 AzureWebJobsStorage 連接字串設定:

    az containerapp config appsettings delete --name <APP-NAME> --resource-group AzureFunctionsContainers-rg --setting-names AzureWebJobsStorage 
    

    這個 az containerapp config appsettings delete 指令會把這個設定從你的應用程式中移除。 以函式應用程式的名稱取代 <APP-NAME>。

  2. 新增具有 AzureWebJobsStorage__ 前置詞的對等設定,以定義利用使用者指派的受控識別對預設儲存體帳戶進行連線:

    clientId=$(az identity show --name <USER-IDENTITY-NAME> --resource-group AzureFunctionsContainers-rg --query 'clientId' -o tsv)
    az containerapp config appsettings set --name <APP-NAME> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage__accountName=<STORAGE-NAME> AzureWebJobsStorage__credential=managedidentity AzureWebJobsStorage__clientId=$clientId
    

    在此範例中,請分別將 <APP-NAME>、<USER-IDENTITY-NAME> 和 <STORAGE-NAME> 取代為函式應用程式名稱、身分識別的名稱和儲存體帳戶名稱。

此時,您的函式正在容器應用程式環境中執行,並已新增必要的應用程式設定。 如有需要,您可以按照 Functions 的標準方式在您的函式應用中新增其他設定。 如需詳細資訊,請參閱使用應用程式設定。

小提示

對函式程式碼進行後續變更時,您需要重建容器、將映像重新發佈至登錄,並使用新的映像版本更新函數應用程式。

在 Azure 上驗證您的函式

將映像部署至 Azure 中的函數應用程式後,您可以透過 HTTP 要求叫用函式。 獲取特定功能的詳細資訊:

    az containerapp function show \
    --resource-group AzureFunctionsContainers-rg \
    --name <APP-NAME> \
    --function-name HttpExample 

以函式應用程式的名稱取代 <APP-NAME>。 使用您剛才取得的 URL 來呼叫 HttpExample 函式端點,並附加查詢字串 ?name=Functions。

要求 URL 看起來應該像這樣:

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

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

目前 Go 不支援此功能。

清理資源

如果您想使用您在本文中建立的資源來繼續使用 Azure 函式,您可以保留所有這些資源。

當您完成此函數應用程式部署時,請刪除 AzureFunctionsContainers-rg 資源群組,以清除該群組中的所有資源:

az group delete --name AzureFunctionsContainers-rg

下一個步驟