你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

教程:使用 IoT Edge for Linux on Windows 创建 IoT Edge 设备的层次结构

适用于:IoT Edge 1.5 复选标记 IoT Edge 1.5 IoT Edge 1.4 复选标记 IoT Edge 1.4

重要

IoT Edge 1.5 LTS 和 IoT Edge 1.4 LTS 是受支持的版本。 IoT Edge 1.4 LTS 的生命周期结束日期为 2024 年 11 月 12 日。 如果你使用的是早期版本,请参阅更新 IoT Edge

可以在层次结构层中组织的网络之间部署 Azure IoT Edge 节点。 层次结构中的每一层都是一个网关设备,用于处理来自其下一层中设备的消息和请求。 此配置也称为嵌套边缘

你可构建设备的层次结构,使得只有顶层可连接到云,而下层只能与相邻的南北层通信。 大多数工业网络遵循 ISA-95 标准,而这种网络分层是其基础。

本教程将指导你使用 IoT Edge for Linux on Windows 创建 IoT Edge 设备的层次结构,将 IoT Edge 运行时容器部署到设备,并在本地配置设备。 你会执行以下任务:

  • 创建和定义 IoT Edge 设备层次结构中的关系。
  • 在层次结构中的设备上配置 IoT Edge 运行时。
  • 在设备层次结构中安装一致的证书。
  • 向层次结构中的设备添加工作负载。
  • 使用 IoT Edge API 代理模块,通过下层设备中的单个端口安全地路由 HTTP 流量。

提示

本教程包括混合使用手动和自动化步骤来展示嵌套的 IoT Edge 功能。

如果你想要以全自动化方式设置 IoT Edge 设备的层次结构,可以参考脚本化的适用于工业 IoT 的 Azure IoT Edge 示例运行自己的脚本。 这一已编写了脚本的方案将 Azure 虚拟机部署为预配置设备以模拟工厂环境。

要深入了解创建和管理 IoT Edge 设备层次结构的手动步骤,请参阅 IoT Edge 设备网关层次结构操作指南

在本教程中,定义了以下网络层:

  • 顶层:此层的 IoT Edge 设备可直接连接到云。

  • 下层:位于顶层下面的层的 IoT Edge 设备无法直接连接到云。 它们需要通过一个或多个中间 IoT Edge 设备来发送和接收数据。

为简单起见,本教程使用双设备层次结构。 顶层设备表示位于层次结构顶层的设备,它可以直接连接到云。 该设备也称为“父设备”。 下层设备表示位于层次结构下层的设备,它无法直接连接到云。 可以根据需要添加更多的设备来代表你的生产环境。 下层设备也称为“子设备”。

教程层次结构,其中包含两个设备:顶层设备和下层设备

注意

子设备可以是下游设备,也可以是嵌套拓扑中的网关设备。

先决条件

若要创建 IoT Edge 设备的层次结构,需要:

  • 使用安装了 Azure IoT 扩展 v0.10.6 或更高版本的 Azure CLI v2.3.1 的 Azure Cloud Shell 中的 Bash Shell。 本教程使用 Azure Cloud Shell。 若要查看 Azure CLI 模块和扩展的当前版本,请运行 az version
  • 两个运行 Azure IoT Edge for Linux on Windows 的 Windows 设备。 应使用外部虚拟交换机部署这两个设备。

提示

如果在 Windows 主机操作系统上配置了端口转发,则可以使用内部或默认虚拟交换机。 但是,为简单起见,在本教程中,这两个设备都使用外部虚拟交换机并连接到同一个外部网络。

有关网络的详细信息,请参阅 Azure IoT Edge for Linux on Windows 网络Azure IoT Edge for Linux on Windows 的网络配置

如果需要在 DMZ 上设置 EFLOW 设备,请参阅如何配置 Azure IoT Edge for Linux on Windows 工业 IoT 与 DMZ 配置

  • 含有效订阅的 Azure 帐户。 如果还没有 Azure 订阅,可以在开始前创建一个免费帐户
  • Azure 中的免费或标准层 IoT 中心
  • 请确保以下端口对于所有设备均为开放入站(最下层设备 443、5671、8883 除外):
    • 443:在父边缘中心和子边缘中心之间用于 REST API 调用,并拉取 docker 容器映像。
    • 5671、8883:用于 AMQP 和 MQTT。

提示

有关 EFLOW 虚拟机防火墙的详细信息,请参阅 IoT Edge for Linux on Windows 安全性

创建 IoT Edge 设备层次结构

IoT Edge 设备构成层次结构的各个层。 本教程会创建包含两个 IoT Edge 设备的层次结构:顶层设备下层设备。 可根据需要创建更多下游设备。

若要创建和配置 IoT Edge 设备的层次结构,请使用 az iot edge devices create Azure CLI 命令。 此命令可简化层次结构的配置,自动完成并浓缩数个步骤:

  • 在 IoT 中心中创建设备
  • 设置父子关系以授权设备间的通信
  • 将部署清单应用于每个设备
  • 为每个设备生成证书链以在它们之间建立安全通信
  • 为每个设备生成配置文件

创建设备配置

创建一组嵌套边缘设备,其中包含一个父设备和一个子设备。 在本教程中,我们使用基本的示例部署清单。 有关其他方案示例,请查看配置示例模板

  1. 在使用 az iot edge devices create 命令之前,需要为顶层和下层设备定义部署清单。 将 deploymentTopLayer.json 示例文件下载到本地计算机。

    顶层设备部署清单定义 IoT Edge API 代理模块,并从下层设备向 IoT 中心声明路由

  2. deploymentLowerLayer.json 示例文件下载到本地计算机。

    下层设备部署清单包括模拟温度传感器模块,并将路由声明到顶层设备。 可以在 systemModules 节中看到,运行时模块设为从 $upstream:443 拉取,而不是 mcr.microsoft.com。 下层设备将 Docker 映像请求发送到端口 443 上的 IoT Edge API 代理模块,因为它无法直接从云中拉取映像。 另一个部署到下层设备的模块(模拟温度传感器模块)也向 $upstream:443 发出其映像请求 。

    有关如何创建下层部署清单的详细信息,请参阅连接 Azure IoT Edge 设备以创建层次结构

  3. Azure Cloud Shell 中,使用 az iot edge devices create Azure CLI 命令为层次结构中的每个设备创建 IoT 中心和配置捆绑包中的设备。 将以下占位符替换为合适的值:

    占位符 说明
    <hub-name> IoT 中心的名称。
    <config-bundle-output-path> 要在其中保存配置捆绑包的文件夹路径。
    <parent-device-name> 顶层父设备 ID 名称。
    <parent-deployment-manifest> 父设备部署清单文件。
    <parent-fqdn-or-ip> 父设备完全限定的域名 (FQDN) 或 IP 地址。
    <child-device-name> 下层子设备 ID 名称。
    <child-deployment-manifest> 子设备部署清单文件。
    <child-fqdn-or-ip> 子设备完全限定的域名 (FQDN) 或 IP 地址。
    az iot edge devices create \
       --hub-name <hub-name> \
       --output-path <config-bundle-output-path> \
       --default-edge-agent "mcr.microsoft.com/azureiotedge-agent:1.4" \
       --device id=<parent-device-name> \
          deployment=<parent-deployment-manifest> \
          hostname=<parent-fqdn-or-ip> \
       --device id=child-1 \
          parent=parent-1 \
          deployment=<child-deployment-manifest> \
          hostname=<child-fqdn-or-ip>
    

    例如,以下命令会在 IoT 中心创建包含两个 IoT Edge 设备的层次结构。 名为 parent-1 的顶层设备和名为 child-1* 的下层设备。 该命令将每个设备的配置捆绑包保存在输出目录中。 该命令还会生成自签名测试证书,并将其包含在配置捆绑包中。 使用安装脚本在每个设备上安装配置捆绑包。

    az iot edge devices create \
       --hub-name my-iot-hub \
       --output-path ./output \
       --default-edge-agent "mcr.microsoft.com/azureiotedge-agent:1.4" \
       --device id=parent-1 \
          deployment=./deploymentTopLayer.json \
          hostname=10.0.0.4 \
       --device id=child-1 \
          parent=parent-1 \
          deployment=./deploymentLowerLayer.json \
          hostname=10.1.0.4
    

运行命令后,可以在输出目录中找到设备配置捆绑包。 例如:

PS C:\nested-edge\output> dir

   Directory: C:\nested-edge\output

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           4/10/2023  4:12 PM           7192 child-1.tgz
-a---           4/10/2023  4:12 PM           6851 parent-1.tgz

可以使用自己的证书和密钥作为参数传递给命令,也可以创建更复杂的设备层次结构。 有关使用 az 命令创建嵌套设备的详细信息,请参阅 az iot edge devices create。 如果不熟悉如何在网关应用场景下使用证书,请参阅操作指南的证书部分

在本教程中,你要使用内联参数创建设备和配置捆绑包。 还可以使用 YAML 或 JSON 格式的配置文件。 有关示例配置文件,请参阅示例 sample_devices_config.yaml

配置 IoT Edge 运行时

除了预配你的设备之外,配置步骤还使用你之前创建的证书在层次结构中的设备之间建立受信任的通信。 这些步骤还会开始建立层次结构的网络结构。 顶层设备会保持 Internet 连接,以便从云中拉取其运行时的映像,而下层设备则会通过顶层设备进行路由,以便访问这些映像。

要配置 IoT Edge 运行时,需要将配置捆绑包应用到设备。 顶层设备下层设备的配置稍有不同,因此请注意要应用到每个设备的设备配置文件。

每个设备都需要其相应的配置捆绑包。 可使用 U 盘或通过安全文件复制操作将配置捆绑包移动到每个设备上。 需要将配置捆绑包复制到每个 EFLOW 设备的 Windows 主机操作系统,然后将其复制到 EFLOW VM。

警告

请确保向每个设备发送正确的配置捆绑包。

顶层设备配置

  1. 连接到顶层 Windows 主机设备,然后将 parent-1.tzg 文件复制到设备。

  2. 使用“以管理员身份运行”启动提升的 PowerShell 会话。

  3. parent-1.tzg 复制到 EFLOW VM 中。

    Copy-EflowVmFile -fromFile parent-1.tzg -toFile ~/ -pushFile
    
  4. 连接到 EFLOW 虚拟机

    Connect-EflowVm
    
  5. 提取配置捆绑包存档。 例如,使用 tar 命令提取 parent-1 存档文件:

    tar -xzf ./parent-1.tgz
    
  6. 设置安装脚本的执行权限。

    chmod +x install.sh
    
  7. 运行 install.sh 脚本。

    sudo sh ./install.sh
    
  8. 应用正确的证书权限并重启 IoT Edge 运行时。

    sudo chmod -R 755 /etc/aziot/certificates/
    sudo iotedge system restart
    
  9. 检查所有 IoT Edge 服务是否正常运行。

    sudo iotedge system status
    
  10. 最后,添加适当的防火墙规则以在下层设备与顶层设备之间启用连接。

    sudo iptables -A INPUT -p tcp --dport 5671 -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport 8883 -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
    sudo iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    sudo iptables-save | sudo tee /etc/systemd/scripts/ip4save
    
  11. 在设备上运行配置和连接性检查。

    sudo iotedge check
    

在上层设备中,你会看到一个输出,其中包含多个传递评估。 可能会显示有关日志策略的一些警告,具体取决于网络情况和 DNS 策略。

如果你想要更深入地了解对设备配置文件所做的修改,请参阅操作指南的在设备上配置 IoT Edge 部分

下层设备配置

  1. 连接到下层 Windows 主机设备,然后将 child-1.tzg 文件复制到设备。

  2. 使用“以管理员身份运行”启动提升的 PowerShell 会话。

  3. child-1.tzg 复制到 EFLOW VM。

    Copy-EflowVmFile -fromFile child-1.tzg -toFile ~/ -pushFile
    
  4. 连接到 EFLOW 虚拟机

    Connect-EflowVm
    
  5. 提取配置捆绑包存档。 例如,使用 tar 命令提取 child-1 存档文件:

    tar -xzf ./child-1.tgz
    
  6. 设置安装脚本的执行权限。

    chmod +x install.sh
    
  7. 运行 install.sh 脚本。

    sudo sh ./install.sh
    
  8. 应用正确的证书权限并重启 IoT Edge 运行时。

    sudo chmod -R 755 /etc/aziot/certificates/
    sudo iotedge system restart
    
  9. 检查所有 IoT Edge 服务是否正常运行。

    sudo iotedge system status
    
  10. 在设备上运行配置和连接性检查。 对于下层设备,需要在命令中手动传递诊断映像:

    sudo iotedge check --diagnostics-image-name <parent_device_fqdn_or_ip>:443/azureiotedge-diagnostics:1.2
    

如果你已正确完成前述步骤,可以验证设备是否已正确配置。 确认每个设备上的配置正确后,可以继续操作。

设备模块部署

在 IoT 中心中创建设备时,应用了设备的模块部署。 az iot edge devices create 命令为顶层和下层设备应用了部署 JSON 文件。 这些部署完成后,下层设备会使用 IoT Edge API 代理模块来拉取它所需的映像。

除了 IoT Edge 代理和 IoT Edge 中心这两个运行时模块外,上层设备还会接收 Docker 注册表模块和 IoT Edge API 代理模块 。

Docker 注册表模块指向现有的 Azure 容器注册表。 在本例中,REGISTRY_PROXY_REMOTEURL 指向 Microsoft Container Registry。 Docker 注册表默认侦听端口 5000。

IoT Edge API 代理模块可将 HTTP 请求路由到其他模块,使下层设备能拉取容器映像或将 blob 推送到存储。 在本教程中,它在端口 443 上进行通信,并配置为将 Docker 容器映像拉取请求路由发送到端口 5000 上的 Docker 注册表模块。 此外,所有 blob 存储都将请求路由上传到端口 11002 上的 AzureBlobStorageonIoTEdge 模块。 有关 IoT Edge API 代理模块及其配置方法的详细信息,请参阅模块的操作指南

要查看如何通过 Azure 门户或 Azure Cloud Shell 创建与此类似的部署,请参阅操作指南的上层设备部分

你可以使用以下命令查看模块的状态:

az iot hub module-twin show --device-id <edge-device-id> --module-id '$edgeAgent' --hub-name <iot-hub-name> --query "properties.reported.[systemModules, modules]"

此命令会输出所有 edgeAgent 报告的属性。 下面是一些有助于监视设备状态的命令:runtime status、runtime start time、runtime last exit time、runtime restart count 。

你还可以在 Azure 门户上查看模块的状态。 导航到 IoT 中心的“设备”部分,查看设备和模块。

查看生成的数据

你推送的模拟温度传感器模块会生成示例环境数据。 它将发送包含环境温度和湿度、机器温度和压力以及时间戳的消息。

还可以通过 Azure Cloud Shell 查看这些消息:

az iot hub monitor-events -n <iot-hub-name> -d <lower-layer-device-name>

例如:

az iot hub monitor-events -n my-iot-hub -d child-1
{
    "event": {
        "origin": "child-1",
        "module": "simulatedTemperatureSensor",
        "interface": "",
        "component": "",
        "payload": "{\"machine\":{\"temperature\":104.29281270901808,\"pressure\":10.48905461241978},\"ambient\":{\"temperature\":21.086561171611102,\"humidity\":24},\"timeCreated\":\"2023-04-17T21:50:30.1082487Z\"}"
    }
}

故障排除

运行 iotedge check 命令来验证配置并解决错误。

即使下游设备没有直接访问 Internet 的权限,也可以在嵌套层次结构中运行 iotedge check

从下层运行 iotedge check 时,程序将尝试通过端口 443 从父计算机拉取映像。

sudo iotedge check --diagnostics-image-name $upstream:443/azureiotedge-diagnostics:1.2

azureiotedge-diagnostics 值是从与注册表模块链接的容器注册表中拉取的。 本教程将其默认设置为 https://mcr.microsoft.com

名称
REGISTRY_PROXY_REMOTEURL https://mcr.microsoft.com

如果使用的是专用容器注册表,请确保容器注册表中包含所有映像(IoTEdgeAPIProxy、edgeAgent、edgeHub、模拟温度传感器映像和诊断映像)。

如果下游设备的处理器体系结构与父设备不同,则需要相应的体系结构映像。 可以使用连接的注册表,也可以在下游设备 config.toml 文件中为 edgeAgentedgeHub 模块指定正确的映像。 例如,如果父设备在 ARM32v7 体系结构上运行,而下游设备在 AMD64 体系结构上运行,则需要在下游设备的 config.toml 文件中指定匹配的版本和体系结构映像标记。

[agent.config]
image = "$upstream:443/azureiotedge-agent:1.4.10-linux-amd64"

"systemModules": {
   "edgeAgent": {
      "settings": {
            "image": "$upstream:443/azureiotedge-agent:1.4.10-linux-amd64"
      },
   },
   "edgeHub": {
      "settings": {
            "image": "$upstream:443/azureiotedge-hub:1.4.10-linux-amd64",
      }
   }
}

清理资源

可以删除本文中创建的本地配置和 Azure 资源,以避免收费。

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

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

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

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

后续步骤

在本教程中,你已将两个 IoT Edge 设备配置为网关,并设置了一个作为另一个设备的父设备。 然后,演示了如何使用 IoT Edge API 代理模块通过网关将容器映像拉取到子设备上。 要了解详细信息,请参阅代理模块用法操作指南

要详细了解如何使用网关创建 IoT Edge 设备的层次结构,请参阅以下文章。