Skip to main content

使用自动部署模块到多个Azure IoT Edge设备上

分类:  Azure物联网 标签:  #Azure #IoT Edge # 发布于: 2023-06-14 21:27:50

我们前面一章学习了什么是自动部署的概念,我们这一章学习step by step的教程。

本教程的目的:

  • 创建Azure IoT Hub以及Azure IoT DSP, 并连接他们用于大规模部署
  • Azure IoT DPS里新建两个分组登记,并给分组登记设定设备的tags属性:tags.location.region='Shanghai'和tags.location.region='Beijing'
  • 创建两个虚拟机并安装Azure IoT Edge Runtime, 并通过DPS完成自动注册。
  • Azure IoT Hub上创建标准的自动部署,观察两个设备是否自动部署了。
  • Azure IoT Hub上创建一个分层部署,并指定部署条件,观察两个设备是否完成了自动部署。

下面我们开始我们的教程。

创建Azure IoT Hub和创建Azure IoT DSP服务,并连接两个服务

我们这里使用Azure CLI的IoT扩展完成本章,关于如何安装和配置Azure CLi IoT工具,请参考文章:https://www.azuredeveloper.cn/article/azure-iot-hub-tools

开始初始化Azure CLi:

az cloud set --name AzureChinaCloud
az login
az account set --subscription [Your Subscrpiton id] 

创建默认的资源组和创建Azure IoT Hub:

az group create --name MyIoTGroupByCli --location chinaeast2  # 创建一个资源组
az iot hub create --resource-group MyIoTGroupByCli --name MyIoTHubByCli --location chinaeast2  # 创建一个IoT Hub的资源

创建一个Azure IoT DPS服务,并连接到Azure IoT Hub:

az iot dps create --name MyIoTHubDPSByCli --resource-group MyIoTGroupByCli --location chinaeast2
az iot hub show-connection-string --name MyIoTHubByCli --key primary --query connectionString -o tsv #使用如下的命令得到Azure IoT Hub的连接字符串
az iot dps linked-hub create --dps-name  MyIoTHubDPSByCli --resource-group MyIoTGroupByCli --connection-string <您的连接字符串> --location chinaeast2 #使用连接字符串连接Azure IoT Hub和DPS服务

连接好Azure IoT HubAzure IoT Hub DPS服务之后,可以使用如下的命令来查看结果:

az iot dps show --name MyIoTHubDPSByCli

Azure IoT Hub DPS服务中创建两个登记分组

我们这里创建两个登记分组是为了演示不同的设备,因此在创建分组的时候要给设备添加tags属性,这里的属性主要是tags.location.region,值分别指到ShanghaiBeijing

使用如下的命令来创建一个针对location在Shanghai的登记分组,请注意参数--edge-enabled表示可以登记注册IoT Edge设备,这个一定要打开。

az iot dps enrollment-group create -g MyIoTGroupByCli --dps-name MyIoTHubDPSByCli --enrollment-id ShanghaiGroupByCli --initial-twin-tags "{'location':{'region':'Shanghai'}}" --edge-enabled

然后再注册一个location在Beijing的登记分组:

az iot dps enrollment-group create -g MyIoTGroupByCli --dps-name MyIoTHubDPSByCli --enrollment-id BeijingGroupByCli --initial-twin-tags "{'location':{'region':'Beijing'}}" --edge-enabled

然后我们可以使用如下的命令得到两个分组登记的idScopeSAS Key我们需要使用两个信息将来在IoT Edge设备进行登记。

取回DPS服务的idScope:

az iot dps show --name MyIoTHubDPSByCli -g MyIoTGroupByCli  | jq .properties.idScope

请注意这里需要安装工具jq, 请参考网站:https://stedolan.github.io/jq/

使用如下的取回SAS Key

az iot dps enrollment-group show --dps-name MyIoTHubDPSByCli -g MyIoTGroupByCli --enrollment-id ShangHaiGroupByCli --show-key
az iot dps enrollment-group show --dps-name MyIoTHubDPSByCli -g MyIoTGroupByCli --enrollment-id BeijingGroupByCli --show-key

后面我们会需要这两个SAS Key用于计算Azure IoT Edge设备的Key, Azure IoT Hub使用这个Key用于从Azure IoT DPSAzure IoT Hub进行分组登记。

Azure IoT Hub中创建自动部署

我们这里演示通过Azure IoT Hub的Portal来创建自动部署,我们这里使用Azure Portal来创建一个标准的部署和一个分层的部署,标准部署用于部署Azure IoT Hub的系统模块,这包括edgeAgentedgeHub, 分层部署用于部署温度监控模块Simulated Temperature Sensor, 需要注意的是这个模块我们只部署在Locaiton为Shanghai的设备上。

现在我们开始来创建这个两个部署。

登录到Azure Portal, 找到您的Azure IoT Hub的资源,然后选择左侧菜单的IoT Edge, 如下图:


从图上可以看到:

  • 步骤1是选择Azure IoT Edge
  • 步骤2选择IoT Edge Deployments
  • 步骤3选择创建一个新的标注部署

创建一个标准的自动部署用于向每个设备部署系统模块: edgeAgentedgeHub

上一步点击了创建IoT Edge Deployments'之后,在出现的界面上起一个名字:sys_module_installation`, 如下图:


然后点击下一步, 如下图选择Runtime Setting:


接下来我们需要创建两个系统模块的部署,edgeAgentedgeHub这两个模块,为了更好的测试我们需要给两个模块添加创建选项和一个环境变量用于两个模块保存离线的数据到设备本地,这样如果设备掉线,本地数据也是一直保存,而且等到设备重新在线之后,也可以很快的同步到IoT Hub, 要满足这样两个功能,需要在创建的时候指定变量。

edgeAgent模块的设置

edgeAgent模块的设置主要如下图:


这个图例需要注意如下的事情:

  • Image URL是:mcr.microsoft.com/azureiotedge-agent:1.2

  • Image Pull Policy是:On Create

  • 需要添加的环境变量名是: storageFolder, 它的值是:/iotedge/storage/edgeagent

  • 容器创建时添加的选项是:

      {"HostConfig":{"Binds":["/var/run/iotedgelocal/edgeagent:/iotedge/storage/edgeagent"]}}
    

edgeHub模块的设置

edgeHub模块的主要设置如下图:


这个图例需要注意的设置如下图:

  • Image URL是:mcr.microsoft.com/azureiotedge-hub:1.2

  • Image Pull Policy是:On Create

  • 需要添加的环境变量名是: storageFolder, 它的值是:/iotedge/storage/edgeagent

  • 容器创建时添加的选项是:

      "Binds":["/var/run/iotedgelocal/edgeagent:/iotedge/storage/edgeagent"]
    

    注意这个选项添加的位置,是添加在已有的HostConfig里的,不要添加错了,添加错了,会提是你错误的json格式。

配置好后,点击按钮apply然后返回,继续选择下一步配置Route, 如下图:


路由起名:defaultRoute, 它的值是:FROM /message/* INTO $upstream, 代表所有的消息都会传递给Azure IoT Hub

然后下一步跳过指标的配置,到目标设备的配置了,如下图:


我们这里设置优先级为10, 目标设备选择条件设置为:tags.location.region='Shanghai' AND tags.location.region='Beijing'

这里是值选择北京和上海两个区域的所有设备, 最后点击下一步,然后创建部署就完成了一个标准的部署创建。

创建分层部署

我们上面讨论过了创建标准的部署时为了给每个设备安装系统模块,我们这里为了演示,创建一个分层模块用于向所有位于上海区域的设备安装一个新模块Simulated Temperature Sensor

一般情况下我们可以通过Azure IoT Edge Marketplace来搜索这个模块,但是很不幸的是Azure IoT Edge Marketplace经常抽风,有时候甚至干脆就不工作了,所以我们建议在部署自定义模块的时候,如果自己知晓模块的镜像地址,干脆就通过手动来部署就好了。我们可以通过github站点来详细的了解一个镜像的手动引入格式是什么,具体文档在这里:https://github.com/microsoft/containerregistry, 通过这里文档,我们可以得知该模块的镜像地址是:mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:latest, 可以通过地址找到它的所有版本:https://mcr.microsoft.com/v2/azureiotedge-simulated-temperature-sensor/tags/list 。

我们开始创建一个新的分层部署, 通过在标准部署那个一样的界面选择Add Layered Deployment, 来添加一个新的分层部署,我们首先给它起一个名字:custom_module_installation, 如下图:

 

然后下一步:这一步里选择Add -> IoT Edge Module, 如下图:


然后在出现的界面上按照如下的配置:


然后下一步,跳过指标配置和消息配置,直接进行目标设备配置:


注意这里的优先级选择:13, 同时设备的选择条件更改为:tags.location.region='Shanghai', 只针对上海区域的设备了。

最后完成创建的界面如下:


设备预置

我们已经配置,现在我们需要来创建两个虚拟机,并模拟分别部署在ShanghaiBeijing的设备,并通过DPS服务来登记和注册这两个设备。

我们这里使用基于Ubuntu 18.04的虚拟机来模拟设备。

创建位于Shanghai的设备

使用如下的命令来创建虚拟机:

az vm create --public-ip-sku Standard --resource-group MyIoTGroupByCli --name ShangHaiDevice-1 --image Canonical:UbuntuServer:18.04-LTS:18.04.202112020 --location chinaeast2 --admin-username azureuser --admin-password <Your Password>

创建完成后,配置该设备为Azure IoT Edge设备。

用ssh等到虚拟机上:

ssh azureuser@<public ip address>

登录之后使用如下的命令安装Azure IoT Edge, 详细的关于如何安装和初步配置Azure IoT Edge, 您可以参考文章:https://www.azuredeveloper.cn/article/simple-introduce-azure-iot-edge, 这篇文章里有详细的讨论,我们这里只是罗列命令:

curl https://packages.microsoft.com/config/ubuntu/18.04/multiarch/packages-microsoft-prod.deb > ./packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt-get install moby-engine
sudo apt-get install aziot-edge

到这里就安装完成了,下一步我们需要配置并启动Azure IoT Edge runtime。

要记得一件事,我们之前在模块上部署的时候,给系统模块设定了storage, 在host上的目录是/var/run/iotedgelocal/edgeagent, ssh登录上去之后,通过如下的命令创建目录:

sudo mkdir -p /var/run/iotedgelocal/edgeagent
sudo mkdir -p /var/run/iotedgelocal/edgehub

然后给这两个目录赋予权限:

sudo chown -R 1000 /var/run/iotedgelocal/edgeagent
sudo chown -R 1000 /var/run/iotedgelocal/edgehub
sudo chmod 700 /var/run/iotedgelocal/edgeagent
sudo chmod 700 /var/run/iotedgelocal/edgehub

注意
千万不要遗漏了这里的权限设置,不过这里有一个问题,为什么在给目录赋予用户的时候是用户ID是1000呢?请大家注意这里必须是1000, 至于为什么,留个大家去思考好了,给一个提示:查看一下docker起来之后的Image里运行的用户ID是多少,就明白了。

由于我们是计划使用DPS服务来登记和注册Azure IoT Edge设备,同时我们使用的登记分组是基于SAS Key的,我们前面的步骤已经告诉了大家如何得到我们需要的两个关键的信息:

  • Azure IoT DPSIdScope
  • 登记分组的SAS Key

下面我们使用这些信息来计算设备的key, 首先我们需要给设备起一个名字,我们这个设备名字就可以叫做:shanghai-device-1, 如果您是windows 电脑,启动powershell, 使用如下的命令来计算设备的key:

$KEY='PASTE_YOUR_ENROLLMENT_KEY_HERE'
$REG_ID='PASTE_YOUR_REGISTRATION_ID_HERE'

$hmacsha256 = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha256.key = [Convert]::FromBase64String($KEY)
$sig = $hmacsha256.ComputeHash([Text.Encoding]::ASCII.GetBytes($REG_ID))
$derivedkey = [Convert]::ToBase64String($sig)
echo "`n$derivedkey`n"

注意,这里的$KEY就是分组的SAS Key, 这里的$REG_ID即是我们的设备名字shanghai-device-1

然后登录到虚拟机之后,采用如下的方式来配置:

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

更改文件的内容如下:

[provisioning]
source = "dps"
global_endpoint = "global.azure-devices-provisioning.cn"
id_scope = "PASTE_YOUR_SCOPE_ID_HERE"

[provisioning.attestation]
method = "symmetric_key"
registration_id = "PASTE_YOUR_REGISTRATION_ID_HERE"

symmetric_key = "PASTE_YOUR_PRIMARY_KEY_OR_DERIVED_KEY_HERE"

保存文件之后运行命令:

sudo iotedge config apply

然后重启设备,sudo iotedge system restart, 即可以了。

然后使用同样的步骤配置位于Beijing的虚拟机,但是需要注意的是,Beijing的虚拟机上device id为beijing-device-1, 同时它选择的分组登记时另外一个分组:BeijingGroupByCli, 使用的SAS Key也是这个分组的,而不是shanghai分组的。这一个一定要记得,会注册同一个分组里了,这里非常重要!!!

全部创建完成之后,既可以登录到两台机器上观察模块的自动部署是否符合预期。