你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
快速入门:配置群集
重要
Azure Arc 启用的 Azure IoT 操作预览版目前处于预览状态。 不应在生产环境中使用此预览版软件。
在正式版推出后,你需要部署新的 Azure IoT 操作安装。 无法升级预览版安装。
有关 beta 版本、预览版或尚未正式发布的版本的 Azure 功能所适用的法律条款,请参阅 Microsoft Azure 预览版的补充使用条款。
本快速入门将在 Azure IoT 操作预览版群集中配置以下资源:
- 资产终结点 - 定义与模拟面包店烤箱的模拟 OPC PLC 服务器的连接。
- 资产 - 表示烤箱并定义烤箱公开的数据点。
- 数据流 - 用于处理模拟烤箱的消息。
资产是表示设备、计算机、系统或流程的物理设备或逻辑实体。 例如,物理资产可以是泵、电机、储罐或生产线。 定义的逻辑资产可以具有属性、流遥测或生成事件。
OPC UA 服务器是与资产通信的软件应用程序。 OPC UA 标记是 OPC UA 服务器公开的数据点。 OPC UA 标记可以提供有关资产状态、性能、质量或条件的实时或历史数据。
本快速入门将使用 Bicep 文件来配置 Azure IoT 操作实例。
先决条件
在 Kubernetes 群集中部署 Azure IoT 操作预览版实例。 快速入门:使用 K3s 在 GitHub Codespaces 中运行 Azure IoT 操作预览版提供了简单的说明来部署可用于快速入门的 Azure IoT 操作实例。
可以在 Bash 或 PowerShell 环境中运行本快速入门中的控制台命令,除非另有说明。
我们将解决什么问题?
OPC UA 服务器公开的数据可能具有复杂的结构,并且难以理解。 Azure IoT 操作提供了一种将 OPC UA 资产建模为标记、事件和属性的方法。 通过此建模,可以更轻松地了解数据并在下游流程(例如,MQTT 代理和数据流)中使用它。 数据流可操作数据并将其路由到云服务,例如 Azure 事件中心。 在本快速入门中,数据流将更改有效负载中某些字段的名称,并将资产 ID 添加到消息中。
部署 OPC PLC 模拟器
本快速入门使用 OPC PLC 模拟器生成示例数据。 若要部署 OPC PLC 模拟器,请运行以下命令:
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/opc-plc-deployment.yaml
以下代码片段显示了已应用的 YAML 文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: opc-plc-000000
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: opcplc-000000
template:
metadata:
labels:
app.kubernetes.io/component: opcplc-000000
spec:
containers:
- name: opc-plc
image: mcr.microsoft.com/iotedge/opc-plc:latest
args:
- "--ph=opcplc-000000"
- "--cdn=opcplc-000000"
- "--ut"
- "--sn=25"
- "--sr=10"
- "--fn=2000"
- "--veryfastrate=1000"
- "--gn=5"
- "--pn=50000"
- "--maxsessioncount=100"
- "--maxsubscriptioncount=100"
- "--maxqueuedrequestcount=2000"
- "--ses"
- "--alm"
- "--at=FlatDirectory"
- "--drurs"
- "--ll-debug"
- "--nodesfile"
- "/app/config/nodesfile.json"
ports:
- containerPort: 50000
volumeMounts:
- name: opc-plc-default-application-cert
mountPath: /app/pki/own
- name: opc-plc-trust-list
mountPath: /app/pki/trusted
- name: config-volume
mountPath: /app/config
volumes:
- name: opc-plc-default-application-cert
secret:
secretName: opc-plc-default-application-cert
- name: opc-plc-trust-list
secret:
secretName: opc-plc-trust-list
- name: config-volume
configMap:
name: opc-plc-config
serviceAccountName: opcplc-000000-service-account
---
apiVersion: v1
kind: ConfigMap
metadata:
name: opc-plc-config
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
data:
nodesfile.json: |
{
"Folder": "MyTelemetry",
"NodeList": [
{
"NodeId": "ns=3;s=FastUInt100",
"Name": "Fryer Temperature",
"DataType": "Double",
"ValueRank": -1,
"AccessLevel": "CurrentReadOrWrite",
"Description": "Fryer Temperature with spikes",
"Anomaly": "Spike",
"MinValue": 150.0,
"MaxValue": 200.0
}
]
}
---
apiVersion: v1
kind: Service
metadata:
name: opcplc-000000
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
type: ClusterIP
selector:
app.kubernetes.io/component: opcplc-000000
ports:
- port: 50000
protocol: TCP
targetPort: 50000
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: opc-plc-self-signed-issuer
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: opc-plc-default-application-cert
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
secretName: opc-plc-default-application-cert
duration: 2160h # 90d
renewBefore: 360h # 15d
issuerRef:
name: opc-plc-self-signed-issuer
kind: Issuer
commonName: OpcPlc
dnsNames:
- opcplc-000000
- opcplc-000000.azure-iot-operations.svc.cluster.local
- opcplc-000000.azure-iot-operations
uris:
- urn:OpcPlc:opcplc-000000
usages:
- digital signature
- key encipherment
- data encipherment
- server auth
- client auth
privateKey:
algorithm: RSA
size: 2048
encodeUsagesInRequest: true
isCA: false
---
apiVersion: v1
kind: Secret
metadata:
name: opc-plc-trust-list
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
data: {}
---
apiVersion: batch/v1
kind: Job
metadata:
name: opcplc-000000-execute-mutual-trust
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
spec:
backoffLimit: 1
template:
spec:
containers:
- name: kubectl
image: mcr.microsoft.com/oss/kubernetes/kubectl:v1.27.1
imagePullPolicy: Always
command: ["/bin/sh"]
args: ["/scripts/execute-commands.sh"]
volumeMounts:
- name: scripts
mountPath: /scripts
readOnly: true
restartPolicy: Never
serviceAccountName: opcplc-000000-service-account
volumes:
- name: scripts
configMap:
name: opcplc-000000-execute-commands-script
---
apiVersion: v1
kind: ConfigMap
metadata:
name: opcplc-000000-execute-commands-script
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
data:
execute-commands.sh: |
#!/bin/sh
# wait 20 seconds for the resources to be created
sleep 20
# Extract the OPC UA connector application instance certificate and add it to the OPC PLC trust list
cert=$(kubectl -n azure-iot-operations get secret aio-opc-opcuabroker-default-application-cert -o jsonpath='{.data.tls\.crt}' | base64 -d)
data=$(kubectl create secret generic temp --from-literal=opcuabroker.crt="$cert" --dry-run=client -o jsonpath='{.data}')
kubectl patch secret opc-plc-trust-list -n azure-iot-operations -p "{\"data\": $data}"
# Extract the OPC PLC application instance certificate and add it to the OPC UA connector trust list
cert=$(kubectl -n azure-iot-operations get secret opc-plc-default-application-cert -o jsonpath='{.data.tls\.crt}' | base64 -d)
data=$(kubectl create secret generic temp --from-literal=opcplc-000000.crt="$cert" --dry-run=client -o jsonpath='{.data}')
kubectl patch secret aio-opc-ua-broker-trust-list -n azure-iot-operations -p "{\"data\": $data}"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: opcplc-000000-service-account
namespace: azure-iot-operations
labels:
app.kubernetes.io/component: opcplc-000000
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: opc-plc-000000-secret-access-role
namespace: azure-iot-operations
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: opc-plc-000000-secret-access-rolebinding
namespace: azure-iot-operations
subjects:
- kind: ServiceAccount
name: opcplc-000000-service-account
namespace: azure-iot-operations
roleRef:
kind: Role
name: opc-plc-000000-secret-access-role
apiGroup: rbac.authorization.k8s.io
注意
此配置使用自签名应用程序实例证书。 请勿在生产环境中使用此配置。 要了解详细信息,请参阅为 OPC UA 连接器配置 OPC UA 证书基础结构。
设置环境变量
如果使用的是 Codespaces 环境,则已设置所需的环境变量,可以跳过此步骤。 否则,请在 shell 中设置以下环境变量:
# Your subscription ID
SUBSCRIPTION_ID=<subscription-id>
# The name of the resource group where your Kubernetes cluster is deployed
RESOURCE_GROUP=<resource-group-name>
# The name of your Kubernetes cluster
CLUSTER_NAME=<kubernetes-cluster-name>
配置群集
运行以下命令以下载并运行配置 Azure IoT 操作实例的 Bicep 文件。 Bicep 文件:
- 添加连接到 OPC PLC 模拟器的资产终结点。
- 添加表示烤箱并定义烤箱公开的数据点的资产。
- 添加用于处理模拟烤箱的消息的数据流。
- 创建用于接收数据的 Azure 事件中心实例。
wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/quickstart.bicep -O quickstart.bicep
AIO_EXTENSION_NAME=$(az k8s-extension list -g $RESOURCE_GROUP --cluster-name $CLUSTER_NAME --cluster-type connectedClusters --query "[?extensionType == 'microsoft.iotoperations'].id" -o tsv | awk -F'/' '{print $NF}')
AIO_INSTANCE_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].name" -o tsv)
CUSTOM_LOCATION_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].extendedLocation.name" -o tsv | awk -F'/' '{print $NF}')
az deployment group create --subscription $SUBSCRIPTION_ID --resource-group $RESOURCE_GROUP --template-file quickstart.bicep --parameters clusterName=$CLUSTER_NAME customLocationName=$CUSTOM_LOCATION_NAME aioExtensionName=$AIO_EXTENSION_NAME aioInstanceName=$AIO_INSTANCE_NAME
查看配置
配置了以下资源的 Bicep 文件:
- 连接到 OPC PLC 模拟器的资产终结点。
- 表示烤箱并定义烤箱公开的数据点的资产。
- 用于处理模拟烤箱的消息的两个数据流。
- 包含数据流目标中心的 Azure 事件中心命名空间。
要查看资产终结点、资产和数据流,请导航到浏览器中的操作体验 UI,并使用 Microsoft Entra ID 凭据登录。 由于你正在使用新部署,因此还没有站点。 可以通过选择“未分配的实例”来查找在上一个快速入门中创建的群集。 在操作体验中,实例表示在其中部署了 Azure IoT 操作的群集。
资产终结点定义与 OPC PLC 模拟器的连接:
烤箱资产定义烤箱公开的数据点:
数据流定义如何处理来自模拟烤箱的消息并将其路由到云中的事件中心:
以下屏幕截图显示了如何配置温度转换数据流:
验证数据是否流向 MQTT 代理
使用 mosquitto_sub 工具验证数据是否流向 MQTT 代理。 在此示例中,你将在 Kubernetes 群集中运行 mosquitto_sub 工具:
运行以下命令来部署包含 mosquitto_pub 和 mosquitto_sub 工具的 Pod,这些工具可用于与群集中的 MQTT 代理交互:
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/mqtt-client.yaml
以下代码片段显示了已应用的 YAML 文件:
# Important: do not use in production environments # Creates a pod with mosquitto-clients and mqttui utilities in your cluster apiVersion: v1 kind: Pod metadata: name: mqtt-client # The namespace must match the IoT MQ BrokerListener's namespace # Otherwise use the long hostname: aio-broker.azure-iot-operations.svc.cluster.local namespace: azure-iot-operations spec: # Use the "mqtt-client" service account which comes with default deployment # Otherwise create it with `kubectl create serviceaccount mqtt-client -n azure-iot-operations` serviceAccountName: mqtt-client containers: # Install mosquitto and mqttui utilities on Alpine linux - image: alpine name: mqtt-client command: ["sh", "-c"] args: ["apk add mosquitto-clients mqttui && sleep infinity"] resources: limits: cpu: 500m memory: 200Mi requests: cpu: 100m memory: 100Mi volumeMounts: - name: broker-sat mountPath: /var/run/secrets/tokens - name: trust-bundle mountPath: /var/run/certs volumes: - name: broker-sat projected: sources: - serviceAccountToken: path: broker-sat audience: aio-internal # Must match audience in BrokerAuthentication expirationSeconds: 86400 - name: trust-bundle configMap: name: azure-iot-operations-aio-ca-trust-bundle # Default root CA cert
注意
此配置是不安全的。 请勿在生产环境中使用此配置。
运行 mqtt-client pod 时,请运行以下命令以在所创建的 Pod 中创建 shell 环境:
kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh
在 mqtt-client pod 中的 Bash shell 中,运行以下命令,使用订阅
data/thermostat
主题的 mosquitto_sub 工具连接到 MQTT 代理:mosquitto_sub --host aio-broker --port 18883 --topic "azure-iot-operations/data/#" -v --debug --cafile /var/run/certs/ca.crt -D CONNECT authentication-method 'K8S-SAT' -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)
此命令在到达
data/thermostat
主题时会继续运行并显示消息,直到按 Ctrl+C 停止它。 要退出 shell 环境,请键入exit
。
要验证添加的烤箱资产是否正在发布数据,请查看 azure-iot-operations/data
主题中的遥测数据:
Client $server-generated/05a22b94-c5a2-4666-9c62-837431ca6f7e received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/oven', ... (152 bytes))
{"temperature":{"SourceTimestamp":"2024-07-29T15:02:17.1858435Z","Value":4558},"Tag 10":{"SourceTimestamp":"2024-07-29T15:02:17.1858869Z","Value":4558}}
Client $server-generated/05a22b94-c5a2-4666-9c62-837431ca6f7e received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/oven', ... (152 bytes))
{"temperature":{"SourceTimestamp":"2024-07-29T15:02:18.1838125Z","Value":4559},"Tag 10":{"SourceTimestamp":"2024-07-29T15:02:18.1838523Z","Value":4559}}
Client $server-generated/05a22b94-c5a2-4666-9c62-837431ca6f7e received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/oven', ... (152 bytes))
{"temperature":{"SourceTimestamp":"2024-07-29T15:02:19.1834363Z","Value":4560},"Tag 10":{"SourceTimestamp":"2024-07-29T15:02:19.1834879Z","Value":4560}}
Client $server-generated/05a22b94-c5a2-4666-9c62-837431ca6f7e received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/oven', ... (152 bytes))
{"temperature":{"SourceTimestamp":"2024-07-29T15:02:20.1861251Z","Value":4561},"Tag 10":{"SourceTimestamp":"2024-07-29T15:02:20.1861709Z","Value":4561}}
Client $server-generated/05a22b94-c5a2-4666-9c62-837431ca6f7e received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/oven', ... (152 bytes))
{"temperature":{"SourceTimestamp":"2024-07-29T15:02:21.1856798Z","Value":4562},"Tag 10":{"SourceTimestamp":"2024-07-29T15:02:21.1857211Z","Value":4562}}
如果没有数据流,请重启 aio-opc-opc.tcp-1
Pod:
使用以下命令查找
aio-opc-opc.tcp-1
Pod 的名称:kubectl get pods -n azure-iot-operations
Pod 的名称类似于
aio-opc-opc.tcp-1-849dd78866-vhmz6
。使用类似于以下示例的命令重启
aio-opc-opc.tcp-1
Pod。 使用上一步中的aio-opc-opc.tcp-1
Pod 名称:kubectl delete pod aio-opc-opc.tcp-1-849dd78866-vhmz6 -n azure-iot-operations
本快速入门前面添加的示例资产可生成类似于以下示例的消息:
{
"Temperature":{
"SourceTimestamp":"2024-11-04T21:30:31.9454188Z",
"Value":357
},
"FillWeight":{
"SourceTimestamp":"2024-11-04T21:30:31.9455619Z",
"Value":357
},
"EnergyUse":{
"SourceTimestamp":"2024-11-04T21:30:31.9455641Z",
"Value":357
}
}
验证数据是否流向事件中心
要验证数据是否流向云,可以在 Azure 门户中查看事件中心实例。 可能需要等待几分钟才能启动数据流并让消息流向事件中心。
之前应用的 Bicep 配置创建了一个事件中心命名空间和被数据流用作目标的中心。 要查看该命名空间和中心,请导航到包含 IoT 操作实例的 Azure 门户中的资源组,然后选择事件中心命名空间。
如果消息流向实例,可以在实例“概述”页上看到传入消息的计数:
如果消息正在流动,则可以使用“数据资源管理器”查看消息:
提示
要查看消息,可能需要为自己分配事件中心命名空间的 Azure 事件中心数据接收方角色。
我们如何解决问题?
本快速入门使用 Bicep 文件配置了 Azure IoT 操作实例以及资产终结点、资产和数据流。 该配置处理并路由来自模拟烤箱的数据。 配置中的数据流将消息路由到 Azure 事件中心实例。
清理资源
如果继续学习下一个快速入门,请保留所有资源。
如果要移除 Azure IoT 操作部署但保留群集,请使用 az iot ops delete 命令:
az iot ops delete --cluster $CLUSTER_NAME --resource-group $RESOURCE_GROUP
如果要删除为此快速入门创建的所有资源,请删除部署 Azure IoT 操作的 Kubernetes 群集,然后移除包含该群集的 Azure 资源组。
如果使用了 Codespaces 来完成这些快速入门,请从 GitHub 中删除你的 Codespace。
下一步
若要了解如何生成 Microsoft Fabric 仪表板,以便从烤箱数据获取见解,请参阅教程:从已处理的数据中获取见解。