在本教學課程中,您會手動將 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 IoT 作業中啟用安全設定中的步驟。
- 部署概觀 提供使用 Azure Kubernetes Service Edge Essentials 或 Ubuntu 使用 K3 在 Windows 上部署 Azure IoT 作業實例的詳細指示。 請依照部署文章中的步驟進行安全設定部署。
啟用安全設定之後,包含 Azure IoT Operations 實例的資源群組也會包含下列資源:
- 用來儲存秘密以同步處理至 Kubernetes 叢集的 Azure Key Vault 實例。
- Azure IoT 作業使用的使用者指派的受控識別,以存取 Azure Key Vault 實例。
- Azure IoT Operations 元件,例如數據流,可以使用使用者指派的受控識別來連接到像 Azure 事件中樞這樣的雲端端點。
請確定當您設定安全設定時,請 授與用戶帳戶許可權,以 使用 Key Vault 秘密官員 角色來管理秘密。
若要登入作業體驗 Web UI,您需要至少具有包含 Kubernetes - Azure Arc 實例之資源群組參與者許可權的 Microsoft Entra ID 帳戶。 若要深入瞭解,請參閱 作業體驗Web UI。
除非另有說明,否則您可以在Bash或PowerShell環境中執行本教學課程中的控制台命令。
我們會解決什麼問題?
OPC UA 伺服器公開的資料可能會有複雜的結構,而且可能難以理解。 Azure IoT 操作提供將 OPC UA 資產模型化為標籤、事件及屬性的方法。 此模型化可讓您更輕鬆地了解數據,並將其用於下游程式,例如 MQTT 訊息代理程式和數據流。
本教學課程也會說明如何使用儲存在 Azure Key Vault 中的認證向模擬 OPC UA 伺服器進行驗證。
部署 OPC PLC 模擬器
本教學課程使用 OPC PLC 模擬器來產生範例數據。 若要部署 OPC PLC 模擬器:
從 GitHub 存放庫下載 opc-plc-tutorial-deployment.yaml 檔案。 若要使用命令列下載,請執行下列命令:
wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/refs/heads/main/samples/quickstarts/opc-plc-tutorial-deployment.yaml -O opc-plc-tutorial-deployment.yaml
opc-plc-tutorial-deployment.yaml
開啟您在文字編輯器中下載的檔案,並變更模擬器的密碼。 密碼是使用--defaultpassword
參數來設定。 記下密碼值,您稍後需要此值。 然後,儲存您的變更。若要將 OPC PLC 模擬器部署到您的叢集,請執行下列命令:
kubectl apply -f opc-plc-tutorial-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:
- "--plchostname=opcplc-000000"
- "--portnum=50000"
- "--certdnsnames=opcplc-000000"
- "--unsecuretransport"
- "--showpnjsonph"
- "--slownodes=5"
- "--slowrate=10"
- "--fastnodes=10"
- "--fasttypelowerbound=212"
- "--fasttypeupperbound=273"
- "--fasttyperandomization=True"
- "--veryfastrate=1000"
- "--guidnodes=1"
- "--appcertstoretype=FlatDirectory"
- "--dontrejectunknownrevocationstatus"
- "--disableanonymousauth"
- "--defaultuser=contosouser"
- "--defaultpassword=contosouserpassword"
ports:
- containerPort: 50000
volumeMounts:
- name: opc-plc-default-application-cert
mountPath: /app/pki/own
- name: opc-plc-trust-list
mountPath: /app/pki/trusted
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
serviceAccountName: opcplc-000000-service-account
---
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
檢查 YAML 檔案中的組態,以了解 OPC PLC 模擬器與 OPC UA 連接器之間的相互信任如何建立。
登入作業體驗
若要建立資產端點、資產及訂閱 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
使用者驗證模式 Username password
同步的秘密名稱 plc-credentials
在本教學課程中,您會從作業體驗 Web UI 將新的秘密新增至 Azure Key Vault 實例。 秘密會自動同步至您的 Kubernetes 叢集:
若要新增使用者名稱參考,請選取 [ 新增參考],然後選取 [新建]。
輸入
plcusername
作為秘密名稱和contosouser
秘密值。 接著選取套用。若要新增密碼參考,請選取 [ 新增參考],然後選取 [新建]。
輸入
plcpassword
作為秘密名稱和您新增至 opc-plc-deployment.yaml 檔案的密碼作為秘密值。 接著選取套用。若要儲存資產端點定義,請選取 [ 建立]。
此設定會將名為 opc-ua-connector-0
的新資產端點部署到叢集。 您可以在 Azure 入口網站中檢視資產端點,或使用 kubectl
來檢視 Kubernetes 叢集中的資產端點:
kubectl get assetendpointprofile -n azure-iot-operations
您可以在資源群組的 Azure Key Vault 實例中看到 plcusername
和 plcpassword
秘密。 秘密會同步至 Kubernetes 叢集,您可以在其中使用 kubectl get secret plc-credentials -n azure-iot-operations
命令來查看這些秘密。 您也可以在 [管理同步的秘密 ] 頁面上查看作業體驗中的秘密。
管理您的資產
在作業體驗中選取執行個體之後,您會在 [資產] 頁面上看到可用的資產清單。 如果還沒有資產,此清單會是空的:
建立資產
若要建立資產,請選取 [建立資產]。 然後輸入下列資產資訊:
欄位 | 值 |
---|---|
資產端點 | opc-ua-connector-0 |
資產名稱 | thermostat |
描述 | A simulated thermostat asset |
預設 MQTT 主題 | azure-iot-operations/data/thermostat |
移除現有的 [自訂屬性],並新增下列自訂屬性。 請小心使用確切的屬性名稱,因為稍後的教學課程會查詢這些名稱:
屬性名稱 | 屬性詳細資料 |
---|---|
批次 | 102 |
客戶 | Contoso |
設備 | 樣板 |
isSpare | 是 |
地點 | 西雅圖 |
選取 [下一步] 以移至 [新增標籤] 頁面。
建立 OPC UA 標籤
在 [新增標籤] 頁面上新增兩個 OPC UA 標籤。 若要新增每個標籤,請選取 [新增標籤或 CSV],然後選取 [新增標籤]。 輸入下表所示的標籤詳細資料:
節點識別碼 | 標籤名稱 | 可檢視模式 |
---|---|---|
ns=3;s=SpikeData | 溫度 | 無 |
此處的節點識別碼專屬於 OPC UA 模擬器。 節點會在指定的範圍內產生隨機值,而且也有間歇性尖峰。
可檢視性模式是下列其中一個值:None
、Gauge
、Counter
、Histogram
或 Log
。
您可以選取 [管理預設設定],以變更每個標籤的預設取樣間隔和佇列大小。
選取 [下一步] 以移至 [新增事件] 頁面,然後 [下一步] 移至 [檢閱] 頁面。
檢閱
在選取 [建立] 之前,請先檢閱您的資產和標籤詳細資料,並進行任何調整:
此組態會將名為 thermostat
的新資產部署到叢集。 您可以在 Azure 入口網站中檢視資源群組中的資產。 您也可以使用 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
工具連線到 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/0000aaaa-11bb-cccc-dd22-eeeeee333333 received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/thermostat', ... (92 bytes))
azure-iot-operations/data/thermostat {"temperature":{"SourceTimestamp":"2025-02-14T11:27:44.5030912Z","Value":48.17536741017152}}
Client $server-generated/0000aaaa-11bb-cccc-dd22-eeeeee333333 received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/thermostat', ... (90 bytes))
azure-iot-operations/data/thermostat {"temperature":{"SourceTimestamp":"2025-02-14T11:27:45.50333Z","Value":98.22872507286887}}
Client $server-generated/0000aaaa-11bb-cccc-dd22-eeeeee333333 received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/thermostat', ... (92 bytes))
azure-iot-operations/data/thermostat {"temperature":{"SourceTimestamp":"2025-02-14T11:27:46.503381Z","Value":12.533323356430426}}
如果沒有資料流程,請重新啟動 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":{
"Value":24.86898871648548,
"SourceTimestamp":"2025-04-25T14:50:07.195274Z"
}
}
我們如何解決問題?
在本教學課程中,您已新增資產端點,然後定義資產和標記。 OPC UA 伺服器的資產和標籤模型資料,讓資料更容易用於 MQTT 代理和其他下游流程。
您使用儲存在 Azure Key Vault 中的認證向 OPC UA 伺服器進行驗證。 這種方法比資產定義中的硬式編碼認證更安全。
您會使用您在下一個教學課程中定義的控溫器資產。
清除資源
如果您繼續進行下一個教學課程,請保留所有資源。
如果您想要移除 Azure IoT 作業部署,但保留叢集,請使用 az iot ops delete 命令:
az iot ops delete --cluster $CLUSTER_NAME --resource-group $RESOURCE_GROUP
如果您想要刪除您為此快速入門建立的所有資源,請刪除您已部署 Azure IoT 作業的 Kubernetes 叢集,然後移除包含叢集的 Azure 資源群組。
如果您在這些快速入門中使用 Codespaces,請從 GitHub 刪除您的 Codespace。