连接Azure IoT Edge设备以创建层次结构

适用范围:IoT Edge 1.5 checkmark IoT Edge 1.5

重要

IoT Edge 1.5 LTS 是受支持的版本。 IoT Edge 1.4 LTS 于 2024 年 11 月 12 日终止。 如果使用的是早期版本,请参阅 Update IoT Edge

本文介绍如何在IoT Edge网关与下游IoT Edge设备之间建立受信任的连接。 此配置称为 嵌套边缘

在网关方案中,IoT Edge设备可以是网关和下游设备。 可以分层多个IoT Edge网关来创建设备层次结构。 下游(子)设备通过其网关(父)设备进行身份验证和发送或接收消息。

本文介绍网关层次结构中IoT Edge设备的两种配置。 第一个是 顶层 IoT Edge 设备。 当多个IoT Edge设备相互连接时,任何没有父设备但直接连接到IoT Hub的设备都被视为位于顶层。 此设备负责处理其下的所有设备的请求。 其他配置适用于层次结构的较低层中的任何 IoT Edge 设备。 这些设备可能是其他下游 IoT 和IoT Edge设备的网关,但还需要通过自己的父设备路由任何通信。

某些网络体系结构要求只有层次结构中的顶部IoT Edge设备才能连接到云。 在此配置中,层次结构下层中的所有IoT Edge设备只能与其网关(父级)设备和任何下游(子)设备通信。

本文中的步骤基于 配置IoT Edge设备以充当透明网关,它将IoT Edge设备设置为下游 IoT 设备的网关。 同样的基本步骤适用于所有网关方案:

  • Authentication:为网关层次结构中的所有设备创建IoT Hub标识。
  • Authorization:在IoT Hub中设置父/子关系,授权下游设备能够像连接到IoT Hub一样连接到其父设备。
  • 网关发现:确保下游设备能够在本地网络上找到其父设备。
  • 安全连接:使用属于同一链的受信任证书建立安全连接。

先决条件

  • 免费或标准IoT中心。
  • 至少两个IoT Edge设备,一个是顶层设备和一个或多个下层设备。 如果没有可用的 IoT Edge 设备,可以在 Ubuntu 虚拟机上运行 Azure IoT Edge。
  • 如果使用 Azure CLI 创建和管理设备,请安装 Azure IoT 扩展

提示

本文提供详细的步骤和选项,以便帮助你创建适用于你的方案的网关层次结构。 有关引导式教程,请参阅 使用网关创建IoT Edge设备的层次结构

创建网关层次结构

可以通过在方案中为IoT Edge设备定义父/子关系来创建IoT Edge网关层次结构。 可以在创建新设备标识时设置父设备,也可以管理现有设备标识的父项和子项。

设置父/子关系的步骤允许下游设备就像连接到 IoT Hub 一样连接到其父设备。

只有 IoT Edge 设备可以是父设备,但 IoT Edge 设备和 IoT 设备都可以是子设备。 父母可以有多个孩子,但孩子只能有一个父母。 通过将父集和子集相互链接来创建网关层次结构,使一个设备的子集成为另一个设备的父集。

默认情况下,一个父对象最多只能有 100 个子对象。 可以通过在父设备的 edgeHub 模块中设置“MaxConnectedClients”环境变量来更改此限制。

在Azure portal中,可以在创建新设备标识或编辑现有设备时管理父/子关系。

创建新的IoT Edge设备时,可以选择从中心的现有IoT Edge设备列表中选择父设备和子设备。

  1. Azure portal 中,导航到IoT hub。
  2. Device management菜单中选择Devices
  3. 选择Add device,然后选中IoT Edge Device复选框。
  4. 除了设置设备 ID 和身份验证设置,还可以选择“设置父设备”或“选择子设备”。
  5. 选择要用作父设备或子设备的设备。

还可以为现有设备创建或管理父/子关系。

  1. Azure portal 中,导航到IoT hub。
  2. Device management菜单中选择Devices
  3. 从列表中选择要管理的 IoT Edge 设备
  4. 选择“设置父设备”齿轮图标“管理子设备”
  5. 添加或删除任何父设备或子设备。

注意事项

若要以编程方式建立父关系和子关系,请使用 C#、Java 或 Node.js < c0>IoT Hub Service SDK。

下面是使用 C# SDK 分配子设备的示例RegistryManager_AddAndRemoveDeviceWithScope() 任务演示如何以编程方式创建三层的层次结构。 IoT Edge设备位于第一层,作为父级。 另一个IoT Edge设备位于第二层,同时充当子级和父级。 最后,IoT 设备处于第三层,作为最低层子设备。

生成证书

必须在同一网关层次结构中的所有设备上安装一致的证书链,才能在它们之间建立安全通信。 层次结构中的每台设备,无论是 IoT Edge 设备还是 IoT 下游设备,都需要拥有同一个根 CA 证书的副本。 层次结构中的每个 IoT 边缘设备会将该根 CA 证书用作其边缘 CA 证书的根。

通过该配置,每个下游 IoT Edge 设备都可以验证其父设备的身份,即确保它们连接到的 edgeHub 具备由共享根 CA 证书签名的服务器证书。

网关和下游设备上的根 CA 颁发的证书链插图

有关IoT Edge证书要求的详细信息,请参阅 了解Azure IoT Edge如何使用证书

  1. 创建或请求以下证书:

    • 根 CA 证书,是给定网关层次结构中所有设备的最顶层共享证书。 此证书安装在所有设备上。
    • 要包括在根证书链中的任何中间证书。
    • Edge CA 证书及其私钥,由根证书和中间证书生成。 网关层次结构中的每个IoT Edge设备都需要一个唯一的 Edge CA 证书。

    可以使用自签名证书颁发机构,也可以从受信任的商业证书颁发机构(如 DigiCert、Verisign 或 GlobalSign)购买。

  2. 如果没有用于测试的证书,请创建一组根证书和中间证书,然后为每个设备创建 Edge CA 证书。 例如,这些命令创建根 CA 证书、父设备证书和子设备证书。

    # !!! For test only - do not use in production !!!
    
    # Create the the root CA test certificate
    ./certGen.sh create_root_and_intermediate
    
    # Create the parent (gateway) device test certificate 
    # signed by the shared root CA certificate
    ./certGen.sh create_edge_device_ca_certificate "gateway"
    
    # Create the downstream device test certificate
    # signed by the shared root CA certificate
    ./certGen.sh create_edge_device_ca_certificate "downstream"
    

    警告

    请勿将测试脚本创建的证书用于生产。 它们包含硬编码密码,并会在 30 天后过期。 出于演示目的提供了测试 CA 证书,以帮助你了解 CA 证书。 在生产环境中使用你自己的最佳安全做法来创建认证和管理生存期。

    有关创建测试证书的详细信息,请参阅 创建演示证书以测试IoT Edge设备功能

  3. 需要将证书和密钥传输到每个设备。 可以使用 USB 驱动器、Azure Key Vault 等服务,或者使用 Secure 文件复制等函数。 选择与您场景最匹配的方法之一。 将文件复制到证书和密钥的首选目录。 对证书使用 /var/aziot/certs,对密钥使用 /var/aziot/secrets

有关在设备上安装证书的详细信息,请参阅 IoT Edge 设备上的 Manage 证书

配置父设备

要配置父设备,请打开本地或远程命令行界面。

若要启用安全连接,网关方案中的每个IoT Edge父设备都需要使用唯一的 Edge CA 证书和网关层次结构中所有设备共享的根 CA 证书的副本进行配置。

  1. 检查你的证书是否符合格式要求

  2. 将根 CA 证书、父 Edge CA 证书和父私钥传输到父设备

  3. 将证书和密钥复制到正确的目录。 对于设备证书,首选目录为 /var/aziot/certs;对于密钥,首选目录为 /var/aziot/secrets

    ### Copy device certificate ###
    
    # If the device certificate and keys directories don't exist, create, set ownership, and set permissions
    sudo mkdir -p /var/aziot/certs
    sudo chown aziotcs:aziotcs /var/aziot/certs
    sudo chmod 755 /var/aziot/certs
    
    sudo mkdir -p /var/aziot/secrets
    sudo chown aziotks:aziotks /var/aziot/secrets
    sudo chmod 700 /var/aziot/secrets
    
    # Copy full-chain device certificate and private key into the correct directory
    sudo cp iot-edge-device-ca-gateway-full-chain.cert.pem /var/aziot/certs
    sudo cp iot-edge-device-ca-gateway.key.pem /var/aziot/secrets
    
    ### Root certificate ###
    
    # Copy root certificate into the /certs directory
    sudo cp azure-iot-test-only.root.ca.cert.pem /var/aziot/certs
    
    # Copy root certificate into the CA certificate directory and add .crt extension.
    # The root certificate must be in the CA certificate directory to install it in the certificate store.
    # Use the appropriate copy command for your device OS or if using EFLOW.
    
    # For Ubuntu and Debian, use /usr/local/share/ca-certificates/
    sudo cp azure-iot-test-only.root.ca.cert.pem /usr/local/share/azure-iot-test-only.root.ca.cert.pem.crt
    # For EFLOW, use /etc/pki/ca-trust/source/anchors/
    sudo cp azure-iot-test-only.root.ca.cert.pem /etc/pki/ca-trust/source/anchors/azure-iot-test-only.root.ca.pem.crt
    
  4. 更改证书和密钥的所有权和权限。

    # Give aziotcs ownership to certificates
    # Read and write for aziotcs, read-only for others
    sudo chown -R aziotcs:aziotcs /var/aziot/certs
    sudo find /var/aziot/certs -type f -name "*.*" -exec chmod 644 {} \;
    
    # Give aziotks ownership to private keys
    # Read and write for aziotks, no permission for others
    sudo chown -R aziotks:aziotks /var/aziot/secrets
    sudo find /var/aziot/secrets -type f -name "*.*" -exec chmod 600 {} \;
    
    # Verify permissions of directories and files
    sudo ls -Rla /var/aziot
    

    包含正确所有权和权限的列表输出如下所示:

    azureUser@vm:/var/aziot$ sudo ls -Rla /var/aziot
    /var/aziot:
    total 16
    drwxr-xr-x  4 root    root    4096 Dec 14 00:16 .
    drwxr-xr-x 15 root    root    4096 Dec 14 00:15 ..
    drwxr-xr-x  2 aziotcs aziotcs 4096 Jan 14 00:31 certs
    drwx------ 2 aziotks aziotks 4096 Jan 23 17:23 secrets
    
    /var/aziot/certs:
    total 20
    drwxr-xr-x 2 aziotcs aziotcs 4096 Jan 14 00:31 .
    drwxr-xr-x 4 root    root    4096 Dec 14 00:16 ..
    -rw-r--r-- 1 aziotcs aziotcs 1984 Jan 14 00:24 azure-iot-test-only.root.ca.cert.pem
    -rw-r--r-- 1 aziotcs aziotcs 5887 Jan 14 00:27 iot-edge-device-ca-gateway-full-chain.cert.pem
    
    /var/aziot/secrets:
    total 16
    drwx------ 2 aziotks aziotks 4096 Jan 23 17:23 .
    drwxr-xr-x 4 root    root    4096 Dec 14 00:16 ..
    -rw------- 1 aziotks aziotks 3243 Jan 14 00:28 iot-edge-device-ca-gateway.key.pem
    
  5. 使用特定于平台的命令更新设备上的证书存储,在父IoT Edge设备上安装 root CA 证书

    # Update the certificate store
    
    # For Ubuntu or Debian - use update-ca-certificates
    sudo update-ca-certificates
    # For EFLOW or RHEL - use update-ca-trust
    sudo update-ca-trust
    

    有关在 EFLOW 中使用 update-ca-trust 的详细信息,请参阅 CBL-Mariner SSL CA 证书管理

该命令报告了已将一个证书添加到 /etc/ssl/certs

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.

更新父配置文件

设备上应已安装IoT Edge。 否则,请按照步骤手动配置单个 Linux IoT Edge 设备

  1. 验证父设备上是否存在 /etc/aziot/config.toml 配置文件。

    如果设备上不存在配置文件,请使用以下命令基于模板文件创建该文件:

    sudo cp /etc/aziot/config.toml.edge.template /etc/aziot/config.toml
    

    还可以使用模板文件作为参考,添加本部分中的配置参数。

  2. 使用编辑器打开IoT Edge配置文件。 例如,使用 nano 编辑器打开 /etc/aziot/config.toml 文件。

    sudo nano /etc/aziot/config.toml
    
  3. 查找 hostname 参数,或将其添加到配置文件的开头。 将值更新为完全限定的域名(FQDN)或IoT Edge父设备的 IP 地址。 例如:

    hostname = "10.0.0.4"
    

    要实现网关发现功能,每个 IoT Edge 网关(父)设备都需要指定一个 hostname 参数,以便其子设备在本地网络中找到它。 每个下游IoT Edge设备都需要指定parent_hostname参数来标识其父级。 在单个IoT Edge设备既是父设备又是子设备的分层方案中,它需要这两个参数。

    hostname 和 trust_bundle_cert 参数必须位于配置文件的开头,位于所有部分之前。 在定义的部分之前添加参数,确保正确应用参数。

    使用少于 64 个字符的 hostname,这是服务器证书公用名称的字符限制。

    与网关层次结构中的 hostname 模式保持一致。 请使用 FQDN 或 IP 地址,但不能同时使用这二者。 连接下游设备需要 FQDN 或 IP 地址。

    在创建 edgeHub 容器之前设置主机名。 如果 edgeHub 正在运行,则在重新创建容器之前,更改配置文件中的主机名不会生效。 有关如何验证主机名是否已应用的详细信息,请参阅验证父配置部分。

  4. 查找“信任捆绑包证书”参数,或将其添加到配置文件的开头。

    trust_bundle_cert 参数更新为设备上根 CA 证书的文件 URI。 例如:

    trust_bundle_cert = "file:///var/aziot/certs/azure-iot-test-only.root.ca.cert.pem"
    
  5. 在配置文件中找到或添加“Edge CA certificate”部分。 使用父IoT Edge设备上的全链证书和密钥文件的文件 URI 路径更新证书cert和私钥pk 参数。 IoT Edge要求证书和私钥采用基于文本的隐私增强邮件(PEM)格式。 例如:

    [edge_ca]
    cert = "file:///var/aziot/certs/iot-edge-device-ca-gateway-full-chain.cert.pem"
    pk = "file:///var/aziot/secrets/iot-edge-device-ca-gateway.key.pem"
    
  6. 验证IoT Edge设备在启动时使用IoT Edge代理的正确版本。 找到 Default Edge Agent 部分,并将IoT Edge映像值设置为版本 1.5。 例如:

    [agent]
    name = "edgeAgent"
    type = "docker"
    
    [agent.config]
    image = "mcr.microsoft.com/azureiotedge-agent:1.5"
    
  7. 父配置文件的开头应类似于以下示例。

    hostname = "10.0.0.4"
    trust_bundle_cert = "file:///var/aziot/certs/azure-iot-test-only.root.ca.cert.pem"
    
    [edge_ca]
    cert = "file:///var/aziot/certs/iot-edge-device-ca-gateway-full-chain.cert.pem"
    pk = "file:///var/aziot/secrets/iot-edge-device-ca-gateway.key.pem"
    
  8. 保存并关闭 config.toml 配置文件。 例如,如果使用 nano 编辑器,请选择 Ctrl+O“写出”、Enter 和 Ctrl+X“退出”。

  9. 如果之前已将任何其他证书用于IoT Edge,请删除以下两个目录中的文件,以确保应用新证书:

    • /var/lib/aziot/certd/certs
    • /var/lib/aziot/keyd/keys
  10. 单击“应用”以应用更改。

    sudo iotedge config apply
    
  11. 检查配置中是否有任何错误。

    sudo iotedge check --verbose
    

    注意事项

    在新预配的设备上,你可能会看到与IoT Edge中心相关的错误:

    ×生产准备状态:边缘集线器的storage目录保存在主机文件系统上 - 错误

    无法检查 edgeHub 容器的当前状态

    新预配的设备上会出现此错误,因为IoT Edge中心模块未运行。 若要解决此错误,请在IoT Hub中设置设备的模块并创建部署。 为设备创建部署会启动设备上的模块,包括IoT Edge Hub模块。

验证父配置

hostname必须是限定域名(FQDN)或IoT Edge设备的 IP 地址,因为下游设备连接时IoT Edge在服务器证书中使用此值。 这些值必须匹配,否则会收到“IP 地址不匹配”错误。

若要验证主机名,需要检查 edgeHub 容器的环境变量。

  1. 列出正在运行的IoT Edge容器。

    iotedge list
    

    验证 edgeAgent 和 edgeHub 容器是否正在运行。 命令的输出应如以下示例所示。

    NAME                        STATUS           DESCRIPTION      CONFIG
    SimulatedTemperatureSensor  running          Up 5 seconds     mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0
    edgeAgent                   running          Up 17 seconds    mcr.microsoft.com/azureiotedge-agent:1.5
    edgeHub                     running          Up 6 seconds     mcr.microsoft.com/azureiotedge-hub:1.5
    
  2. 检查 edgeHub 容器。

    sudo docker inspect edgeHub
    
  3. 在输出中的 Env 部分找到 EdgeDeviceHostName 参数。

    "EdgeDeviceHostName=10.0.0.4"
    
  4. 验证 EdgeDeviceHostName 参数值是否与 主机名设置匹配。config.toml 如果配置不匹配,那么在您修改并应用配置时,edgeHub 容器正在运行。 若要更新 EdgeDeviceHostName,先删除 edgeAgent 容器。

    sudo docker rm -f edgeAgent
    

    EdgeAgent 和 edgeHub 容器将在几分钟内重新创建和启动。 EdgeHub 容器开始运行后,检查容器并验证 EdgeDeviceHostName 参数与配置文件是否匹配。

配置下游设备

要配置设备,请打开本地或远程命令行。

若要启用安全连接,网关方案中的每个IoT Edge下游设备都需要使用唯一的 Edge CA 证书和网关层次结构中所有设备共享的根 CA 证书的副本进行配置。

  1. 检查你的证书是否符合格式要求

  2. 将根 CA 证书、子 Edge CA 证书和子设备私钥传输到下游设备

  3. 将证书和密钥复制到正确的目录。 对于设备证书,首选目录为 /var/aziot/certs;对于密钥,首选目录为 /var/aziot/secrets

    ### Copy device certificate ###
    
    # If the device certificate and keys directories don't exist, create, set ownership, and set permissions
    sudo mkdir -p /var/aziot/certs
    sudo chown aziotcs:aziotcs /var/aziot/certs
    sudo chmod 755 /var/aziot/certs
    
    sudo mkdir -p /var/aziot/secrets
    sudo chown aziotks:aziotks /var/aziot/secrets
    sudo chmod 700 /var/aziot/secrets
    
    # Copy device full-chain certificate and private key into the correct directory
    sudo cp iot-device-downstream-full-chain.cert.pem /var/aziot/certs
    sudo cp iot-device-downstream.key.pem /var/aziot/secrets
    
    ### Root certificate ###
    
    # Copy root certificate into the /certs directory
    sudo cp azure-iot-test-only.root.ca.cert.pem /var/aziot/certs
    
    # Copy root certificate into the CA certificate directory and add .crt extension.
    # The root certificate must be in the CA certificate directory to install it in the certificate store.
    # Use the appropriate copy command for your device OS or if using EFLOW.
    
    # For Ubuntu and Debian, use /usr/local/share/ca-certificates/
    sudo cp azure-iot-test-only.root.ca.cert.pem /usr/local/share/azure-iot-test-only.root.ca.cert.pem.crt
    # For EFLOW, use /etc/pki/ca-trust/source/anchors/
    sudo cp azure-iot-test-only.root.ca.cert.pem /etc/pki/ca-trust/source/anchors/azure-iot-test-only.root.ca.pem.crt
    
  4. 更改证书和密钥的所有权和权限。

    # Give aziotcs ownership to certificates
    # Read and write for aziotcs, read-only for others
    sudo chown -R aziotcs:aziotcs /var/aziot/certs
    sudo find /var/aziot/certs -type f -name "*.*" -exec chmod 644 {} \;
    
    # Give aziotks ownership to private keys
    # Read and write for aziotks, no permission for others
    sudo chown -R aziotks:aziotks /var/aziot/secrets
    sudo find /var/aziot/secrets -type f -name "*.*" -exec chmod 600 {} \;
    
  5. 使用特定于平台的命令更新设备上的证书存储,在下游IoT Edge设备上安装 root CA 证书

    # Update the certificate store
    
    # For Ubuntu or Debian - use update-ca-certificates
    sudo update-ca-certificates
    # For EFLOW or RHEL - use update-ca-trust
    sudo update-ca-trust
    

    有关在 EFLOW 中使用 update-ca-trust 的详细信息,请参阅 CBL-Mariner SSL CA 证书管理

该命令报告了已将一个证书添加到 /etc/ssl/certs

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.

更新下游配置文件

设备上应已安装IoT Edge。 否则,请按照步骤手动配置单个 Linux IoT Edge 设备

  1. 验证下游设备上是否存在 /etc/aziot/config.toml 配置文件。

    如果设备上不存在配置文件,请使用以下命令基于模板文件创建该文件:

    sudo cp /etc/aziot/config.toml.edge.template /etc/aziot/config.toml
    

    还可以使用模板文件作为参考,添加本部分中的配置参数。

  2. 使用编辑器打开IoT Edge配置文件。 例如,使用 nano 编辑器打开 /etc/aziot/config.toml 文件。

    sudo nano /etc/aziot/config.toml
    
  3. 找到 parent_hostname 参数或将其添加到配置文件的开头,每个下游IoT Edge设备都需要指定 parent_hostname 参数来标识其父级。 将 parent_hostname 参数更新为父设备的 FQDN 或 IP 地址,使之与父设备的配置文件中作为主机名提供的内容匹配。 例如:

    parent_hostname = "10.0.0.4"
    
  4. 查找“信任捆绑包证书”参数,或将其添加到配置文件的开头。

    trust_bundle_cert 参数更新为设备上根 CA 证书的文件 URI。 例如:

    trust_bundle_cert = "file:///var/aziot/certs/azure-iot-test-only.root.ca.cert.pem"
    
  5. 在配置文件中找到或添加“Edge CA certificate”部分。 将IoT Edge下游设备上的完整链证书文件和密钥文件的文件URI路径用于更新证书cert和私钥pk参数。 IoT Edge要求证书和私钥采用基于文本的隐私增强邮件(PEM)格式。 例如:

    [edge_ca]
    cert = "file:///var/aziot/certs/iot-device-downstream-full-chain.cert.pem"
    pk = "file:///var/aziot/secrets/iot-device-downstream.key.pem"
    
  6. 验证IoT Edge设备在启动时使用IoT Edge代理的正确版本。 找到 Default Edge Agent 部分,并将IoT Edge映像值设置为版本 1.5。 例如:

    [agent]
    name = "edgeAgent"
    type = "docker"
    
    [agent.config]
    image = "mcr.microsoft.com/azureiotedge-agent:1.5"
    
  7. 下游配置文件的开头应类似于以下示例所示。

    parent_hostname = "10.0.0.4"
    trust_bundle_cert = "file:///var/aziot/certs/azure-iot-test-only.root.ca.cert.pem"
    
    [edge_ca]
    cert = "file:///var/aziot/certs/iot-device-downstream-full-chain.cert.pem"
    pk = "file:///var/aziot/secrets/iot-device-downstream.key.pem"
    
  8. 保存并关闭 config.toml 配置文件。 例如,如果使用 nano 编辑器,请选择 Ctrl+O“写出”、Enter 和 Ctrl+X“退出”。

  9. 如果之前已将任何其他证书用于IoT Edge,请删除以下两个目录中的文件,以确保应用新证书:

    • /var/lib/aziot/certd/certs
    • /var/lib/aziot/keyd/keys
  10. 单击“应用”以应用更改。

    sudo iotedge config apply
    
  11. 检查配置中是否有任何错误。

    sudo iotedge check --verbose
    

    提示

    IoT Edge检查工具使用容器执行某些诊断检查。 如果要在下游IoT Edge设备上使用此工具,请确保它们可以访问mcr.microsoft.com/azureiotedge-diagnostics:latest,或者在您的专用容器注册表中存有该容器映像。

    注意事项

    在新预配的设备上,你可能会看到与IoT Edge中心相关的错误:

    ×生产准备状态:边缘集线器的storage目录保存在主机文件系统上 - 错误

    无法检查 edgeHub 容器的当前状态

    新预配的设备上会出现此错误,因为IoT Edge中心模块未运行。 若要解决此错误,请在IoT Hub中设置设备的模块并创建部署。 为设备创建部署会启动设备上的模块,包括IoT Edge Hub模块。

对下游设备进行网络隔离

本文到目前为止的步骤将IoT Edge设备设置为网关或下游设备,并在它们之间创建受信任的连接。 网关设备处理下游设备和IoT Hub之间的交互,包括身份验证和消息路由。 部署到下游IoT Edge设备的模块仍可以创建与云服务的自己的连接。

某些网络体系结构(例如那些遵循 ISA-95 标准的网络体系结构)会尝试最大程度地减少 Internet 连接数。 在这些情况下,可以在没有直接 Internet 连接的情况下配置下游IoT Edge设备。 除了通过网关设备路由IoT Hub通信之外,下游IoT Edge设备可以依赖于网关设备进行所有云连接。

此网络配置要求只有网关层次结构顶层IoT Edge设备才能直接连接到云。 IoT Edge下层中的设备只能与其父设备或任何子设备通信。 网关设备上的特殊模块可启用此方案,这些模块包括:

  • API 代理模块是任何具有其他IoT Edge设备连接在其下的IoT Edge网关上所必需的。 这意味着,它必须位于网关层次结构的每个层(底层除外)。 此模块使用 nginx 反向代理在单个端口上通过网络层路由 HTTP 数据。 它的可配置性高(可以通过模块孪生和环境变量进行配置),因此可以根据网关方案要求对其进行调整。

  • Docker 注册表模块可以在网关层次结构的top 层IoT Edge网关上部署。 此模块负责代表较低层中的所有IoT Edge设备检索和缓存容器映像。 在顶层部署此模块的替代方法是使用本地注册表,或者手动将容器映像加载到设备上,并将模块拉取策略设置为 never。

  • Azure Blob Storage 在 IoT Edge 上可以部署在网关层次结构的顶部层 IoT Edge 网关上。 此模块负责代表底层中的所有IoT Edge 设备上传数据块。 上传 blob 的能力还可以为较低层 IoT Edge 设备提供有用的故障排除功能,例如模块日志上传和支持包上传。

网络配置

对于顶层的每个网关设备,网络操作员必须:

  • 提供静态 IP 地址或完全限定的域名 (FQDN)。

  • 通过端口 443(HTTPS)和 5671(AMQP)授权从此 IP 地址到 Azure IoT Hub 主机名的出站通信。

  • 通过端口 443(HTTPS)授权从此 IP 地址到Azure Container Registry主机名的出站通信。

    API 代理模块一次只能处理到一个容器注册表的连接。 我们建议将所有容器映像,包括 Microsoft 容器注册表 (mcr.microsoft.com) 提供的公共映像,存储在私有容器注册表中。

对于下层中的每个网关设备,网络操作员需要执行以下操作:

  • 提供静态 IP 地址。
  • 授权此 IP 地址通过端口443 (HTTPS) 和5671 (AMQP) 发起到父网关 IP 地址的出站通信。

将模块部署到顶层设备

网关层次结构的最高层的IoT Edge设备具有一组必需的模块,这些模块必须部署到该设备上,除在设备上可能运行的任何工作负载模块外。

API 代理模块经过设计,可以通过自定义来管理大多数常见的网关场景。 本文提供了一个以基本配置设置模块的示例。 有关更多详细信息和示例,请参阅 为网关层次结构方案配置 API 代理模块

  1. Azure portal 中,导航到IoT hub。

  2. Device management菜单中选择Devices

  3. 从列表中选择要配置的顶层IoT Edge设备。

  4. 选择“设置模块”。

  5. IoT Edge modules 部分中,选择 Add然后选择 IoT Edge Module

  6. 更新以下模块设置:

    设置 “值”
    IoT 模块名称 IoTEdgeAPIProxy
    映像 URI mcr.microsoft.com/azureiotedge-api-proxy:latest
    重启策略 总是
    所需状态 “正在运行”

    如果要使用 API 代理模块的不同版本或体系结构,请查找 Microsoft 工件注册表中的可用映像。

    1. 在“环境变量”选项卡中,添加一个名为 的“文本”NGINX_DEFAULT_PORT类型变量,其值为 443

    2. 在“容器创建选项”选项卡中,将端口绑定更新为引用端口 443。

      {
        "HostConfig": {
          "PortBindings": {
            "443/tcp": [
              {
                "HostPort": "443"
              }
            ]
          }
        }
      }
      

    这些更改将 API 代理模块配置为在端口 443 上进行侦听。 若要防止端口绑定冲突,需要将 edgeHub 模块配置为不在端口 443 上进行侦听。 相反,API 代理模块会在端口 443 上路由任何 edgeHub 流量。

  7. 选择“添加”,将模块添加到部署中。

  8. 选择“运行时设置”并查找 edgeHub 模块“容器创建选项”。 删除端口 443 的端口绑定,保留端口 5671 和 8883 的绑定。

    {
      "HostConfig": {
        "PortBindings": {
          "5671/tcp": [
            {
              "HostPort": "5671"
            }
          ],
          "8883/tcp": [
            {
              "HostPort": "8883"
            }
          ]
        }
      }
    }
    
  9. 选择“应用”,将更改保存到运行时设置

  10. 提供以下值,以便将 Docker 注册表模块添加到你的部署。

    1. IoT Edge modules 部分中,选择 Add然后选择 IoT Edge Module

      设置 “值”
      IoT 模块名称 registry
      映像 URI registry:latest
      重启策略 always
      所需状态 running
    2. 在“环境变量”选项卡中,添加以下变量:

      名称 类型 “值”
      REGISTRY_PROXY_REMOTEURL 文本 希望此注册表模块映射到的容器注册表的 URL。 例如 https://myregistry.azurecr。 注册表模块只能映射到一个容器注册表,因此,建议将所有容器映像置于单个专用容器注册表中。
      REGISTRY_PROXY_USERNAME 文本 用于向容器注册表进行身份验证的用户名。
      REGISTRY_PROXY_PASSWORD 文本 用于向容器注册表进行身份验证的密码。
    3. 在“容器创建选项”选项卡中,将端口绑定更新为引用端口 5000。

    {
      "HostConfig": {
        "PortBindings": {
          "5000/tcp": [
            {
              "HostPort": "5000"
            }
          ]
        }
      }
    }
    
  11. 选择“添加”,将模块添加到部署中。

  12. 选择“下一步:路由”以转到下一步。

  13. 若要使来自下游设备的设备到云消息能够到达IoT Hub,请包括将所有消息传递到IoT Hub的路由。 例如:

    1. 名称Route
    2. FROM /messages/* INTO $upstream
  14. 选择“查看 + 创建”,转到最后一步。

  15. 选择“创建”以部署到设备。

将模块部署到下层设备

IoT Edge网关层级较低层的设备必须部署一个必需的模块,除此之外,你还可以在设备上运行和部署任何工作负载模块。

路由容器映像拉取

在讨论网关层次结构中IoT Edge设备所需的代理模块之前,请务必了解较低层中的IoT Edge设备如何获取其模块映像。

如果下层设备无法连接到云,但你希望它们照常拉取模块映像,则必须将网关层次结构的顶层设备配置为处理这些请求。 顶层设备需要运行一个映射到容器注册表的 Docker 注册表模块。 然后,配置 API 代理模块,以便将容器请求路由到该模块。 本文前面的部分已讨论这些详细信息。 在此配置中,下层设备不应指向云容器注册表,而应指向在顶层运行的注册表。

例如,下层设备应调用 mcr.microsoft.com/azureiotedge-api-proxy:1.1,而不应调用 $upstream:443/azureiotedge-api-proxy:1.1

$upstream参数指向下层设备的父级,因此请求将路由到所有层,直到到达具有代理环境路由容器请求到注册表模块的顶层为止。 此示例中的 :443 端口应替换为父设备上的 API 代理模块正在侦听的端口。

API 代理模块只能路由到一个注册表模块,每个注册表模块只能映射到一个容器注册表。 因此,下层设备需要拉取的任何映像都必须存储在单个容器注册表中。

如果不希望较低层设备通过网关层次结构发出模块拉取请求,另一个选项是管理本地注册表解决方案。 也可在创建部署之前将模块映像推送到设备上,然后将 imagePullPolicy 设置为 never。

启动IoT Edge代理

IoT Edge代理是在任何IoT Edge设备上启动的第一个运行时组件。 需要确保任何下游的 IoT Edge 设备在启动时都可以访问 edgeAgent 模块映像,然后它们可以访问部署并启动其余的模块映像。

更新IoT Edge设备上的配置文件以提供其身份验证信息、证书和父主机名时,还会更新 edgeAgent 容器映像。

如果顶级网关设备配置为处理容器映像请求,请将 mcr.microsoft.com 替换为父主机名和 API 代理侦听端口。 在部署清单中,可以将 $upstream 用作快捷方式,但这需要 edgeHub 模块来处理路由,而该模块此时尚未启动。 例如:

[agent]
name = "edgeAgent"
type = "docker"

[agent.config]
image = "{Parent FQDN or IP}:443/azureiotedge-agent:1.5"

如果使用本地容器注册表,或在设备上手动提供容器映像,请相应地更新配置文件。

配置运行时和部署代理模块

API 代理模块是路由云与任何下游IoT Edge设备之间所有通信所必需的。 层次结构底层的IoT Edge设备(没有下游IoT Edge设备)不需要此模块。

API 代理模块经过设计,可以通过自定义来管理大多数常见的网关场景。 本文简要介绍了以基本配置设置模块的步骤。 有关详细信息和示例,请参阅配置适用于网关层次结构方案的 API 代理模块

  1. Azure portal 中,导航到IoT hub。

  2. Device management菜单中选择Devices

  3. 从列表中选择要配置的下层IoT Edge设备。

  4. 选择“设置模块”。

  5. IoT Edge modules 部分中,选择 Add然后选择 IoT Edge Module

  6. 更新以下模块设置:

    设置 “值”
    IoT 模块名称 IoTEdgeAPIProxy
    映像 URI mcr.microsoft.com/azureiotedge-api-proxy:latest
    重启策略 always
    所需状态 running

    如果要使用 API 代理模块的不同版本或体系结构,请查找 Microsoft 工件注册表中的可用映像。

    1. 在“环境变量”选项卡中,添加一个名为 的“文本”NGINX_DEFAULT_PORT类型变量,其值为 443

    2. 在“容器创建选项”选项卡中,将端口绑定更新为引用端口 443。

      {
        "HostConfig": {
          "PortBindings": {
            "443/tcp": [
              {
                "HostPort": "443"
              }
            ]
          }
        }
      }
      

    这些更改将 API 代理模块配置为在端口 443 上进行侦听。 若要防止端口绑定冲突,需要将 edgeHub 模块配置为不在端口 443 上进行侦听。 相反,API 代理模块会在端口 443 上路由任何 edgeHub 流量。

  7. 选择“运行时设置”。

  8. 更新 edgeHub 模块设置:

    1. 在“映像”字段中,将 替换为 mcr.microsoft.com
    2. 在“创建选项”字段中,删除端口 443 的端口绑定,保留端口 5671 和 8883 的绑定。
    {
      "HostConfig": {
        "PortBindings": {
          "5671/tcp": [
            {
              "HostPort": "5671"
            }
          ],
          "8883/tcp": [
            {
              "HostPort": "8883"
            }
          ]
        }
      }
    }
    
  9. 更新 edgeAgent 模块设置:

    1. 在“映像”字段中,将 替换为 mcr.microsoft.com
  10. 选择“应用”,将更改保存到运行时设置

  11. 选择“下一步:路由”以转到下一步。

  12. 若要启用来自下游设备的设备到云消息以达到IoT Hub,请包括将所有消息传递到 $upstream 的路由。 在下层设备的情况下,upstream 参数指向父设备。 例如:

    1. 名称Route
    2. FROM /messages/* INTO $upstream
  13. 选择“查看 + 创建”,转到最后一步。

  14. 选择“创建”以部署到设备。

验证从子级到父级的连接

  1. 通过在下游设备上运行以下 openssl 命令,验证从子级到父级的 TLS/SSL 连接。 将 <parent hostname> 替换为父节点的 FQDN 或 IP 地址。

    openssl s_client -connect <parent hostname>:8883 </dev/null 2>&1 >/dev/null
    

    该命令应断言父证书链验证成功,类似于以下示例:

    azureUser@child-vm:~$ openssl s_client -connect <parent hostname>:8883 </dev/null 2>&1 >/dev/null
    Can't use SSL_get_servername
    depth=3 CN = Azure_IoT_Hub_CA_Cert_Test_Only
    verify return:1
    depth=2 CN = Azure_IoT_Hub_Intermediate_Cert_Test_Only
    verify return:1
    depth=1 CN = gateway.ca
    verify return:1
    depth=0 CN = <parent hostname>
    verify return:1
    DONE
    

    可以忽略“无法使用 SSL_get_servername”消息。

    depth=0 CN = 值应与父级 配置文件中指定的 hostname 参数匹配。

    如果命令超时,则可能是子设备和父设备之间的端口被阻塞。 请查看设备的网络配置和设置。

    警告

    不在网关的 [edge_ca] 部分中使用全链证书会导致下游设备出现证书验证错误。 例如, openssl s_client ... 上述命令生成:

    Can't use SSL_get_servername
    depth=1 CN = gateway.ca
    verify error:num=20:unable to get local issuer certificate
    verify return:1
    depth=0 CN = <parent hostname>
    verify return:1
    DONE
    

    如果未在下游设备上使用和配置全链设备证书,则连接到下游IoT Edge设备的启用了 TLS 的设备也会出现相同的问题。

将Microsoft Defender for IoT与 IoT Edge 网关集成

下游设备可用于使用下游设备代理将Microsoft Defender for IoT的微代理与IoT Edge网关集成。

若要使用下游设备代理将Microsoft Defender for IoT与IoT Edge集成

  1. 登录到Azure portal。

  2. 转到 IoT Hub>Your Hub>Device management>Devices

  3. 选择你的设备。

    显示设备所在位置以供选择的屏幕截图。

  4. 选择创建的 DefenderIotMicroAgent 模块孪生。

    显示 DefenderIotMicroAgent 位置的屏幕截图。

  5. 选择 按钮以复制Connection string(主密钥)。

  6. 将connection string粘贴到文本编辑应用程序中,并将 GatewayHostName 添加到字符串。 GatewayHostName 是父设备的完全限定域名或 IP 地址。 例如 HostName=nested11.azure-devices.cn;DeviceId=downstream1;ModuleId=module1;SharedAccessKey=xxx;GatewayHostName=10.16.7.4

  7. 在下游设备上打开终端。

  8. 使用以下命令可将以 utf-8 编码的连接字符串置于 Defender for Cloud 代理目录中的以下路径中的文件 connection_string.txt/etc/defender_iot_micro_agent/connection_string.txt

    sudo bash -c 'echo "<connection string>" > /etc/defender_iot_micro_agent/connection_string.txt'
    

    connection_string.txt 现应在路径位置 /etc/defender_iot_micro_agent/connection_string.txt 中。

  9. 通过运行以下命令重启服务:

    sudo systemctl restart defender-iot-micro-agent.service 
    
  10. 返回设备。

    显示如何导航回设备的屏幕截图。

  11. 启用与IoT Hub的连接,然后选择齿轮图标。

    屏幕截图显示了如何选择以设置父设备。

  12. 从显示的列表中选择父设备。

  13. 确保下游设备与IoT Edge设备之间的端口 8883(MQTT)处于打开状态。

后续步骤

如何将IoT Edge设备用作网关

配置适用于网关层次结构方案的 API 代理模块