教學課程:將 OPC UA 資產新增至 Azure IoT 作業叢集
在本教學課程中,您會手動將 OPC UA 資產新增至 Azure IoT 作業叢集。 這些資產會將訊息發佈至 Azure IoT 操作叢集中的 MQTT 代理程式。 一般而言,OT 使用者會完成這些步驟。
資產是實體裝置或邏輯實體,代表裝置、機器、系統及流程。 例如,實體資產可以是泵、馬達、油箱或生產線。 您定義的邏輯資產可以有屬性、串流遙測資料或產生事件。
OPC UA 伺服器是與資產通訊的軟體應用程式。 OPC UA 標籤是 OPC UA 伺服器公開的資料點。 OPC UA 標記可以提供資產狀態、效能、品質或條件的即時或歷程記錄資料。
在本教學課程中,您會使用作業體驗Web UI來建立資產。 您也可以使用 Azure CLI 來完成其中一些工作。
必要條件
部署在 Kubernetes 叢集中的 Azure IoT 作業實例。 若要建立實例,請使用下列其中一項來部署 Azure IoT 作業:
- 快速入門:使用 K3 在 GitHub Codespaces 中執行 Azure IoT 作業提供簡單的指示,以部署可用於教學課程的 Azure IoT 作業實例。
- 部署概觀 提供使用 Azure Kubernetes Service Edge Essentials 或 Ubuntu 使用 K3 在 Windows 上部署 Azure IoT 作業實例的詳細指示。
若要登入作業體驗 Web UI,您需要至少具有包含 Kubernetes - Azure Arc 實例之資源群組參與者許可權的 Microsoft Entra ID 帳戶。 若要深入瞭解,請參閱 作業體驗Web UI。
除非另有說明,否則您可以在Bash或PowerShell環境中執行本教學課程中的控制台命令。
我們會解決什麼問題?
OPC UA 伺服器公開的資料可能會有複雜的結構,而且可能難以理解。 Azure IoT 操作提供將 OPC UA 資產模型化為標籤、事件及屬性的方法。 此模型化可讓您更輕鬆地了解數據,並將其用於下游程式,例如 MQTT 訊息代理程式和數據流。
部署 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 標籤和事件,請使用作業體驗。
瀏覽至瀏覽器中的作業體驗,並使用您的 Microsoft Entra ID 認證登入。
選取網站
網站是 Azure IoT 操作執行個體的集合。 站台通常會依實體位置將執行個體分組,並讓 OT 使用者更容易找出和管理資產。 IT 系統管理員會建立站台並將 Azure IoT 操作執行個體指派給他們。 因為您正在使用新的部署,因此還沒有網站。 您可以選取 [檢視未指派的實例],找到您在先前建立的叢集。 在作業體驗中,執行個體代表您部署 Azure IoT 操作的叢集。
選取您的執行個體
選取您在上一個教學課程中部署 Azure IoT 作業的實例:
提示
如果您沒有看到任何執行個體,您可能不在正確的 Microsoft Entra ID 租用戶中。 您可以從操作體驗的右上方功能表變更租用戶。
新增資產端點
當您在上一篇文章中部署 Azure IoT 操作時,包含內建 OPC PLC 模擬器。 在此步驟中,您會新增資產端點,讓您能夠連線到 OPC PLC 模擬器。
若要新增資產端點:
選取 [資產端點],然後選取 [建立資產端點]:
輸入下列端點資訊:
欄位 值 資產端點名稱 opc-ua-connector-0
OPC UA 伺服器 URL opc.tcp://opcplc-000000:50000
使用者驗證模式 Anonymous
若要儲存定義,請選取 [建立]。
此設定會將名為
opc-ua-connector-0
的新資產端點部署到叢集。 您可以使用kubectl
來檢視資產端點:kubectl get assetendpointprofile -n azure-iot-operations
管理您的資產
在作業體驗中選取執行個體之後,您會在 [資產] 頁面上看到可用的資產清單。 如果還沒有資產,此清單會是空的:
建立資產
若要建立資產,請選取 [建立資產]。 然後輸入下列資產資訊:
欄位 | 值 |
---|---|
資產端點 | opc-ua-connector-0 |
資產名稱 | thermostat |
描述 | A simulated thermostat asset |
預設 MQTT 主題 | azure-iot-operations/data/thermostat |
移除現有的 [自訂屬性],並新增下列自訂屬性。 請小心使用確切的屬性名稱,因為稍後的教學課程會查詢這些名稱:
屬性名稱 | 屬性詳細資料 |
---|---|
batch | 102 |
客戶 | Contoso |
設備 | 樣板 |
isSpare | true |
location | 西雅圖 |
選取 [下一步] 以移至 [新增標籤] 頁面。
建立 OPC UA 標籤
在 [新增標籤] 頁面上新增兩個 OPC UA 標籤。 若要新增每個標籤,請選取 [新增標籤或 CSV],然後選取 [新增標籤]。 輸入下表所示的標籤詳細資料:
節點識別碼 | 標籤名稱 | 可檢視模式 |
---|---|---|
ns=3;s=FastUInt10 | 溫度 | 無 |
ns=3;s=FastUInt100 | 標籤 10 | 無 |
可檢視性模式是下列其中一個值:None
、Gauge
、Counter
、Histogram
或 Log
。
您可以選取 [管理預設設定],以變更每個標籤的預設取樣間隔和佇列大小。
選取 [下一步] 以移至 [新增事件] 頁面,然後 [下一步] 移至 [檢閱] 頁面。
檢閱
在選取 [建立] 之前,請先檢閱您的資產和標籤詳細資料,並進行任何調整:
此組態會將名為 thermostat
的新資產部署到叢集。 您可以使用 kubectl
來檢視資產:
kubectl get assets -n azure-iot-operations
檢視 Azure 入口網站 中的資源
若要檢視您在 Azure 入口網站 中建立的資產端點和資產,請移至包含 Azure IoT Operations 實例的資源群組。 您可以在 Azure IoT Operations 資源群組中看到控溫器資產。 如果您選取 [ 顯示隱藏類型],您也可以看到資產端點:
入口網站可讓您檢視資產詳細數據。 如需詳細資訊,請選取 [JSON 檢視 ]:
確認資料正在流動
使用 mosquitto_sub 工具,驗證資料流向 MQTT 代理程式。 在此範例中,您會在 Kubernetes 叢集內執行 mosquitto_sub 工具:
執行下列命令來部署 Pod,其中包含 mosquitto_pub 和 mosquitto_sub 工具,這些工具有助於與叢集中的 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 # Create a service account apiVersion: v1 kind: ServiceAccount metadata: name: mqtt-client namespace: azure-iot-operations --- # 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 中建立殼層環境:
kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh
在 mqtt-client Pod 中的 Bash 殼層上,執行下列命令,以使用訂閱
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 將其停止。 若要結束殼層環境,請輸入exit
。
若要確認您新增的控溫器資產正在發佈資料,請檢視 azure-iot-operations/data
主題中的遙測資料:
Client $server-generated/05a22b94-c5a2-4666-9c62-837431ca6f7e received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/thermostat', ... (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/thermostat', ... (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/thermostat', ... (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/thermostat', ... (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/thermostat', ... (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-08-02T13:52:15.1969959Z",
"Value": 2696
},
"Tag 10": {
"SourceTimestamp": "2024-08-02T13:52:15.1970198Z",
"Value": 2696
}
}
我們如何解決問題?
在本教學課程中,您已新增資產端點,然後定義資產和標記。 OPC UA 伺服器的資產和標籤模型資料,讓資料更容易用於 MQTT 代理和其他下游流程。 您會使用您在下一個教學課程中定義的控溫器資產。
清除資源
如果您繼續進行下一個教學課程,請保留所有資源。
如果您想要移除 Azure IoT 作業部署,但保留叢集,請使用 az iot ops delete 命令:
az iot ops delete --cluster $CLUSTER_NAME --resource-group $RESOURCE_GROUP
如果您想要刪除您為此快速入門建立的所有資源,請刪除您已部署 Azure IoT 作業的 Kubernetes 叢集,然後移除包含叢集的 Azure 資源群組。
如果您在這些快速入門中使用 Codespaces,請從 GitHub 刪除您的 Codespace。
後續步驟
教學課程:使用數據流將資產遙測傳送至雲端。