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

  1. 博客
  2. 文章

Canonical
23 January 2025

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


简介

随着最近 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 如何成为叶节点理想平台的信息,请单击此处。


查看更多内容

Canonical Managed Kubeflow AI 运维平台现已登陆 Microsoft Azure Marketplace

Ubuntu 发行商 Canonical 近日宣布,其 Managed Kubeflow 服务已在 Microsoft Azure Marketplace 正式上线,实现全面商用(GA)。该解决方案允许 AI 团队在自有云租户环境内获得一个完全托管、可直接投入生产的 MLOps 平台。 上游 Kubeflow...

Canonical 与 Microsoft 合作,加强企业级 Linux 防护

Canonical 正与 Microsoft Defender 合作,提升企业关键业务 Linux 工作负载的安全性 2026 年 3 月 18 日 Ubuntu 发行商 Canonical 宣布与 Microsoft Defender 推出全新安全合作项目,旨在结合 Canonical 安全维护服务 Ubuntu...

全新工具 Workshop 上线:一条命令即可在 Ubuntu 中启动沙箱开发环境

开发者如今可在智能体 AI 等前沿工作流程中,获得环境统一、可复现的开发体验 Canonical 正式发布 Workshop,该解决方案可通过单条命令快速启动开发环境。只需配置一次,此开发环境即可在多台设备上复现使用。这意味着各类开发设备与部署流水线可保持统一工作流程,并可大幅减少管理依赖关系所花费的时间。...

Canonical 技术案例 – 彻底解决 12 年老旧代码中的 Linux 性能漏洞

部分支持案例处理起来十分简单。另一些案例则要深入老旧遗留代码,一处逻辑缺陷就能悄无声息让常规指令引发严重性能故障。本系列将介绍 Canonical 技术支持与持续工程团队如何协作,排查、修复并向上游提交仅靠常规故障排查无法解决的疑难问题。在第二篇帖子中,libnss-db 中一处存在 12 年之久的漏洞导致 getent...