在本教學課程中,您會手動將 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 作業:
- 快速入門:使用 K3s 在 GitHub Codespaces 中執行 Azure IoT 操作提供了簡單的指示,據以部署可用於教學課程的 Azure IoT 操作執行個體。 然後,若要啟用安全設定,請遵循在 Azure IoT 作業中啟用安全設定中的步驟。
- 部署概觀提供使用 Azure Kubernetes Service 邊緣程式集在 Windows 上或使用 K3s 在 Ubuntu 上部署 Azure IoT 操作執行個體的詳細指示。 請遵循部署文章中的步驟,以進行安全設定部署,並安裝最新版本。
這很重要
如果您遵循 快速入門:使用 K3s 在 GitHub Codespaces 中執行 Azure IoT 作業 一文中的步驟,就無法在您建立的執行個體上啟用安全設定。
啟用安全設定之後,包含 Azure IoT Operations 實例的資源群組也會包含下列資源:
- 用來儲存秘密以同步處理至 Kubernetes 叢集的 Azure Key Vault 執行個體。
- 由使用者指派、供 Azure IoT 操作用來存取 Azure Key Vault 執行個體的受控識別。
- Azure IoT Operations 元件,例如數據流,可以使用使用者指派的受控識別來連接到像 Azure 事件中樞這樣的雲端端點。
- Azure 裝置登錄命名空間,用於儲存您的資產和裝置。
請確定當您設定安全設定時,請 授與用戶帳戶許可權,以 使用 Key Vault 秘密官員 角色來管理秘密。
若要登入操作體驗 Web UI,您需要至少具有資源群組參與者權限的 Microsoft Entra ID 帳戶,其中包含您的 Kubernetes - Azure Arc 執行個體。 若要深入了解,請參閱操作體驗 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.yamlopc-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"
- "--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: 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 PLC 模擬器可以將資料傳送至 OPC UA 的連接器之前,您需要在它們之間建立相互信任。 在本教學課程中,OPC PLC 模擬器和 OPC UA 連接器會使用自我簽署憑證來建立與 OPC UA 連接器的相互信任:
- 模擬器的應用程式實例憑證會儲存在 Kubernetes 秘密中
opc-plc-default-application-cert。 - OPC UA 應用程式實例憑證的連接器會儲存在 Kubernetes 秘密中
aio-opc-opcuabroker-default-application-cert。
這很重要
在實際執行環境中,使用企業級應用程式執行個體憑證來建立相互信任。 若要深入瞭解,請參閱 設定企業級應用程式實例憑證。
將連接器的憑證新增至模擬器的信任清單
每個 OPC UA 伺服器都有自己的管理信任清單的機制。 若要將連接器的憑證新增至模擬器的信任清單,請執行下列命令:
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}"
$cert = kubectl -n azure-iot-operations get secret aio-opc-opcuabroker-default-application-cert -o jsonpath='{.data.tls\.crt}' | %{ [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($_)) }
$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}"
將模擬器的憑證新增至連接器的信任清單
每個 OPC UA 伺服器類型都有自己的機制來管理其應用程式實例憑證。 若要將模擬器的憑證下載到名為 opcplc-000000.crt的檔案,請執行下列命令:
kubectl -n azure-iot-operations get secret opc-plc-default-application-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > opcplc-000000.crt
kubectl -n azure-iot-operations get secret opc-plc-default-application-cert -o jsonpath='{.data.tls\.crt}' | %{ [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($_)) } > opcplc-000000.crt
若要將模擬器的憑證新增至連接器的信任清單:
移至 作業體驗 Web UI,並使用您的 Microsoft Entra ID 認證登入。
選取您的網站。 如果您使用新的部署,就還不會有網站。 您可以選取 [檢視未指派的執行個體],找出您先前建立的叢集。 在操作體驗中,執行個體代表您部署 Azure IoT 操作的叢集。
選取您部署 Azure IoT 作業的實例:
提示
如果您沒有看到任何執行個體,您可能不在正確的 Microsoft Entra ID 租用戶中。 您可以從操作體驗的右上方功能表變更租用戶。
選取 [裝置],然後選取 [管理憑證和秘密]:
在 [憑證和秘密] 頁面上,選取 [新增憑證]:
選取 [上傳憑證],並選取 [OPC UA 信任清單] 作為憑證存放區,然後選擇您先前下載的
opcplc-000000.crt檔案。 然後選取 [上傳]:選取 ,然後套用。
模擬器的應用程式實例憑證現在位於 OPC UA 信任清單的連接器中。
新增裝置
在此步驟中,您會使用操作體驗來新增裝置,以讓您連線至 OPC PLC 模擬器。 若要新增裝置:
選取 [裝置],然後選取 [建立新的]:
輸入
opc-ua-connector作為裝置名稱,然後在 [Microsoft.OpcUa] 圖格上選取 [新增]:輸入下列 Microsoft.OpcUa 輸入端點資訊:
欄位 值 端點名稱 opc-ua-connector-0OPC UA 伺服器 URL opc.tcp://opcplc-000000:50000使用者驗證模式 Username password
在本教學課程中,您會從作業體驗 Web UI 將新的秘密新增至 Azure Key Vault 實例。 秘密會自動同步至您的 Kubernetes 叢集:
若要新增使用者名稱參考,請選取 [ 新增參考],然後選取 [新建]。
輸入
plcusername作為秘密名稱和contosouser秘密值。 接著選取套用。若要新增密碼參考,請選取 [ 新增參考],然後選取 [新建]。
輸入
plcpassword作為秘密名稱和您新增至 opc-plc-deployment.yaml 檔案的密碼作為秘密值。 接著選取套用。在 [裝置詳細資料] 頁面上,選取 [下一步] 以移至 [其他資訊] 頁面。
在 [新增自訂屬性] 頁面上,您可以選擇性地更新或新增自訂屬性至裝置。 完成後,請選取 [下一步]。
若要在 [摘要] 頁面上儲存裝置定義,請選取 [建立]。
此設定會將新裝置部署至叢集,而此裝置稱為 opc-ua-connector 且具有稱為 opc-ua-connector-0 的端點。 您可以在 Azure 入口網站中檢視裝置,也可以使用 kubectl 來檢視 Kubernetes 叢集中的裝置:
kubectl get device -n azure-iot-operations
您可以在資源群組的 Azure Key Vault 實例中看到 plcusername 和 plcpassword 秘密。 秘密會同步至 Kubernetes 叢集,您可以在其中使用 kubectl get secret -n azure-iot-operations 命令來查看這些秘密。 您也可以在 [管理同步的秘密 ] 頁面上查看作業體驗中的秘密。
管理您的資產
在作業體驗中選取執行個體之後,您會在 [資產] 頁面上看到可用的資產清單。 如果還沒有資產,此清單會是空的:
建立資產
若要建立資產,請選取 建立資產。 然後輸入下列資產資訊:
| 欄位 | 值 |
|---|---|
| 輸入端點 | opc-ua-connector-0 |
| 資產名稱 | thermostat |
| 描述 | A simulated thermostat asset |
移除現有的 [自訂屬性],並新增下列自訂屬性。 請務必使用確切的屬性名稱,如後續教學課程中的 Power BI 範本會加以查詢:
| 屬性名稱 | 屬性詳細資料 |
|---|---|
| 批次 | 102 |
| 客戶 | Contoso |
| 設備 | 樣板 |
| isSpare | 是 |
| 位置 | 西雅圖 |
選取 下一步 以移至 [資料集 ] 頁面。
建立資料集
若要建立資料集,請選取 建立資料集。 輸入下表中顯示的資料集詳細資料:
| 欄位 | 值 |
|---|---|
| 資料集名稱 | thermostat |
| 目的地 | MQTT |
| 主題 | azure-iot-operations/data/thermostat |
選取 建立並繼續以儲存資料集並前往資料點頁面。
提示
您可以選取 [管理預設設定] ,以變更每個資料點的預設取樣間隔和佇列大小。
建立 OPC UA 資料點
在 [ 資料點 ] 頁面上新增 OPC UA 資料點。 若要新增資料點,請選取 [ 新增資料點]。 輸入下表所示的資料點詳細資料:
| 數據源 | 資料點名稱 |
|---|---|
| ns=3;s=SpikeData | 溫度 |
這裏的資料來源值是特定 OPC UA 模擬器節點。 節點會在指定的範圍內產生隨機值,而且也有間歇性尖峰。
選取 [儲存]。
選取 [ 下一步 ] 以移至 [事件群組 ] 頁面,然後選取 [ 下一步 ] 移至 [ 管理群組 ] 頁面,然後選取 [下一步 ] 移至 [ 檢閱 ] 頁面。
檢閱
在選取 [建立] 之前,請先檢閱您的資產和標籤詳細資料,並進行任何調整:
此設定會將名為 thermostat 的新資產部署至叢集。 您也可以使用 kubectl 在您的叢集本地檢視資產。
kubectl get assets.namespace -n azure-iot-operations
檢視 Azure 入口網站中的資源
若要檢視您已在 Azure 入口網站中建立的裝置和資產,請移至 [Azure 裝置登錄檔]:
入口網站可讓您檢視資產詳細資料。 如需詳細資訊,請選取 [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 Shell 上,執行下列指令,以使用 mosquitto_sub 工具連線至 MQTT 代理程式,並使用萬用字元來訂閱
data/#主題: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/#主題時繼續執行並顯示訊息,直到您按 Ctrl+C 將其停止。 若要結束殼層環境,請輸入exit。
若要確認您新增的控溫器資產正在發佈數據,請檢視主題中的 azure-iot-operations/data/thermostat 訊息:
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-1Pod 的名稱:kubectl get pods -n azure-iot-operations您的 Pod 名稱看起來就像
aio-opc-opc.tcp-1-849dd78866-vhmz6。使用類似下列範例的命令重新啟動
aio-opc-opc.tcp-1Pod。 使用上一個步驟中的aio-opc-opc.tcp-1Pod 名稱: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。