教程:将 Azure Functions 作为 IoT Edge 模块进行部署Tutorial: Deploy Azure functions as IoT Edge modules

可以使用 Azure Functions 部署代码,以直接将业务逻辑实现到 Azure IoT Edge 设备。You can use Azure Functions to deploy code that implements your business logic directly to your Azure IoT Edge devices. 本教程将引导你在模拟的 IoT Edge 设备上创建和部署用于筛选传感器数据的 Azure 函数。This tutorial walks you through creating and deploying an Azure function that filters sensor data on the simulated IoT Edge device. 使用的模拟 IoT Edge 设备是在 WindowsLinux 快速入门的“在模拟设备上部署 Azure IoT Edge”中创建的。You use the simulated IoT Edge device that you created in the Deploy Azure IoT Edge on a simulated device on Windows or Linux quickstarts. 本教程介绍如何执行下列操作:In this tutorial, you learn how to:

  • 使用 Visual Studio Code 创建 Azure 函数。Use Visual Studio Code to create an Azure function.
  • 使用 VS Code 和 Docker 创建 Docker 映像并将其发布到容器注册表。Use VS Code and Docker to create a Docker image and publish it to a container registry.
  • 将模块从容器注册表部署到 IoT Edge 设备。Deploy the module from the container registry to your IoT Edge device.
  • 查看筛选的数据。View filtered data.

 - 教程体系结构、暂存以及部署函数模块

![Diagram - Tutorial architecture, stage and deploy function module](./media/tutorial-deploy-function/functions-architecture.png)

Note

Azure IoT Edge 上的 Azure Function 模块为公共预览版。Azure Function modules on Azure IoT Edge are in public preview.

在本教程中创建的 Azure 函数可以筛选由设备生成的温度数据。The Azure function that you create in this tutorial filters the temperature data that's generated by your device. 该函数只在温度高于指定阈值的情况下,向 Azure IoT 中心上游发送消息。The function only sends messages upstream to Azure IoT Hub when the temperature is above a specified threshold.

如果没有 Azure 订阅,可在开始前创建一个试用帐户If you don't have an Azure subscription, create a trial account before you begin.

先决条件Prerequisites

在开始学习本教程之前,应已完成上一篇教程来设置用于开发 Linux 容器的开发环境:开发适用于 Linux 设备的 IoT Edge 模块Before beginning this tutorial, you should have gone through the previous tutorial to set up your development environment for Linux container development: Develop IoT Edge modules for Linux devices. 完成该教程后,已应准备好以下必备组件:By completing that tutorial, you should have the following prerequisites in place:

若要通过 Azure Functions 开发 IoT Edge 模块,请在开发计算机上安装下述额外的必备组件:To develop an IoT Edge module in with Azure Functions, install the following additional prerequisites on your development machine:

创建函数项目Create a function project

在先决条件部分安装的适用于 Visual Studio Code 的 Azure IoT 工具提供管理功能和一些代码模板。The Azure IoT Tools for Visual Studio Code that you installed in the prerequisites provides management capabilities as well as some code templates. 在本部分,请使用 Visual Studio Code 创建包含 Azure 函数的 IoT Edge 解决方案。In this section, you use Visual Studio Code to create an IoT Edge solution that contains an Azure function.

创建新项目Create a new project

创建可以使用自己的代码进行自定义的 C# 函数解决方案模板。Create a C# Function solution template that you can customize with your own code.

  1. 在开发计算机上打开 Visual Studio Code。Open Visual Studio Code on your development machine.

  2. 打开 VS Code 命令面板,方法是选择“视图” > “命令面板”。Open the VS Code command palette by selecting View > Command Palette.

  3. 在命令面板中,输入并运行命令 Azure IoT Edge: New IoT Edge SolutionIn the command palette, enter and run the command Azure IoT Edge: New IoT Edge Solution. 按命令面板中的提示创建解决方案。Follow the prompts in the command palette to create your solution.

    字段Field Value
    选择文件夹Select folder 在适用于 VS Code 的开发计算机上选择用于创建解决方案文件的位置。Choose the location on your development machine for VS Code to create the solution files.
    提供解决方案名称Provide a solution name 输入解决方案的描述性名称(例如 FunctionSolution),或者接受默认名称。Enter a descriptive name for your solution, like FunctionSolution, or accept the default.
    选择模块模板Select module template 选择“Azure Functions - C#”。 Choose Azure Functions - C#.
    提供模块名称Provide a module name 将模块命名为 CSharpFunctionName your module CSharpFunction.
    为模块提供 Docker 映像存储库Provide Docker image repository for the module 映像存储库包含容器注册表的名称和容器映像的名称。An image repository includes the name of your container registry and the name of your container image. 容器映像是在上一步预先填充的。Your container image is prepopulated from the last step. localhost:5000 替换为 Azure 容器注册表中的登录服务器值。Replace localhost:5000 with the login server value from your Azure container registry. 可以在 Azure 门户的容器注册表的“概览”页中检索登录服务器。You can retrieve the login server from the Overview page of your container registry in the Azure portal. 最终的字符串看起来类似于 <注册表名称>.azurecr.cn/CSharpFunction。The final string looks like <registry name>.azurecr.cn/CSharpFunction.

    提供 Docker 映像存储库

添加注册表凭据Add your registry credentials

环境文件存储容器注册表的凭据,并将其与 IoT Edge 运行时共享。The environment file stores the credentials for your container registry and shares them with the IoT Edge runtime. 此运行时需要这些凭据才能将专用映像拉取到 IoT Edge 设备中。The runtime needs these credentials to pull your private images onto the IoT Edge device.

  1. 在 VS Code 资源管理器中,打开 .env 文件。In the VS Code explorer, open the .env file.
  2. 使用从 Azure 容器注册表复制的 usernamepassword 值更新相关字段。Update the fields with the username and password values that you copied from your Azure container registry.
  3. 保存此文件。Save this file.

选择目标体系结构Select your target architecture

目前,Visual Studio Code 可以开发适用于 Linux AMD64 和 Linux ARM32v7 设备的 C 模块。Currently, Visual Studio Code can develop C modules for Linux AMD64 and Linux ARM32v7 devices. 需要选择面向每个解决方案的体系结构,因为每种体系结构类型的容器的生成和运行方式均不相同。You need to select which architecture you're targeting with each solution, because the container is built and run differently for each architecture type. 默认设置为 Linux AMD64。The default is Linux AMD64.

  1. 打开命令面板并搜索 Azure IoT Edge:Set Default Target Platform for Edge Solution,或者选择窗口底部边栏中的快捷方式图标。Open the command palette and search for Azure IoT Edge: Set Default Target Platform for Edge Solution, or select the shortcut icon in the side bar at the bottom of the window.

  2. 在命令面板中,从选项列表中选择目标体系结构。In the command palette, select the target architecture from the list of options. 本教程将使用 Ubuntu 虚拟机作为 IoT Edge 设备,因此将保留默认设置 amd64For this tutorial, we're using an Ubuntu virtual machine as the IoT Edge device, so will keep the default amd64.

使用自定义代码更新模块Update the module with custom code

让我们添加一些附加的代码,使模块在将消息转发到 IoT 中心之前,先在边缘上对其进行处理。Let's add some additional code so that the module processes the messages at the edge before forwarding them to IoT Hub.

  1. 在 Visual Studio Code 中,打开“模块” > “CSharpFunction” > “CSharpFunction.cs” 。In Visual Studio Code, open modules > CSharpFunction > CSharpFunction.cs.

  2. CSharpFunction.cs 文件的内容替换为以下代码。Replace the contents of the CSharpFunction.cs file with the following code. 此代码接收有关环境温度和计算机温度的遥测,只有在计算机温度高于定义的阈值时才将消息转发到 IoT 中心。This code receives telemetry about ambient and machine temperature, and only forwards the message on to IoT Hub if the machine temperature is above a defined threshold.

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EdgeHub;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    
    namespace Functions.Samples
    {
        public static class CSharpFunction
        {
            [FunctionName("CSharpFunction")]
            public static async Task FilterMessageAndSendMessage(
                [EdgeHubTrigger("input1")] Message messageReceived,
                [EdgeHub(OutputName = "output1")] IAsyncCollector<Message> output,
                ILogger logger)
            {
                const int temperatureThreshold = 20;
                byte[] messageBytes = messageReceived.GetBytes();
                var messageString = System.Text.Encoding.UTF8.GetString(messageBytes);
    
                if (!string.IsNullOrEmpty(messageString))
                {
                    logger.LogInformation("Info: Received one non-empty message");
                    // Get the body of the message and deserialize it.
                    var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
                    if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
                    {
                        // Send the message to the output as the temperature value is greater than the threshold.
                        var filteredMessage = new Message(messageBytes);
                        // Copy the properties of the original message into the new Message object.
                        foreach (KeyValuePair<string, string> prop in messageReceived.Properties)
                        {filteredMessage.Properties.Add(prop.Key, prop.Value);}
                        // Add a new property to the message to indicate it is an alert.
                        filteredMessage.Properties.Add("MessageType", "Alert");
                        // Send the message.       
                        await output.AddAsync(filteredMessage);
                        logger.LogInformation("Info: Received and transferred a message with temperature above the threshold");
                    }
                }
            }
        }
        //Define the expected schema for the body of incoming messages.
        class MessageBody
        {
            public Machine machine {get; set;}
            public Ambient ambient {get; set;}
            public string timeCreated {get; set;}
        }
        class Machine
        {
            public double temperature {get; set;}
            public double pressure {get; set;}         
        }
        class Ambient
        {
            public double temperature {get; set;}
            public int humidity {get; set;}         
        }
    }
    
  3. 保存文件。Save the file.

生成 IoT Edge 解决方案Build your IoT Edge solution

在上一部分,你已经创建了一个 IoT Edge 解决方案并将代码添加到了 CSharpFunction,该函数会筛选出其中报告的计算机温度低于可接受阈值的消息。In the previous section, you created an IoT Edge solution and added code to the CSharpFunction to filter out messages where the reported machine temperature is less than the acceptable threshold. 现在需将解决方案生成为容器映像并将其推送到容器注册表。Now you need to build the solution as a container image and push it to your container registry.

在本部分中,你将第二次提供容器注册表的凭据(第一次是在 IoT Edge 解决方案的 .env 文件中),方法是从开发计算机本地登录,以便 Visual Studio Code 可以将映像推送到注册表。In this section, you provide the credentials for your container registry for the second time (the first was in the .env file of your IoT Edge solution) by signing in locally from your development machine so that Visual Studio Code can push images to your registry.

  1. 打开 VS Code 集成终端,方法是选择“视图” > “终端” 。Open the VS Code integrated terminal by selecting View > Terminal.

  2. 在集成终端输入以下命令,登录到容器注册表。Sign in to your container registry by entering the following command in the integrated terminal. 使用用户名以及此前从 Azure 容器注册表复制的登录服务器。Use the username and login server that you copied from your Azure container registry earlier.

    docker login -u <ACR username> <ACR login server>
    

    当系统提示输入密码时,请粘贴容器注册表的密码(它在终端窗口中不可见),然后按 EnterWhen you're prompted for the password, paste the password (it won't be visible in the terminal window) for your container registry and press Enter.

    Password: <paste in the ACR password and press enter>
    Login Succeeded
    
  3. 在 VS Code 资源管理器中右键单击“deployment.template.json”文件,然后选择“生成并推送 IoT Edge 解决方案”。 In the VS Code explorer, right-click the deployment.template.json file and select Build and Push IoT Edge solution.

告知 Visual Studio Code 生成解决方案时,它首先获取部署模板中的信息,然后在名为 config 的新文件夹中生成 deployment.json 文件。然后,它在集成终端运行两个命令,即 docker builddocker pushWhen you tell Visual Studio Code to build your solution, it first takes the information in the deployment template and generates a deployment.json file in a new folder named config. Then it runs two commands in the integrated terminal: docker build and docker push. 这两个命令会生成代码,将函数容器化,然后将代码推送到在初始化解决方案时指定的容器注册表。These two commands build your code, containerize the functions, and then push the code to the container registry that you specified when you initialized the solution.

查看容器映像View your container image

将容器映像推送到容器注册表以后,Visual Studio Code 会输出一条成功消息。Visual Studio Code outputs a success message when your container image is pushed to your container registry. 若要自行确认操作是否成功,可以在注册表中查看映像。If you want to confirm the successful operation for yourself, you can view the image in the registry.

  1. 在 Azure 门户中,浏览到 Azure 容器注册表。In the Azure portal, browse to your Azure container registry.
  2. 选择“存储库”。 Select Repositories.
  3. 列表中应会显示 csharpfunction 存储库。You should see the csharpfunction repository in the list. 选择此存储库可查看更多详细信息。Select this repository to see more details.
  4. 在“标记”部分,应会显示 0.0.1-amd64 标记。 In the Tags section, you should see the 0.0.1-amd64 tag. 此标记指示生成的映像的版本和平台。This tag indicates the version and platform of the image that you built. 这些值在 CSharpFunction 文件夹的 module.json 文件中设置。These values are set in the module.json file in the CSharpFunction folder.

部署并运行解决方案Deploy and run the solution

可以使用 Azure 门户将函数模块部署到 IoT Edge 设备,就像在快速入门中所做的一样。You can use the Azure portal to deploy your function module to an IoT Edge device like you did in the quickstarts. 也可以在 Visual Studio Code 中部署和监视模块。You can also deploy and monitor modules from within Visual Studio Code. 以下部分使用适用于 VS Code 的 Azure IoT 工具,该工具已在先决条件中列出。The following sections use the Azure IoT Tools for VS Code that was listed in the prerequisites. 如果尚未安装该扩展,现在请安装。Install the extension now, if you didn't already.

  1. 在 VS Code 资源管理器中,展开“Azure IoT 中心设备”部分。 In the VS Code explorer, expand the Azure IoT Hub Devices section.

  2. 右键单击 IoT Edge 设备的名称,然后选择“为单个设备创建部署”。 Right-click the name of your IoT Edge device, and then select Create Deployment for single device.

  3. 浏览到包含 CSharpFunction 的解决方案文件夹。Browse to the solution folder that contains the CSharpFunction. 打开 config 文件夹,选择 deployment.json 文件,然后选择“选择 Edge 部署清单”。 Open the config folder, select the deployment.json file, and then choose Select Edge Deployment Manifest.

  4. 刷新“Azure IoT 中心设备”部分。 Refresh the Azure IoT Hub Devices section. 此时应看到新的 CSharpFunctionSimulatedTemperatureSensor 模块以及 $edgeAgent$edgeHub 一起运行。You should see the new CSharpFunction running along with the SimulatedTemperatureSensor module and the $edgeAgent and $edgeHub. 新模块显示可能需要一些时间。It may take a few moments for the new modules to show up. IoT Edge 设备必须从 IoT 中心检索其新的部署信息,启动新容器,然后将状态报告回 IoT 中心。Your IoT Edge device has to retrieve its new deployment information from IoT Hub, start the new containers, and then report the status back to IoT Hub.

    在 VS Code 中查看部署的模块

查看生成的数据View generated data

若要查看到达 IoT 中心的所有消息,请在命令面板中运行 Azure IoT Hub:开始监视内置事件终结点You can see all of the messages that arrive at your IoT hub by running Azure IoT Hub: Start Monitoring Built-in Event Endpoint in the command palette.

也可通过筛选视图来查看从特定设备到达 IoT 中心的所有消息。You can also filter the view to see all of the messages that arrive at your IoT hub from a specific device. 右键单击“Azure IoT 中心设备”部分中的设备,然后选择“开始监视内置事件终结点”。 Right-click the device in the Azure IoT Hub Devices section and select Start Monitoring Built-in Event Endpoint.

若要停止监视消息,请在命令面板中运行 Azure IoT Hub:停止监视内置事件终结点To stop monitoring messages, run the command Azure IoT Hub: Stop Monitoring Built-in Event Endpoint in the command palette.

清理资源Clean up resources

如果打算继续学习下一篇建议的文章,可以保留已创建的资源和配置,以便重复使用。If you plan to continue to the next recommended article, you can keep the resources and configurations that you created and reuse them. 还可以继续使用相同的 IoT Edge 设备作为测试设备。You can also keep using the same IoT Edge device as a test device.

否则,可以删除本文中创建的本地配置和 Azure 资源,以避免收费。Otherwise, you can delete the local configurations and the Azure resources that you created in this article to avoid charges.

删除 Azure 资源Delete Azure resources

删除 Azure 资源和资源组的操作不可逆。Deleting Azure resources and resource groups is irreversible. 请确保不要意外删除错误的资源组或资源。Make sure that you don't accidentally delete the wrong resource group or resources. 如果在现有的包含要保留资源的资源组中创建了 IoT 中心,请只删除 IoT 中心资源本身,而不要删除资源组。If you created the IoT hub inside an existing resource group that has resources that you want to keep, delete only the IoT hub resource itself, instead of deleting the resource group.

若要删除资源,请执行以下操作:To delete the resources:

  1. 登录到 Azure 门户,然后选择“资源组”。Sign in to the Azure portal and select Resource groups.

  2. 选择包含 IoT Edge 测试资源的资源组的名称。Select the name of the resource group that contains your IoT Edge test resources.

  3. 查看包含在资源组中的资源的列表。Review the list of resources contained in your resource group. 若要删除这一切,可以选择“删除资源组”。If you want to delete all of them, you can select Delete resource group. 如果只需删除部分内容,可以单击要单独删除的每个资源。If you want to delete only some of them, you can click into each resource to delete them individually.

后续步骤Next steps

在本教程中,你已创建一个 Azure 函数模块,其中包含用于筛选 IoT Edge 设备生成的原始数据的代码。In this tutorial, you created an Azure function module with code to filter raw data that's generated by your IoT Edge device. 做好生成自己的模块的准备以后,即可详细了解如何使用用于 Visual Studio Code 的 Azure IoT Edge 进行开发When you're ready to build your own modules, you can learn more about how to Develop with Azure IoT Edge for Visual Studio Code.

继续阅读后续教程,了解如何使用 Azure IoT Edge 通过其他方式将数据转化为边缘业务见解。Continue on to the next tutorials to learn other ways that Azure IoT Edge can help you turn data into business insights at the edge.