创建第一个容器化 Azure Functions

在本文中,创建一个在 Linux 容器中运行的函数应用,并将其部署到 Azure Functions。

在容器中将函数代码部署到 Azure Functions 需要高级计划专用(应用服务)计划托管。

将函数应用容器部署到 Azure 的其他选项包括:

在容器中创建函数应用

首先,使用 Azure Functions 工具,借助特定于语言的 Linux 基础映像在 Docker 容器中将项目代码创建为函数应用。 确保在文章顶部选择所选语言。

重要

创建自己的容器时,需要将容器的基础映像更新为受支持的最新基础映像。 Azure Functions 支持的基映像特定于语言,可在 Azure Functions 基础映像存储库中找到。

Functions 团队致力于发布这些基础映像的每月更新。 定期更新包括 Functions 运行时和语言的最新次要版本更新和安全修补程序。 对于容器,应定期更新 Dockerfile 中的基础映像,重新生成并重新部署容器的更新版本。

配置本地环境

在开始之前,必须满足以下要求:

如果没有 Azure 订阅,可在开始前创建一个 Azure 试用版

若要将创建的容器化函数应用映像发布到容器注册表,需要 Docker ID 和 Docker(在本地计算机上运行)。 如果没有 Docker ID,可以创建 Docker 帐户

还需要完成容器注册表快速入门中的创建容器注册表部分,才能创建注册表实例。 记下完全限定的登录服务器名称。

创建并激活虚拟环境

在适当的文件夹中,运行以下命令以创建并激活一个名为 .venv 的虚拟环境。 请确保使用 Python 3.8、3.7 或 3.6,这些版本受 Azure Functions 支持。

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 参数告诉 Functions 运行时要使用哪个 Java 版本。 如果希望函数在 Java 11 上运行,请使用 -DjavaVersion=11。 如果不指定 -DjavaVersion,则 Maven 默认使用 Java 8。 有关详细信息,请参阅 Java 版本

重要

要完成本文中的步骤,JAVA_HOME 环境变量必须设置为正确版本的 JDK 的安装位置。

Maven 会请求你提供所需的值,以在部署上完成项目的生成。 按照提示提供以下信息:

Prompt 说明
groupId com.fabrikam 一个值,用于按照 Java 的包命名规则在所有项目中标识你的项目。
artifactId fabrikam-functions 一个值,该值是 jar 的名称,没有版本号。
version 1.0-SNAPSHOT 选择默认值。
package 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 new 创建一个与函数名称匹配的子文件夹,该子文件夹包含一个名为 function.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。 浏览器一定会显示一条“hello”消息,该消息回显 Functions(提供给 name 查询参数的值)。

按 Ctrl+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 停止 Docker。

将容器映像发布到注册表

若要使容器映像可用于部署到托管环境,必须将其推送到容器注册表。

Docker Hub 是托管映像并提供映像和容器服务的容器注册表。

  1. 如果尚未登录到 Docker,请使用 docker login 命令登录(请将 <docker_id> 替换为你的 Docker Hub 帐户 ID)。 此命令会提示输入用户名和密码。 如果出现“登录成功”消息,则表示已登录。

    docker login
    
  2. 登录后,使用 docker push 命令将映像推送到 Docker Hub,同样,请将 <docker_id> 替换为你的 Docker Hub 帐户 ID。

    docker push <DOCKER_ID>/azurefunctionsimage:v1.0.0
    

    首次推送映像可能需要几分钟时间,具体取决于网络速度。 后续更改的推送速度会更快。

创建函数的支持性 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 命令创建资源组。 在上述命令中,使用从 <REGION> 命令返回的可用区域代码,将 <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 存储中唯一的名称。 存储名称只能包含 3 到 24 个数字和小写字母字符。 Standard_LRS 指定 Functions 支持的常规用途帐户。

  4. 使用以下命令在你的 <REGION> 和 Linux 容器 (--is-linux) 中的“弹性高级版 1”定价层 (--sku EP1) 中为 Azure Functions 创建名为 myPremiumPlan 的高级计划。

    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 存储的连接字符串对其进行配置。

  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 Functions,可以保留所有这些资源。 由于为 Azure Functions 创建了高级计划,因此每天会产生一到两美元的费用。

若要避免持续性的费用,请删除 AzureFunctionsContainers-rg 资源组以清理其中的所有资源:

az group delete --name AzureFunctionsContainers-rg

后续步骤