谢谢您的订阅!
当新的内容发布后您将开始接收邮件。您也可以点击邮件内的链接随时取消订阅。关闭Close

分步指南:在 Ubuntu 上使用 Azure IoT Operations

by Canonical on 23 January 2025

简介

随着最近 Azure IoT Operations 的发布,Microsoft 为其客户提供了一个统一的数据平面,在节点数据捕获、基于边缘的遥测处理和云入口方面做出重大改进。 

Azure IoT Operations 与 Ubuntu 的结合可谓是相得益彰,可以构建开箱即用的安全可靠的解决方案。 

这篇博客是 Microsoft 的 Azure IoT Operations 入门的分步指南。最后,您会将 Azure IoT Operations 服务部署到本地支持 Azure Arc 的 microk8s Kubernetes 集群,并使用 X509 证书身份验证配置了与集群的 MQTT 代理的安全通信。为了实现这一点,您将执行命令、创建和编辑文件并发布自签名证书,以模拟智能冰箱向云提供监控信息的行为。

在本教程中,我们将配置三个组件。首先是边缘节点,然后是作为叶节点和数据生成器的 Ubuntu Core 设备,最后是一个基于云的环境来可视化数据。

您需要一个 Microsoft Azure 账户来完成本教程。让我们开始吧。 

边缘节点

1. 创建 Multipass 实例

第一步是创建一个运行边缘节点的环境。我们将使用 Multipass,这是一个来自 Canonical 的轻量级虚拟机管理器,旨在快速启动和管理本地机器上的 Ubuntu 图像。我们将使用它为边缘节点创建 Ubuntu 22.04 VM,然后创建一个核心设备作为叶节点。 

对于边缘节点,我们需要增加默认磁盘、内存和 CPU 大小,以使它们更加真实,在本例中为 20GB 磁盘、6GB 内存和 2 个 CPU。 

启动后,我们将使用 shell 命令进入虚拟机:

$ multipass launch 22.04 --disk 20G --memory 8G --cpus 2 
Launched: cleansing-guanaco
$ multipass shell cleansing-guanaco

2. 安装 MicroK8s

现在我们正在边缘节点虚拟机内部工作,我们将安装 Microk8s,这是 Canonical 的超轻量 Kubernetes 实现。我们将用它来运行 Azure IoT Operations 集群。

$ snap install microk8s –-classic 

该安装将自动创建集群,默认名称为 microk8s-cluster

为了避免在 Microk8s 中使用 sudo,我们将创建一个用户组,然后创建一个可以被 Azure 获取的 kubectl 配置文件。

注意:为了避免被要求对 snap 命令使用 sudo,您可以使用“snap login”登录到 snap store。系统将要求提供凭据,但如果您愿意继续使用 sudo,也可忽略此要求。

sudo usermod -a -G microk8s $USER
sudo chown -f -R $USER ~/.kube

mkdir -p ~/.kube
microk8s config > ~/.kube/config

3. 部署 Azure IoT Operations

下一步,我们将部署 Azure IoT Operations 集群。为此,我们需要安装 Azure CLI。这可以使用以下命令来实现:

curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

此时,我们将按照 Microsoft 快速入门说明在您的本地集群上部署 Deploy Azure IoT Operations。对于本教程,只需要按照快速入门指南的第一页进行操作,不需要进行下一步(将 OPC-UA 资产添加到 Azure 集群)。

由于我们将使用自己的集群而不是 GitHub 代码空间,我们需要在开始之前设置一些环境变量。

SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 从您的 azure 帐户中获取,可在 Azure 门户网站的订阅下找到

LOCATION="westeurope" # 必须是支持 Azure IoT Operations 的有效 Azure 位置,可在此处找到,使用“az account list-locations -o table”列出位置

RESOURCE_GROUP="azure_iot_operations_quickstart" # 资源组(将在它下面创建所有 Azure 资源)的名称

CLUSTER_NAME="my-local-cluster" # 本地集群的名称,替换为唯一的名称以避免名称冲突

您可能需要选择唯一的 CLUSTER_NAME 以避免名称冲突,因为它正用于创建一些具有全局名称空间的 Azure 资源(例如密钥库)。有关如何重命名 Microk8s 集群的详细信息,请单击此处

通过证书身份验证从设备发布和订阅 MQTT

为了向我们的集群认证设备,我们需要生成一些 X509 证书。因为我们是自签名,所以可以在您的集群机器上创建这些证书,尽管不建议在生产中使用。

1. 安装 step-cli

您将使用 step-cli 来创建证书。安装时,请遵循此处的说明。

2. 创建所需的自签名 X509 证书

创建自签名的根 CA 证书和私钥。

step certificate create --profile root-ca "My Root CA" root_ca.crt root_ca.key

创建由根证书签名的中间 CA 证书。

step certificate create --profile intermediate-ca "My Intermediate CA" intermediate_ca.crt intermediate_ca.key --ca root_ca.crt --ca-key root_ca.key

创建由中间证书签名的叶(客户端)证书。–Bundle 标志将中间证书与客户端证书捆绑在一起。这对于在向 MQTT 代理提交证书时完成 CA 链非常重要,因为根证书是唯一将被导入 Azure IoT Operations 集群的证书。

step certificate create --profile leaf "Client A" client_a_intermediate_bundle.crt client_a_intermediate_bundle.key --ca intermediate_ca.crt --ca-key intermediate_ca.key --bundle

3. 配置证书身份验证

将根 CA 证书作为 configmap 导入到 “client-ca” 密钥下。

microk8s kubectl create configmap client-ca --from-file=root_ca.crt -n azure-iot-operations

使用以下内容创建 x509Attributes.toml 文件。它用于为授权目的定义证书到属性的映射。内容是虚拟的,因为我们只关心身份验证,但是文件是必需的。

[root]
subject = "CN = Contoso Root CA Cert, OU = Engineering, C = US"

[root.attributes]
organization = "contoso"

[intermediate]
subject = "CN = Contoso Intermediate CA"

[intermediate.attributes]
city = "seattle"
foo = "bar"

[smart-fan]
subject = "CN = smart-fan"

[smart-fan.attributes]
building = "17"

x509Attributes.toml 文件作为 Kubernetes 密码导入到 “x509-attributes” 密钥下。

microk8s kubectl create secret generic x509-attributes --from-file=x509Attributes.toml -n azure-iot-operations

使用以下内容创建 patch-authn-x509.json 文件。它将用于添加客户端证书,作为引用“client-ca”密钥下导入的根 CA 证书的第一种身份验证方法。

[
    {
        "op": "add",
        "path": "/spec/authenticationMethods/0",
        "value": {
            "method": "x509",
            "x509Settings": {
                "trustedClientCaCert": "client-ca"
            }
        }
    }
]

在身份验证 brokerauthentication 上应用补丁。

microk8s kubectl patch brokerauthentication default -n azure-iot-operations --type json --patch "$(cat patch-authn-x509.json)"

4. 向外界公开 MQTT 代理端点

使用以下内容定义 patch-listener-loadbalancer-ip-dns.json 文件。它将用于将侦听器的类型更改为负载平衡器,并定义 ip 和 dns SAN(服务备用名称),以便从集群外部进行安全通信。

[
    {
        "op": "replace",
        "path": "/spec/serviceType",
        "value": "loadBalancer"
    },
    {
        "op": "add",
        "path": "/spec/ports/0/tls/certManagerCertificateSpec/san",
        "value": {
            "dns": [
                "localhost"
            ],
            "ip": [
                "127.0.0.1"
            ]
        }
    }
]

在侦听器 brokerauthentication 上应用补丁。
microk8s kubectl patch brokerlistener default -n azure-iot-operations --type json --patch "$(cat patch-listener-loadbalancer-ip-dns.json)"

检查 MQTT 前端服务上分配的外部 ip 和端口。应用补丁可能需要一些时间。

microk8s kubectl get service aio-broker --namespace azure-iot-operations

5. 使用演示客户端 snap 发布到 MQTT

创建 Ubuntu Core Multipass 实例。确保它可以连接到 Multipass 服务器实例,然后安装 snap:

$ multipass launch core24 -n CoreDev24
$ multipass shell CoreDev24

安装演示客户端 snap。

snap install --edge azure-iot-operations-mqtt-demo-client

在本地获取根 CA 证书,以便安全地与 MQTT 代理通信。

microk8s kubectl get configmap aio-ca-trust-bundle-test-only -n azure-iot-operations -o jsonpath='{.data.ca\.crt}' > ca.crt

配置 broker.host、broker.port、broker.ca、client.cert 和 client.key。

snap set azure-iot-operations-mqtt-demo-client broker.host=localhost broker.port=31698 broker.ca="$(cat ca.crt)" client.cert="$(cat client_a_intermediate_bundle.crt)" client.key="$(cat client_a_intermediate_bundle.key)" # replace 31698 with the correct port

(!) 如果您之前已经设置了 client.username 和 client.password,请取消设置,以避免使用的身份验证方法出现任何歧义。

snap set azure-iot-operations-mqtt-demo-client client.username! client.password!

开始发布消息。

azure-iot-operations-mqtt-demo-client.mqtt-producer

在 Microsoft Fabric 上发送和可视化 MQTT 数据

MQTT 客户端运行并发布数据后,我们现在将尝试使用 Microsoft Fabric 来可视化这些数据。

1. 创建 Azure 事件中心

创建 Azure 事件中心命名空间。

az eventhubs namespace create --name ${CLUSTER_NAME:0:24} --resource-group $RESOURCE_GROUP --location $LOCATION

创建 Azure 事件中心,数据将被发送到该中心。

az eventhubs eventhub create --name smart-refrigerator --resource-group $RESOURCE_GROUP --namespace-name ${CLUSTER_NAME:0:24} --retention-time 1 --partition-count 1 --cleanup-policy Delete

获取集群上 Azure IoT Operations Kubernetes 扩展的名称。

AIO_EXTENSION_NAME=$(az k8s-extension list --resource-group $RESOURCE_GROUP --cluster-name $CLUSTER_NAME --cluster-type connectedClusters -o tsv --query "[?extensionType=='microsoft.iotoperations'].name")

定义 event-hubs-config.bicep 文件,该文件将用于向 Azure IoT Operations Kubernetes 扩展分配事件中心数据接收者事件中心数据发送者 的角色,包含以下内容。

@description('Location for cloud resources')
param aioExtensionName string = 'azure-iot-operations'
param clusterName string = 'clusterName'
param eventHubNamespaceName string = 'default'

resource connectedCluster 'Microsoft.Kubernetes/connectedClusters@2021-10-01' existing = {
  name: clusterName
}

resource aioExtension 'Microsoft.KubernetesConfiguration/extensions@2022-11-01' existing = {
  name: aioExtensionName
  scope: connectedCluster
}

resource ehNamespace 'Microsoft.EventHub/namespaces@2021-11-01' existing = {
  name: eventHubNamespaceName
}

// Role assignment for Event Hubs Data Receiver role
resource roleAssignmentDataReceiver 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(ehNamespace.id, aioExtension.id, '7f951dda-4ed3-4680-a7ca-43fe172d538d')
  scope: ehNamespace
  properties: {
     // ID for Event Hubs Data Receiver role is a638d3c7-ab3a-418d-83e6-5f17a39d4fde
    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') 
    principalId: aioExtension.identity.principalId
    principalType: 'ServicePrincipal'
  }
}

// Role assignment for Event Hubs Data Sender role
resource roleAssignmentDataSender 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(ehNamespace.id, aioExtension.id, '69b88ce2-a752-421f-bd8b-e230189e1d63')
  scope: ehNamespace
  properties: {
    // ID for Event Hubs Data Sender role is 2b629674-e913-4c01-ae53-ef4638d8f975
    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') 
    principalId: aioExtension.identity.principalId
    principalType: 'ServicePrincipal'
  }
}

应用 event-hubs-config.bicep 来分配角色。

az deployment group create --name assign-RBAC-roles --resource-group $RESOURCE_GROUP --template-file event-hubs-config.bicep --parameters aioExtensionName=$AIO_EXTENSION_NAME --parameters clusterName=$CLUSTER_NAME --parameters eventHubNamespaceName=${CLUSTER_NAME:0:24}

2. 创建数据流

定义 dataflow.yml 文件,该文件将用于创建从集群的 MQTT 代理到 Azure 事件中心的数据流,其内容如下。


apiVersion: connectivity.iotoperations.azure.com/v1beta1
kind: DataflowEndpoint
metadata:
  name: mqtt-source
  namespace: azure-iot-operations
spec:
  endpointType: Mqtt
  mqttSettings:
    host: "aio-broker:18883"
    tls:
      mode: Enabled
      trustedCaCertificateConfigMapRef: azure-iot-operations-aio-ca-trust-bundle
    authentication:
      method: ServiceAccountToken
      serviceAccountTokenSettings:
        audience: aio-internal
---
apiVersion: connectivity.iotoperations.azure.com/v1beta1
kind: DataflowEndpoint
metadata:
  name: kafka-target
  namespace: azure-iot-operations
spec:
  endpointType: Kafka
  kafkaSettings:
    host: '<NAMESPACE>.servicebus.windows.net:9093'
    batching:
      latencyMs: 0
      maxMessages: 100
    tls:
      mode: Enabled
    authentication:
      method: SystemAssignedManagedIdentity
      systemAssignedManagedIdentitySettings:
        audience: https://<NAMESPACE>.servicebus.windows.net
---
apiVersion: connectivity.iotoperations.azure.com/v1beta1
kind: Dataflow
metadata:
  name: mqtt-to-eh
  namespace: azure-iot-operations
spec:
  profileRef: example-dataflow
  operations:
    - operationType: source
      sourceSettings:
        endpointRef: mqtt-source
        dataSources:
        - smart-refrigerator
    - operationType: destination
      destinationSettings:
        endpointRef: kafka-target
        dataDestination: smart-refrigerator
---
apiVersion: connectivity.iotoperations.azure.com/v1beta1
kind: DataflowProfile
metadata:
  name: example-dataflow
  namespace: azure-iot-operations
spec:
  instanceCount: 1
  diagnostics:
    logs:
      level: "debug"

将 <NAMESPACE> 占位符替换为事件中心名称空间名称,并将其另存为新的 my_dataflow.yml 文件。

sed 's/<NAMESPACE>/'"${CLUSTER_NAME:0:24}"'/' dataflow.yaml > my_dataflow.yaml

应用 my_dataflow.yml 文件来创建数据流。

microk8s kubectl apply -f my_dataflow.yaml

通过转到 Azure 门户网站并导航到事件中心命名中间 > 事件中心,验证数据正在流向 Azure 事件中心。

3. 创建 Microsoft Fabric 仪表板

遵循从您的数据获取见解的快速入门说明,为 OPC UA 数据创建 Microsoft Fabric 仪表板。您应该对说明进行以下调整:

1. 必要时使用 smart-refrigerator 事件中心,而不是 destinationeh

2. 使用以下列创建名为 MQTT 的 KQL 表,而不是 OPCUA

Column NameData Type
RefrigeratorTempDecimal
FreezerTempDecimal
TimestampDatetime

3. 使用下面的 KQL 查询为表创建映射,并在需要时使用创建的 mqtt_mapping 映射,而不是 opcua_mapping

.create table ['MQTT'] ingestion json mapping 'mqtt_mapping' '[{"column":"RefrigeratorTemp", "Properties":{"Path":"$.refrigerator_temp"}},{"column":"FreezerTemp", "Properties":{"Path":"$.freezer_temp"}},{"column":"Timestamp", "Properties":{"Path":"$.timestamp"}}]'

4. 对仪表板使用以下 KQL 查询。
MQTT 
| where Timestamp between (_startTime.._endTime)
| project Timestamp, RefrigeratorTemp, FreezerTemp

5. 使用以下仪表板视觉特征:

  • Tile name: Refrigerator and Freezer Temperature
  • Visual type: Line chart
  • Data:
    • Y columns: RefrigeratorTemp (decimal) and FreezerTemp (decimal) (already inferred by default)
    • X columns: Timestamp (datetime) (already inferred by default)
  • Y Axis:
    • Label: Temperature in C
  • X Axis:
    • Label: Timestamp

完成上述步骤后,仪表板应该如下所示。

总结

所以,现在您应该拥有一个功能齐全的 Azure IoT Operations 部署,模拟智能冰箱,并通过 MQTT 将数据发送到云端,在那里您可以实现实时可视化。从这里开始,您可以使用大量的选项可以用来增强数据收集和聚合。 

基于本教程,您可以开发自己的 IoT 解决方案,其中数据可视化和实时遥测报告将是成功的关键。

要进一步了解边缘节点的功能,请查看此处提供的 Microsoft 文档。

此外,如果在你的环境中选择了该协议的话,这也是一个 OPC-UA 模拟器,可作为一个用于试验的 snap 软件包。 当您想扩展到生产的时候,如果您想了解更多关于 Ubuntu Core 如何成为叶节点理想平台的信息,请单击此处

订阅博客文章

订阅您感兴趣的主题

在提交此表格的同时,我确认已阅读和同意的隐私声明隐私政策。

查看更多内容

什么是 IoT 设备管理?

IoT 设备管理是指用于部署、监控和维护 IoT 设备的流程或实践。随着组织扩大其 IoT 工作,可靠的设备管理方法对于运行安全、简化的设备群至关重要。  全球联网设备的激增(预计 2024 年达到 188 亿台)意味着 IoT 设备管理变得越来越复杂,这一现实并没有被恶意行为者忽视。事实上, 2023 年平均每个组织每周遭受 60 次 IoT 攻击。这是因为设备以及它们之间的连接和您的管理系统构成了一个相当大的攻击面。 在这篇博客中,我们将通过关注您需要实现的 3 个目标来讲解 IoT 设备管理的基础:可见性、互操作性和安全性。我们将介绍开放式设备管理方法如何确保您在任何行业、任何规模的任何设备中实现这三个目标。 可统合并保护您设备的一把伞 您可以将自己的 IoT 管理 […]

写给坚守CentOS的你-必知的六个关键点,助你做好准备

CentOS 7 的生产商在 2020 年宣布,CentOS 7 将于 2024 年 7 月达到生命周期结束(EoL)。如今,该日期已经过去,然而 CentOS 的故事还没有结束。有人预计 CentOS 用户数量会大幅下降,但数据显示,22% 的企业仍在使用 CentOS。  我们也许应该降低我们的期望:CentOS 7 的生命周期可能即将结束,但许多组织可能仍在考虑向新系统过渡却尚未实施。然而,CentOS 用户仍然必须面对这样一个事实:他们等待迁移的时间越长,就越难保持 CentOS 资产的安全和功能。坚持下去看起来很诱人,但是月复一月,年复一年,依赖关系将开始瓦解,手动修补工作量将增加,不兼容性将开始在整个堆栈中出现。  本篇博客适合仍在决定迁移到哪个系统的读者进行 […]

Canonical 推出首个 MicroCloud LTS 版本

扩大 Canonical 基础架构解决方案 - MicroCloud 2.1.0 LTS 长期支持承诺  Canonical 推出 MicroCloud 的首个长期支持(LTS,Long Term Support)版本。MicroCloud 是 Canonical 的云基础架构产品组合的一员。作为 Ubuntu 的发行商,Canonical 以每两年在4月份提供 Ubuntu LTS 版本著名。随着 MicroCloud LTS 的加入,Canonical 扩大了对寻求面向边缘和低接触云的可扩展虚拟化解决方案的组织提供长期支持的承诺。  MicroCloud 2.1.0 LTS 支持单节点部署,改进了安全状况,并在初始化过程中具有更大的灵活性。它将 LXD 作为其虚拟化平 […]