你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本教程介绍如何使用分配策略将多个模拟对称密钥设备安全地预配到一组 IoT 中心。 IoT 中心设备预配服务 (DPS) 通过其内置的分配策略和其对自定义分配策略的支持,支持各种分配方案。
为 地理位置/地理位置延迟 预配是一种常见的分配方案。 当设备在两位置之间移动时,可通过将设备预配到距离每个位置最近的 IoT 中心来改善网络延迟。 在此方案中,为注册选择跨越区域的一组 IoT 中心。 为这些注册选择内置的“最低延迟”分配策略。 此策略会使设备预配服务评估设备延迟,并从一组 IoT 中心确定最接近的 IoT 中心。
本教程使用 Azure IoT C SDK 中的模拟设备示例来演示如何跨区域预配设备。 在本教程中执行以下步骤:
- 使用 Azure CLI 创建两个区域 IoT 中心(美国西部 2 和美国东部)
- 创建基于地理位置预配设备的注册(最低延迟)
- 使用 Azure CLI 创建两个区域 Linux VM,以充当同一区域中的设备(美国西部 2 和美国东部)
- 在这两个 Linux VM 上为 Azure IoT C SDK 设置开发环境
- 模拟设备并验证它们是否已预配到最近区域中的 IoT 中心。
重要说明
某些区域可能会不时地强制限制虚拟机的创建。 在编写本指南时,westus2(美国西部 2)和 eastus(美国东部)区域允许创建 VM。 如果无法在其中一个区域创建 VM,可以尝试在其他区域中创建。 若要了解有关在创建 VM 时选择 Azure 地理区域的详细信息,请参阅 Azure 中虚拟机的区域
Prerequisites
如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
完成快速入门中的步骤 :使用 Azure 门户设置 IoT 中心设备预配服务。
在 Azure Cloud Shell 中使用 Bash 环境。 有关详细信息,请参阅 Azure Cloud Shell 入门。
如果要在本地运行 CLI 引用命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI。
如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅 使用 Azure CLI 向 Azure 进行身份验证。
如果系统发出提示,则在首次使用时安装 Azure CLI 扩展。 有关扩展的详细信息,请参阅 使用和管理 Azure CLI 中的扩展。
运行 az version 以查找所安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade。
创建两个区域 IoT 中心
在本部分中,将创建一个 Azure 资源组和两个新的区域 IoT 中心资源。 一个 IoT 中心适用于 美国西部 2 区域,另一个中心用于 美国东部 区域。
重要说明
建议对本教程中创建的所有资源使用相同的资源组。 使用同一个资源组可以让你在完成任务后更容易清理。
在 Azure Cloud Shell 中,使用以下 az group create 命令创建资源组:
az group create --name contoso-us-resource-group --location eastus在 eastus 位置创建 IoT 中心,并将其添加到使用以下 az iot hub create 命令创建的资源组(替换为
{unique-hub-name}自己的唯一名称):az iot hub create --name {unique-hub-name} --resource-group contoso-us-resource-group --location eastus --sku S1该命令可能需要几分钟时间才能完成。
现在,在 westus2 位置创建一个 IoT 中心,并将其添加到之前使用以下 az iot hub create 命令创建的资源组(将
{unique-hub-name}替换为自己的唯一名称):az iot hub create --name {unique-hub-name} --resource-group contoso-us-resource-group --location westus2 --sku S1该命令可能需要几分钟时间才能完成。
为地理延迟创建注册
在本部分中,您将为设备创建新的注册组。
为简单起见,本教程对注册使用 对称密钥证明 。 对于更安全的解决方案,请考虑使用具有信任链的 X.509 证书证明。
登录到 Azure 门户,并导航到设备预配服务实例。
从导航菜单的“设置”部分选择“管理注册”。
选择“添加注册组”。
在“添加注册组”页的“注册 + 预配”选项卡上,提供以下信息以配置注册组详细信息:
字段 说明 证明 选择“对称密钥”作为证明类型。 对称密钥设置 选中“自动生成对称密钥”复选框。 组名 将组命名为 contoso-us-devices,或提供你自己的组名称。 注册组名称是一个不区分大小写的字符串(最大长度为 128 个字符),包含字母数字字符和以下特殊字符: '-'、'.'、'_'、':'。 最后一个字符必须是字母数字或短划线 ('-')。选择“下一步:IoT 中心”。
使用以下步骤将两个 IoT 中心添加到注册组:
在“添加注册组”页的“IoT 中心”选项卡上,在“目标 IoT 中心”部分选择“添加 IoT 中心链接”。
在“添加 IoT 中心链接”页上,选择在 eastus 区域中创建的 IoT 中心,并为其分配 iothubowner 访问权限。
选择“保存”。
再次选择“添加 IoT 中心链接”,并按照相同的步骤添加在 westus2 区域中创建的 IoT 中心。
在“目标 IoT 中心”下拉菜单中,选择这两个 IoT 中心。
对于“分配策略”,请选择“最低延迟”。
选择“查看 + 创建”。
在“审阅 + 创建”选项卡上,验证你的全部值,然后选择“创建”。
创建注册组后,从注册组列表中选择其名称 contoso-us-devices。
复制“主密钥”。 稍后使用此密钥为这两个模拟设备生成唯一的设备密钥。
创建区域 Linux VM
在此部分中,你将创建两个区域性 Linux 虚拟机 (VM),一个位于美国西部 2,一个位于美国东部 2。 这些 VM 将从每个区域运行设备模拟示例,以演示这两个区域中针对设备的设备预配。
为了更轻松地清理资源,请将这些 VM 添加到包含创建的 IoT 中心的同一资源组 contoso-us-resource-group。
在 Azure Cloud Shell 中,在命令中更改以下参数后,运行该命令以创建美国东部区域 VM:
--name:为美国东部区域设备 VM 输入一个唯一名称。
--admin-username:使用你自己的管理员用户名称。
--admin-password:使用你自己的管理员密码。
az vm create \ --resource-group contoso-us-resource-group \ --name ContosoSimDeviceEast \ --location eastus \ --image Canonical:UbuntuServer:18.04-LTS:18.04.201809110 \ --admin-username contosoadmin \ --admin-password myContosoPassword2018 \ --authentication-type password --public-ip-sku Standard此命令需要几分钟才能完成。
命令完成后,复制美国东部区域 VM 的 publicIpAddress 值。
在 Azure Cloud Shell 中,在命令中更改以下参数后,运行该命令以创建美国西部 2 区域 VM:
--name:为美国西部 2 区域设备 VM 输入一个唯一名称。
--admin-username:使用你自己的管理员用户名称。
--admin-password:使用你自己的管理员密码。
az vm create \ --resource-group contoso-us-resource-group \ --name ContosoSimDeviceWest2 \ --location westus2 \ --image Canonical:UbuntuServer:18.04-LTS:18.04.201809110 \ --admin-username contosoadmin \ --admin-password myContosoPassword2018 \ --authentication-type password --public-ip-sku Standard此命令需要几分钟才能完成。
命令完成后,复制美国西部 2 区域 VM 的 publicIpAddress 值。
打开两个命令行 shell。
使用 SSH 连接到每个 shell 中的其中一个区域 VM。
将你作为参数复制的管理员用户名和公共 IP 地址传递给 SSH。 在出现提示时输入管理员密码。
ssh contosoadmin@1.2.3.4 contosoadmin@ContosoSimDeviceEast:~$ssh contosoadmin@5.6.7.8 contosoadmin@ContosoSimDeviceWest:~$
准备 Azure IoT C SDK 开发环境
在本部分中,将在每个 VM 上克隆 Azure IoT C SDK。 SDK 包含将从每个区域模拟设备预配的示例。
对于每个 VM:
,使用以下命令安装 CMake 、g++ 、gcc 和 Git:
sudo apt-get update sudo apt-get install cmake build-essential libssl-dev libcurl4-openssl-dev uuid-dev git-all找到并复制最新版 SDK 的标记名称。
在两个虚拟机上克隆 Azure IoT Device SDK for C。 将在上一步中找到的标记用作
-b参数的值,例如:lts_03_2025。git clone -b <release-tag> https://github.com/Azure/azure-iot-sdk-c.git cd azure-iot-sdk-c git submodule update --init应该预料到此操作需要几分钟才能完成。
在存储库内创建一个新的 cmake 文件夹,并更改为该文件夹。
mkdir ~/azure-iot-sdk-c/cmake cd ~/azure-iot-sdk-c/cmake运行以下命令,生成特定于你的开发客户端平台的 SDK 版本:
cmake -Dhsm_type_symm_key:BOOL=ON -Duse_prov_client:BOOL=ON ..生成成功后,最后的几个输出行如下所示:
-- IoT Client SDK Version = 1.7.0 -- Provisioning SDK Version = 1.7.0 -- Looking for include file stdint.h -- Looking for include file stdint.h - found -- Looking for include file stdbool.h -- Looking for include file stdbool.h - found -- target architecture: x86_64 -- Performing Test CXX_FLAG_CXX11 -- Performing Test CXX_FLAG_CXX11 - Success -- Found OpenSSL: /usr/lib/x86_64-linux-gnu/libcrypto.so (found version "1.1.1") -- Found CURL: /usr/lib/x86_64-linux-gnu/libcurl.so (found version "7.58.0") -- Found CURL: /usr/lib/x86_64-linux-gnu/libcurl.so -- target architecture: x86_64 -- iothub architecture: x86_64 -- Configuring done -- Generating done -- Build files have been written to: /home/contosoadmin/azure-iot-sdk-c/azure-iot-sdk-c
派生唯一设备密钥
在组注册中使用对称密钥证明时,不会直接使用注册组密钥。 而是你自己从每个设备的注册组密钥派生唯一密钥。
在本教程的这一部分中,你将从您的组主密钥生成一个设备密钥,以计算设备唯一注册 ID 的 HMAC-SHA256。 然后,结果将转换为 Base64 格式。
重要说明
不要在设备代码中包含你的组主键。
对于eastus 和 westus2 设备:
使用 openssl 生成唯一密钥。 可使用以下 Bash shell 脚本(将
{primary-key}替换为之前复制的注册组的主键,并将{contoso-simdevice}替换为你自己的每个设备的唯一注册 ID。 注册 ID 是一个不区分大小写的字符串(最大长度为 128 个字符),包含字母数字字符和以下特殊字符:'-'、'.'、'_'、':'。 最后一个字符必须是字母数字或短划线 ('-')。KEY={primary-key} REG_ID={contoso-simdevice} keybytes=$(echo $KEY | base64 --decode | xxd -p -u -c 1000) echo -n $REG_ID | openssl sha256 -mac HMAC -macopt hexkey:$keybytes -binary | base64该脚本输出类似于以下密钥的内容:
p3w2DQr9WqEGBLUSlFi1jPQ7UWQL4siAGy75HFTFbf8=现在,每个设备都有自己的派生设备密钥和唯一的注册 ID,以便在预配过程中使用注册组执行对称密钥证明。
模拟来自每个区域的设备
在本部分中,将为这两个区域 VM 更新 Azure IoT C SDK 中的预配示例。
示例代码模拟将预配请求发送到你的设备预配服务实例的设备启动序列。 启动序列会使设备被识别,并分配给基于延迟的最近的物联网(IoT)中心。
在 Azure 门户中,选择设备预配服务的“概述”选项卡,记下“ID 范围”的值。
在两个 VM 上,都打开 ~/azure-iot-sdk-c/provisioning_client/samples/prov_dev_client_sample/prov_dev_client_sample.c 进行编辑。
vi ~/azure-iot-sdk-c/provisioning_client/samples/prov_dev_client_sample/prov_dev_client_sample.c在两个 VM 上,找到
id_scope常量,将值替换为前面复制的“ID 范围”值。static const char* id_scope = "0ne00002193";在两个 VM 上,在同一文件中找到
main()函数的定义。 确保变量hsm_type设置为SECURE_DEVICE_TYPE_SYMMETRIC_KEY如下代码示例所示,以匹配注册组证明方法。将你对文件的更改保存在这两个 VM 上。
SECURE_DEVICE_TYPE hsm_type; //hsm_type = SECURE_DEVICE_TYPE_TPM; //hsm_type = SECURE_DEVICE_TYPE_X509; hsm_type = SECURE_DEVICE_TYPE_SYMMETRIC_KEY;在两个 VM 上,都在 prov_dev_client_sample.c 中找到已注释掉的对
prov_dev_set_symmetric_key_info()的调用。// Set the symmetric key if using they auth type //prov_dev_set_symmetric_key_info("<symm_registration_id>", "<symmetric_Key>");取消注释这些函数调用,并将占位符值(包括尖括号)替换为每个设备的唯一注册 ID 以及在上一节中派生的设备的派生设备密钥。 以下函数调用中显示的键是示例。 请使用你之前生成的密钥。
美国东部:
// Set the symmetric key if using they auth type prov_dev_set_symmetric_key_info("contoso-simdevice-east", "p3w2DQr9WqEGBLUSlFi1jPQ7UWQL4siAGy75HFTFbf8=");美国西部:
// Set the symmetric key if using they auth type prov_dev_set_symmetric_key_info("contoso-simdevice-west", "J5n4NY2GiBYy7Mp4lDDa5CbEe6zDU/c62rhjCuFWxnc=");在这两个 VM 上,保存文件。
在这两个 VM 上,导航到以下 Bash 脚本中显示的示例文件夹,并生成示例。
cd ~/azure-iot-sdk-c/cmake/provisioning_client/samples/prov_dev_client_sample/ cmake --build . --target prov_dev_client_sample --config Debug在成功生成后,在这两个 VM 上都运行 prov_dev_client_sample.exe,以模拟来自每个区域的设备。 请注意,每个设备将被分配到最邻近模拟设备区域的 IoT 中心。
运行模拟:
~/azure-iot-sdk-c/cmake/provisioning_client/samples/prov_dev_client_sample/prov_dev_client_sample来自美国东部 VM 的示例输出:
contosoadmin@ContosoSimDeviceEast:~/azure-iot-sdk-c/cmake/provisioning_client/samples/prov_dev_client_sample$ ./prov_dev_client_sample Provisioning API Version: 1.2.9 Registering Device Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Registration Information received from service: contoso-east-hub.azure-devices.net, deviceId: contoso-simdevice-east Press enter key to exit:来自美国西部 VM 的示例输出:
contosoadmin@ContosoSimDeviceWest:~/azure-iot-sdk-c/cmake/provisioning_client/samples/prov_dev_client_sample$ ./prov_dev_client_sample Provisioning API Version: 1.2.9 Registering Device Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Registration Information received from service: contoso-west-hub.azure-devices.net, deviceId: contoso-simdevice-west Press enter key to exit:
清理资源
如果打算继续使用本教程中创建的资源,则可以保留它们。 否则,请使用以下步骤删除本教程创建的所有资源,以避免不必要的费用。
此处的步骤假定你按照名为 contoso-us-resource-group 的同一资源组的指示创建了本教程中的所有资源。
重要说明
删除资源组的操作不可逆。 资源组以及包含在其中的所有资源将被永久删除。 请确保不要意外删除错误的资源组或资源。 如果在现有的包含要保留资源的资源组中创建了 IoT 中心,则只删除 IoT 中心资源本身,而不要删除资源组。
若要按名称删除资源组:
登录 Azure 门户。
选择“资源组”。
在“按名称筛选...”文本框中,键入包含资源的资源组名称“contoso-us-resource-group”。
在结果列表中的资源组右侧,选择“...”,然后选择“删除资源组”。
系统会要求确认是否删除资源组。 再次键入资源组的名称进行确认,然后选择“删除”。 片刻之后,将会删除该资源组及其包含的所有资源。
Next steps
若要了解有关自定义分配策略的详细信息,请参阅