谢谢您的订阅!
当新的内容发布后您将开始接收邮件。您也可以点击邮件内的链接随时取消订阅。关闭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 如何成为叶节点理想平台的信息,请单击此处

订阅博客文章

订阅您感兴趣的主题

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

查看更多内容

Ubuntu 全面支持 Azure Cobalt 100 虚拟机

Ubuntu 和 Ubuntu Pro 支持 Microsoft 的 Azure Cobalt 100 虚拟机(VM),由其首个内部设计的 64 位 Arm 处理器提供支持。凭借 Ubuntu 广泛的 Arm 兼容性,用户可以放心地使用这些虚拟机部署他们的工作负载。 全面的 Arm 软件包支持 Ubuntu 通过编译和测试该架构 Ubuntu 存档中超过 95% 的软件包,确保采用这些新虚拟机的用户获得无缝体验。这种广泛的兼容性使开发人员和企业能够运行他们喜欢的工具和应用程序,而无需进行任何妥协。 为多样化的工作负载做好准备 Azure Cobalt 100 虚拟机非常适合各种要求苛刻的工作负载,包括: 此外,这些虚拟机在支持 Anbox Cloud 部署方面表现出色,为 […]

Canonical 获得 ISO/SAE 21434 认证,强化了汽车网络安全标准

经过认证的网络安全流程有助于保护下一代互联汽车 Canonical 自豪地宣布,其安全管理系统经过全球知名认证提供商 TÜV SÜD 的广泛评估,已获得 ISO/SAE 21434 认证。这一里程碑突出了 Canonical 在为汽车行业提供可信可靠的开源解决方案方面的领导地位。它强调了 Canonical 对三大关键业务支柱的承诺:强大的网络安全、符合全球行业标准以及为自动驾驶和智能汽车构建更安全的未来。 强大的汽车网络安全 随着车辆的互联程度越来越高,未经授权的访问、远程攻击和数据泄露的风险也显著增加。ISO/SAE 21434 为在整个车辆生命周期内管理这些风险提供了详细的框架。对于原始设备制造商和一级供应商来说,合规是在竞争激烈的市场中交付产品的关键。 Canon […]

Canonical 和 Renesas 宣布将合作加速企业 AI 创新

Ubuntu 的发行商 Canonical 宣布,半导体解决方案的全球领导者 Renesas Electronics Corporation 已加入 Canonical 的硅合作伙伴计划,以提供量身定制的尖端解决方案来满足边缘计算和 AI 应用不断增长的需求。随着行业越来越多地采用 AI 驱动的解决方案,对高效、可扩展和安全维护的边缘计算平台的需求前所未有地高涨。此次合作将结合 Renesas 在嵌入式处理方面的专业知识和 Canonical 全面的物联网(IoT)软件堆栈。 可扩展的生产级解决方案 Canonical 和 Renesas 的合作旨在为原始设备制造商(OEM)和原始设计制造商 (ODM)提供可扩展的生产级解决方案,从而缩短上市时间(TTM)。Renesas […]