教程:使用 IoT Edge for Linux on Windows 通过 Linux 容器开发 IoT Edge 模块

适用于:IoT Edge 1.4 checkmark IoT Edge 1.4

本教程介绍如何使用 IoT Edge for Linux on Windows 和 Visual Studio 2022 开发、调试自己的代码并将其部署到 IoT Edge 设备。 你将通过将 C# 模块部署到 Linux 设备来了解 IoT Edge 解决方案的最常见开发人员场景。 你将部署和调试在 Windows 上的 Linux 容器 (EFLOW) 中运行的自定义 Azure IoT Edge 模块。 即使你计划使用其他语言或部署 Azure 服务,本教程仍然有助于了解开发工具和概念。

本文包括两个 IoT Edge 开发工具的步骤:

  • 命令行接口 (CLI) 是开发的首选工具。
  • 适用于 Visual Studio 的 Azure IoT Edge Tools 扩展。 该扩展处于维护模式

使用本文开头的工具选择器按钮选择工具版本。

在本教程中,你将了解如何执行以下操作:

  • 设置开发计算机。
  • 使用适用于 Visual Studio Code 的 IoT Edge Tools 创建新项目。
  • 将项目作为容器生成并将其存储在 Azure 容器注册表中。
  • 将代码部署到 IoT Edge 设备。

先决条件

本文假设你使用运行 Windows 的计算机作为开发计算机。 在 Windows 计算机上,可以开发 Windows 或 Linux 模块。 本教程会指导你使用 Windows 上的 IoT Edge for Linux 生成和部署模块,进而开发 Linux 容器。

Visual Studio 2022 准备就绪后,还需要以下工具和组件:

  • 从 Visual Studio Marketplace 下载并安装 Azure IoT Edge Tools。 可以使用 Azure IoT Edge Tools 扩展来创建和生成 IoT Edge 解决方案。 首选开发工具为命令行 (CLI) Azure IoT Edge 开发工具。 该扩展包括用于创建 Visual Studio 项目的 Azure IoT Edge 项目模板。 目前,无论使用哪种开发工具,都需要安装该扩展。

    重要

    适用于 VS 2022 的 Azure IoT Edge Tools 扩展处于维护模式。 首选开发工具为命令行 (CLI) Azure IoT Edge 开发工具

    提示

    如果使用的是 Visual Studio 2019,请从 Visual Studio 市场下载并安装 Azure IoT Edge Tools for VS 2019

云资源:

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

关键概念

本教程详细介绍如何开发 IoT Edge 模块。 IoT Edge 模块有时简称模块,它是一个包含可执行代码的容器 。 可以将一个或多个模块部署到 IoT Edge 设备。 模块执行特定的任务,例如,从传感器引入数据、清理和分析数据,或者将消息发送到 IoT 中心。 有关详细信息,请参阅了解 Azure IoT Edge 模块

开发 IoT Edge 模块时,了解开发计算机和最终将部署模块的目标 IoT Edge 设备之间的差异非常重要。 为保存模块代码而生成的容器必须与目标设备的操作系统 (OS) 匹配。 例如,最常见的方案是在 Windows 计算机上开发面向运行 IoT Edge 的 Linux 设备的模块。 在这种情况下,容器操作系统将为 Linux。 在学习本教程的过程中,请记住开发计算机 OS容器 OS 之间的差异。 在本教程中,你将使用 Windows 主机进行开发,并使用 IoT Edge for Linux on Windows (EFLOW) VM 来生成和部署模块。

本教程针对使用 Linux 容器运行 IoT Edge 的设备。 只要开发计算机可以运行 Linux 容器,就可以使用首选操作系统。 建议通过 Linux 容器使用 Visual Studio 进行开发,因此这就是本教程使用的工具。 还可以使用 Visual Studio Code,但两个工具提供的支持存在差异。 有关详细信息,请参阅使用 Visual Studio Code 开发 Azure IoT Edge 模块

设置 docker-cli 和 Docker 引擎远程连接

IoT Edge 模块被打包为容器,因此,需要在开发计算机上安装容器引擎来生成和管理容器。 EFLOW 虚拟机已包含 Docker 引擎的实例,因此本教程演示如何从 Windows 开发人员计算机远程连接到 EFLOW VM Docker 实例。 由于使用此方法,我们不再依赖于适用于 Windows 的 Docker Desktop。

第一步是在 Windows 开发计算机上配置 docker-cli,以便能够连接到远程 Docker 引擎。

  1. docker-cli Chocolatey 下载 docker-cli 的预编译 docker.exe 版本。 还可以从 docker/cli GitHub 下载官方 cli 项目,然后按照存储库说明对其进行编译。
  2. 将 docker.exe 提取到开发计算机中的某个目录。 例如 C:\Docker\bin
  3. 打开“关于你的电脑”->“系统信息”->“高级系统设置”
  4. 选择“高级”->“环境变量”-> 在“用户变量”下选中“Path”
  5. 编辑“Path”变量并添加 docker.exe 的位置
  6. 打开权限提升的 PowerShell 会话
  7. 使用该命令检查 Docker CLI 是否可访问
    docker --version
    

如果成功配置了所有设置,则上述命令应会输出 Docker 版本,类似于“Docker version 20.10.12, build e91ed57”。

第二步是配置 EFLOW 虚拟机 Docker 引擎以接受外部连接,并添加相应的防火墙规则。

警告

将 Docker 引擎公开给外部连接可能会增加安全风险。 请仅将此配置用于开发目的。 在开发完成后,确保将该配置还原为默认设置。

  1. 打开权限提升的 PowerShell 会话并运行以下命令

    # Configure the EFLOW virtual machine Docker engine to accept external connections, and add the appropriate firewall rules.
    Invoke-EflowVmCommand "sudo iptables -A INPUT -p tcp --dport 2375 -j ACCEPT"
    
    # Create a copy of the EFLOW VM _docker.service_ in the system folder.
    Invoke-EflowVmCommand "sudo cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service"
    
    # Replace the service execution line to listen for external connections.
    Invoke-EflowVmCommand "sudo sed -i 's/-H fd:\/\// -H fd:\/\/ -H tcp:\/\/0.0.0.0:2375/g'  /etc/systemd/system/docker.service"
    
    # Reload the EFLOW VM services configurations.
    Invoke-EflowVmCommand "sudo systemctl daemon-reload"
    
    # Reload the Docker engine service.
    Invoke-EflowVmCommand "sudo systemctl restart docker.service"
    
    # Check that the Docker engine is listening to external connections.
    Invoke-EflowVmCommand "sudo netstat -lntp | grep dockerd"
    

    下面是示例输出。

    PS C:\> # Configure the EFLOW virtual machine Docker engine to accept external connections, and add the appropriate firewall rules.
    PS C:\> Invoke-EflowVmCommand "sudo iptables -A INPUT -p tcp --dport 2375 -j ACCEPT"
    PS C:\>
    PS C:\> # Create a copy of the EFLOW VM docker.service in the system folder.
    PS C:\> Invoke-EflowVmCommand "sudo cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service"
    PS C:\>
    PS C:\> # Replace the service execution line to listen for external connections.
    PS C:\> Invoke-EflowVmCommand "sudo sed -i 's/-H fd:\/\// -H fd:\/\/ -H tcp:\/\/0.0.0.0:2375/g' /etc/systemd/system/docker.service"
    PS C:\>
    PS C:\> # Reload the EFLOW VM services configurations.
    PS C:\> Invoke-EflowVmCommand "sudo systemctl daemon-reload"
    PS C:\>
    PS C:\> # Reload the Docker engine service.
    PS C:\> Invoke-EflowVmCommand "sudo systemctl restart docker.service"
    PS C:\>
    PS C:\> # Check that the Docker engine is listening to external connections.
    PS C:\> Invoke-EflowVmCommand "sudo netstat -lntp | grep dockerd"
    tcp6       0      0 :::2375                 :::* LISTEN      2790/dockerd
    
  2. 最后一步是测试 Docker 与 EFLOW VM Docker 引擎的连接。 首先,需要 EFLOW VM IP 地址。

    Get-EflowVmAddr
    

    提示

    如果部署的 EFLOW VM 不使用静态 IP,则每次 Windows 主机 OS 重启或网络更改时,IP 地址可能会更改。 确保每次建立远程 Docker 引擎连接时都使用正确的 EFLOW VM IP 地址。

    下面是示例输出。

    PS C:\> Get-EflowVmAddr
    [03/15/2022 15:22:30] Querying IP and MAC addresses from virtual machine (DESKTOP-J1842A1-EFLOW)
     - Virtual machine MAC: 00:15:5d:6f:da:78
     - Virtual machine IP : 172.31.24.105 retrieved directly from virtual machine
    00:15:5d:6f:da:78
    172.31.24.105 
    
  3. 使用获取的 IP 地址连接到 EFLOW VM Docker 引擎,然后运行 Hello-World 示例容器。 请将 <EFLOW-VM-IP> 替换为在上一步获取的 EFLOW VM IP 地址。

    docker -H tcp://<EFLOW-VM-IP>:2375 run --rm hello-world
    

    应会看到容器正在下载,然后将会运行并输出以下结果。

    PS C:\> docker -H tcp://172.31.24.105:2375 run --rm hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    2db29710123e: Pull complete
    Digest: sha256:4c5f3db4f8a54eb1e017c385f683a2de6e06f75be442dc32698c9bbe6c861edd
    Status: Downloaded newer image for hello-world:latest
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (amd64)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/get-started/
    

创建 Azure IoT Edge 项目

可在 Visual Studio 的 IoT Edge 项目模板中创建可部署到 IoT Edge 设备中的解决方案。 首先创建一个 Azure IoT Edge 解决方案,并在该解决方案中生成第一个模块。 每一个 IoT Edge 解决方案都可包含多个模块。

重要

Visual Studio 创建的 IoT Edge 项目结构与 Visual Studio Code 中的不同。

目前,Azure IoT Edge 开发工具 CLI 不支持创建 Visual Studio 项目类型。 需要使用 Visual Studio IoT Edge 扩展来创建 Visual Studio 项目。

  1. 在 Visual Studio 中,创建新的项目。

  2. 在“创建新项目”页面中,搜索“Azure IoT Edge”。 选择与 IoT Edge 设备的平台(Linux IoT Edge 模块)和体系结构匹配的项目,然后选择“下一步”。

    Create New Project

  3. 在“配置新项目”中,输入项目名称并指定位置,然后选择“创建”。

  4. 在“添加模块”窗口中,选择想开发的模块类型。 还可以选择“现有模块”,可实现将现有 IoT Edge 模块加入部署。 指定模块名称和模块映像存储库。

  5. 在“存储库 URL”中提供模块的映像存储库的名称。 Visual Studio 使用localhost:5000/<你的模块名>自动填充模块名。 将其替换为你自己的注册表信息。 如果使用本地 Docker 注册表进行测试,请使用 localhost。 如果使用 Azure 容器注册表,那么请从注册表的设置中使用登录服务器。 登录服务器类似于 <注册表名称>.azurecr.cn。 仅替换字符串的 localhost:5000 部分,使最终结果类似于 <注册表名称>.azurecr.cn/<模块名称>

  6. 选择“添加”,将模块添加到项目中。

    Screenshot of adding how to add an application and module to Visual Studio solution

    注意

    如果你有现有的 IoT Edge 项目,可以通过打开 module.json 文件来更改存储库 URL。 存储库 URL 位于 JSON 文件的“repository”属性中。

现在,已在 Visual Studio 解决方案中创建了一个 IoT Edge 项目和 IoT Edge 模块。

项目结构

在解决方案中有两个项目级别的文件夹,包括主项目文件夹和一个模块文件夹。 例如,你可能有一个名为 AzureIotEdgeApp1 的主项目文件夹和一个名为 IotEdgeModule1 的模块文件夹。 主项目文件夹包含部署清单。

模块文件夹内有模块代码文件,该文件名为 Program.csmain.c,具体取决于所选语言。 该文件夹还含有名为 module.json 的文件,用于描述模块的元数据。 各种 Docker 文件可提供将模块生成为 Windows 或 Linux 容器所需的信息。

项目的部署清单

要编辑的部署清单名为 deployment.debug.template.json。 该文件是 IoT Edge 部署清单模板,用于定义设备上运行的所有模块,以及这些模块相互通信的方式。 有关部署清单的详细信息,请参阅了解如何部署模块和建立路由

打开此部署模板,可以看到其中包含“edgeAgent”和“edgeHub”这两个运行时模块,以及在此 Visual Studio 项目中创建的自定义模块。 另外,还有名为“SimulatedTemperatureSensor”的第四个模块。 此默认模块会生成用于测试模块的模拟数据。如果不需要此模块,亦可将其删除。 若要了解模拟温度传感器的工作原理,请查看 SimulatedTemperatureSensor.csproj 源代码

设置 IoT Edge 运行时版本

目前,最新的稳定运行时版本是 1.4。 应将 IoT Edge 运行时版本更新为最新的稳定版本或面向设备的相应版本。

  1. 在解决方案资源管理器中,右键单击主项目名称,然后选择“设置 IoT Edge 运行时版本”。

    Screenshot of how to find and select the menu item named 'Set IoT Edge Runtime version'.

  2. 使用下拉菜单选择 IoT Edge 设备正在运行的运行时版本,然后选择“确定”以保存更改。 如果未进行更改,选择“取消”可退出。

    目前该扩展不包括针对最新运行时版本的选择。 如果要设置高于 1.2 的运行时版本,请打开 deployment.debug.template.json 部署清单文件。 更改系统运行时模块映像 edgeAgent 和 edgeHub 的运行时版本。 例如,如果要使用 IoT Edge 运行时版本 1.4,请更改部署清单文件中的以下行:

    "systemModules": {
       "edgeAgent": {
        //...
          "image": "mcr.microsoft.com/azureiotedge-agent:1.4"
        //...
       "edgeHub": {
       //...
          "image": "mcr.microsoft.com/azureiotedge-hub:1.4",
       //...
    
  3. 如果更改了版本,请右键单击项目名称并选择“为 IoT Edge 生成部署”以重新生成部署清单。 该操作会基于部署模板生成部署清单,该清单将显示在 Visual Studio 项目的 “config” 文件夹中。

  1. 打开 deployment.debug.template.json 部署清单文件。 部署清单是一个 JSON 文档,用于描述要在目标 IoT Edge 设备上配置的模块。

  2. 更改系统运行时模块映像 edgeAgent 和 edgeHub 的运行时版本。 例如,如果要使用 IoT Edge 运行时版本 1.4,请更改部署清单文件中的以下行:

    "systemModules": {
        "edgeAgent": {
        //...
            "image": "mcr.microsoft.com/azureiotedge-agent:1.4",
        //...
        "edgeHub": {
        //...
            "image": "mcr.microsoft.com/azureiotedge-hub:1.4",
        //...
    

设置 Visual Studio 2022 远程 Docker 引擎实例

使用 Azure IoT Edge Tools 扩展,并将其配置为使用 EFLOW 虚拟机中运行的远程 Docker 引擎。

  1. 选择“工具”->“Azure IoT Edge 工具”->“IoT Edge 工具设置...”

  2. 将 DOCKER_HOST localhost 值替换为 EFLOW VM IP 地址。 如果你忘记了 IP 地址,请使用 EFLOW PowerShell cmdlet Get-EflowVmAddr 获取该地址。 例如,如果 EFLOW VM IP 地址为 172.20.1.100,则新值应为 tcp://172.20.1.100:2375。

    Screenshot of IoT Edge Tools settings

  3. 选择“确定”

开发模块

添加新模块后,其已附带随时可用于生成并部署到设备的默认代码,以便无需操作任何代码即可开始测试。 模块代码在模块文件夹中的文件名为 Program.cs(适用于 C#)或 main.c(适用于 C)。

生成默认解决方案后,系统会将“SimulatedTemperatureSensor”模块中的模拟数据路由到模块,该模块会接收输入内容,然后将其发送到 IoT 中心。

准备好使用自己的代码自定义模块模板时,请使用 Azure IoT 中心 SDK 生成其他模块,以解决 IoT 解决方案的关键需求,例如安全性、设备管理和可靠性。

生成并推送单个模块

通常,需要先测试和调试每个模块,然后再在具有多个模块的整个解决方案中运行此模块。 由于解决方案将使用在 EFLOW VM 中运行的 Docker 引擎进行生成或调试,因此第一步是生成和发布模块以启用远程调试。

  1. 在解决方案资源管理器中,选择并突出显示模块项目文件夹(例如 myIotEdgeModule)。 将自定义模块设置为启动项目。 在菜单中选择“项目”>“设为启动项目”。

  2. 若要调试 C# Linux 模块,需要更新 Dockerfile.amd64.debug 文件来启用 SSH 服务。 更新 Dockerfile.amd64.debug 文件来使用以下模板:Dockerfile for Azure IoT Edge AMD64 C# 模块和远程调试支持

    注意

    如果选择“调试”,Visual Studio 使用 Dockerfile.(amd64|windows-amd64).debug 生成 Docker 映像。 生成容器映像时,它将在该映像中包含 .NET Core 命令行调试器 VSDBG。 对于生产就绪的 IoT Edge 模块,建议使用“发布”配置,此模块可在没有 VSDBG 的情况下使用

    警告

    确保模板的最后一行 (ENTRYPOINT ["dotnet", "IotEdgeModule1.dll"]) 中的 DLL 名称与 IoT Edge 模块项目的名称匹配。

    Screenshot of setting the Dockerfile template

  3. 若要与 Linux 模块建立 SSH 连接,需要创建一个 RSA 密钥。 打开权限提升的 PowerShell 会话并运行以下命令,以创建新的 RSA 密钥。 确保将 RSA 密钥保存在同一 IoT Edge 模块文件夹下,并且密钥的名称为 id_rsa。

    ssh-keygen -t RSA -b 4096 -m PEM
    

    Screenshot of how to create an SSH key

  4. 如果使用的是专用注册表(如 Azure 容器注册表 (ACR)),请使用以下 Docker 命令登录。 可以从 Azure 门户的注册表的“访问密钥”页中获取用户名和密码。 如果使用的是本地注册表,可运行本地注册表

    docker -H tcp://<EFLOW-VM-IP>:2375 login -u <ACR username> -p <ACR password> <ACR login server>
    
  1. 在“解决方案资源管理器”中,右键单击项目文件夹,选择“生成并推送 IoT Edge 模块”,为每个模块生成和推送 Docker 映像。

  2. 如果使用的是专用注册表(如 Azure 容器注册表),则需要将注册表登录信息添加到文件 deployment.template.json 中的运行时设置。 将占位符替换为实际 ACR 管理员用户名、密码和注册表名。

          "settings": {
            "minDockerVersion": "v1.25",
            "loggingOptions": "",
            "registryCredentials": {
              "registry1": {
                "username": "<username>",
                "password": "<password>",
                "address": "<registry name>.azurecr.cn"
              }
            }
          }
    

    注意

    本文使用 Azure 容器注册表的管理员登录凭据,其十分适用于开发和测试方案。 为生产方案做好准备后,建议使用最低权限身份验证选项(如服务主体)。 有关详细信息,请参阅管理容器注册表的访问权限

  3. 需要公开端口 22 以访问模块 SSH 服务。 本教程使用 10022 作为主机端口,但你可以指定不同的端口,用作连接到 Linux C# 模块时使用的 SSH 端口。 需要将 SSH 端口信息添加到文件 deployment.debug.template.json 中此 Linux 模块设置的“createOptions”。

         "createOptions": {
            "HostConfig": {
               "Privileged": true,
               "PortBindings": {
                     "22/tcp": [
                        {
                           "HostPort": "10022"
                        }
                     ]
               }
            }
         }
    
  4. 在“解决方案资源管理器”中,右键单击项目文件夹并选择“为 IoT Edge 生成部署”以生成新的 IoT Edge 部署 json。

  5. 通过单击“视图”“Cloud Explorer”打开 Cloud Explorer。 确保已登录到 Visual Studio 2019。

  6. 在 Cloud Explorer 中,展开订阅并找到要部署的 Azure IoT 中心和 Azure IoT Edge 设备 。

  7. 右键单击 IoT Edge 设备并选择“创建部署”。 在 Visual Studio 解决方案的 config 文件夹中,导航到为平台配置的调试部署清单,例如 deployment.amd64.json

生成模块 Docker 映像

开发模块后,可以生成模块映像以存储在容器注册表中,以便部署到 IoT Edge 设备。

使用模块的 Dockerfile 生成模块 Docker 映像。

docker build --rm -f "<DockerFilePath>" -t <ImageNameAndTag> "<ContextPath>" 

例如,假设命令 shell 位于项目目录中,且模块名称为 IotEdgeModule1。 若要为本地注册表或 Azure 容器注册表生成映像,请使用以下命令:

# Build the image for the local registry

docker build --rm -f "./IotEdgeModule1/Dockerfile.amd64.debug" -t localhost:5000/iotedgemodule1:0.0.1-amd64 "./IotEdgeModule1"

# Or build the image for an Azure Container Registry

docker build --rm -f "./IotEdgeModule1/Dockerfile.amd64.debug" -t myacr.azurecr.cn/iotedgemodule1:0.0.1-amd64 "./IotEdgeModule1"

推送模块 Docker 映像

将模块映像推送到本地注册表或容器注册表。

docker push <ImageName>

例如:

# Push the Docker image to the local registry

docker push localhost:5000/iotedgemodule1:0.0.1-amd64

# Or push the Docker image to an Azure Container Registry
az acr login --name myacr
docker push myacr.azurecr.cn/iotedgemodule1:0.0.1-amd64

将模块部署到 IoT Edge 设备。

在 Visual Studio 中,打开主项目中的 deployment.debug.template.json 部署清单文件。 部署清单是一个 JSON 文档,用于描述要在目标 IoT Edge 设备上配置的模块。 在部署之前,需要更新 Azure 容器注册表凭据、模块映像以及适当的 createOptions 值。 若要了解 createOption 值的详细信息,请参阅如何配置 IoT Edge 模块的容器创建选项

  1. 如果使用 Azure 容器注册表来存储模块映像,则需要在 “edgeAgent” 设置中将凭据添加到 “deployment.debug.template.json”。 例如,

    "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "runtime": {
          "type": "docker",
          "settings": {
            "minDockerVersion": "v1.25",
            "loggingOptions": "",
            "registryCredentials": {
              "myacr": {
                "username": "myacr",
                "password": "<your_acr_password>",
                "address": "myacr.azurecr.cn"
              }
            }
          }
        },
    //...
    
  2. image 属性值替换为推送到注册表的模块映像名称。 例如,如果为自定义模块 IotEdgeModule1 推送了标记为 myacr.azurecr.cn/iotedgemodule1:0.0.1-amd64 的映像,请使用该标记值替换映像属性值。

  3. 对于部署模板中的每个系统和自定义模块,添加或将 createOptions 替换为字符串化内容。

    例如,IotEdgeModule1 的映像和 createOptions 设置应类似于以下内容:

    "IotEdgeModule1": {
    "version": "1.0.0",
    "type": "docker",
    "status": "running",
    "restartPolicy": "always",
    "settings": {
        "image": "myacr.azurecr.cn/iotedgemodule1:0.0.1-amd64",
        "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
    }
    

使用 IoT Edge Azure CLI set-modules 命令将模块部署到 Azure IoT 中心。 例如,若要将 deployment.debug.amd64.json 文件中定义的模块部署到 IoT Edge 设备 my-device 的 IoT 中心 my-iot-hub,请使用以下命令:

az iot edge set-modules --hub-name my-iot-hub --device-id my-device --content ./deployment.debug.template.json --login "HostName=my-iot-hub.azure-devices.cn;SharedAccessKeyName=iothubowner;SharedAccessKey=<SharedAccessKey>"

提示

可以在 Azure 门户中的“Azure IoT 中心”>“安全设置”>“共享访问策略”下找到 IoT 中心连接字符串。

  1. 在“Cloud Explorer”中,右键单击你的边缘设备并刷新,以查看与 $edgeAgent 和 $edgeHub 模块一起运行的新模块。

调试解决方案

  1. 使用权限提升的 PowerShell 会话运行以下命令

    1. 根据用于 Linux C# 模块的名称获取 moduleId。 请务必将 <iot-edge-module-name> 占位符替换为你的模块名称。

      $moduleId = Invoke-EflowVmCommand "sudo docker ps -aqf name=<iot-edge-module-name>"
      
    2. 检查 $moduleId 是否正确 - 如果该变量为空,请确保使用正确的模块名称

    3. 在 Linux 容器中启动 SSH 服务

      Invoke-EflowVmCommand "sudo docker exec -it -d $moduleId service ssh start"
      
    4. 在 EFLOW VM 上打开模块 SSH 端口(本教程使用端口 10022)

      Invoke-EflowVmCommand "sudo iptables -A INPUT -p tcp --dport 10022 -j ACCEPT"
      

    警告

    出于安全原因,每次 EFLOW VM 重启时,IP 表规则都会删除现有设置并恢复原始设置。 此外,必须再次手动启动模块 SSH 服务。

  2. 成功启动 SSH 服务后,选择“调试”->“附加到进程”,将“连接类型”设置为“SSH”,将“连接目标”设置为你的 EFLOW VM 的 IP 地址。 如果你不知道 EFLOW VM IP,可以使用 Get-EflowVmAddr PowerShell cmdlet。 首先,键入 IP 并按 Enter。 在弹出窗口中输入以下配置:

    字段
    主机名 使用 EFLOW VM IP
    端口 10022(或在部署配置中使用的端口)
    用户名 root
    身份验证类型 私钥
    私钥文件 上一步中创建的 id_rsa 的完整路径
    密码 用于上一步中创建的密钥的密码

    Screenshot of how to connect to a remote system

  3. 使用 SSH 成功连接到模块后,可以选择进程并选择“附加”。 对于 C# 模块,需要选择进程“dotnet”,然后依次选择“附加到”、“托管(CoreCLR)”。 首次运行可能需要 10 到 20 秒的时间。

    Screenshot of how to attach an edge module process.

  4. 设置用于检查模块的断点。

    • 如果在 C# 环境中开发,请在 ModuleBackgroundService.csPipeMessage() 函数中设置断点。
    • 如果是 C 环境,在“main.c”的 InputQueue1Callback() 函数中设置断点。
  5. SimulatedTemperatureSensor 的输出应会重定向到自定义 Linux C# 模块的 input1。 应触发断点。 可在 Visual Studio“局部变量”窗口中监视变量 。

    Screenshot of how to debug a single module

  6. 按 Ctrl+F5 或选择“停止”按钮可停止调试 。

清理资源

如果打算继续学习下一篇建议的文章,可以保留已创建的资源和配置,以便重复使用。 还可以继续使用相同的 IoT Edge 设备作为测试设备。

否则,可以删除本文中使用的本地配置和 Azure 资源,以免产生费用。

删除 Azure 资源

删除 Azure 资源和资源组的操作不可逆。 请确保不要意外删除错误的资源组或资源。 如果在现有的包含要保留资源的资源组中创建了 IoT 中心,请只删除 IoT 中心资源本身,而不要删除资源组。

若要删除资源,请执行以下操作:

  1. 登录到 Azure 门户,然后选择“资源组”。

  2. 选择包含 IoT Edge 测试资源的资源组的名称。

  3. 查看资源组中所包含资源的列表。 若要删除这一切,可以选择“删除资源组”。 如果只需删除部分内容,可以单击要单独删除的每个资源。

后续步骤

在本教程中,你在开发计算机上设置了 Visual Studio,并从中部署和调试了你的第一个 IoT Edge 模块。 你已经了解基本概念,请尝试向模块添加功能,以便它可以分析通过它传递的数据。