教學:將 OPC UA 資產加入你的 Azure IoT 操作 叢集

在這個教學中,你要手動將 OPC UA 資產加入你的 Azure IoT 操作 叢集。 這些資產會將訊息發佈到你 Azure IoT 操作 叢集中的 MQTT 代理。 一般而言,OT 使用者會完成這些步驟。

資產是實體裝置或邏輯實體,代表裝置、機器、系統及流程。 例如,實體資產可以是泵、馬達、油箱或生產線。 您定義的邏輯資產可以有屬性、串流數據點或產生事件。

OPC UA 伺服器是與資產通訊的軟體應用程式。 OPC UA 標籤是 OPC UA 伺服器公開的資料點。 OPC UA 標籤可以提供資產狀態、效能、品質或條件的即時或歷程記錄資料。

在本教學課程中,您將使用操作體驗 Web UI 建立資產。 你也可以用Azure CLI來完成部分任務。

必要條件

一個啟用安全設定的 Azure IoT 操作 實例部署在 Kubernetes 叢集中。 要建立實例,請使用以下其中一種來部署 Azure IoT 操作:

這很重要

如果按照文章 快速入門:使用 K3s 在 GitHub Codespaces 中執行 Azure IoT 作業的步驟,您建立的實例無法啟用安全設定。

啟用安全設定後,包含你的 Azure IoT 操作 實例的資源群組也會包含以下資源:

  • 一個 Azure Key Vault 實例用來儲存要同步到 Kubernetes 叢集的機密資料。
  • 由使用者指派的託管身分,用以讓 Azure IoT 操作 存取 Azure Key Vault 實體。
  • 使用者指派的受管理身份可供 Azure IoT 操作 元件(例如資料流)使用,以連接至雲端端點(如 Azure 事件中樞)。
  • 一個 Azure 裝置登錄檔命名空間,用來儲存你的資產和裝置。

請確保在進行安全設定時,您已透過 金鑰保存庫 秘密管理者角色,將管理秘密的權限授予使用者帳戶。

要登入 Operations Experience 的網頁介面,你需要一個至少擁有資源群組貢獻者權限的 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 模擬器:

  1. 從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
    
  2. opc-plc-tutorial-deployment.yaml開啟您在文字編輯器中下載的檔案,並變更模擬器的密碼。 密碼是使用 --defaultpassword 參數來設定。 記下密碼值,您稍後需要此值。 然後,儲存您的變更。

  3. 若要將 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

若要將模擬器的憑證新增至連接器的信任清單:

  1. 請進入operations experience網頁介面,並以你的Microsoft Entra ID帳號登入。

  2. 選取您的網站。 如果您使用新的部署,就還不會有網站。 您可以選取 [檢視未指派的執行個體],找出您先前建立的叢集。 在營運體驗中,實例代表你部署 Azure IoT 操作 的叢集。

    顯示作業體驗中未指派實例節點的螢幕快照。

  3. 選擇你部署 Azure IoT 操作 的實例:

    實例清單截圖。Azure IoT 操作 實例清單截圖。

    提示

    如果看不到任何執行個體,可能是因為您不在正確的 Microsoft Entra ID 租用戶中。 您可以從操作體驗的右上方功能表變更租用戶。

  4. 選取 [裝置],然後選取 [管理憑證和秘密]:

    顯示如何在作業體驗中尋找 [管理憑證] 頁面的螢幕快照。

  5. 在 [憑證和秘密] 頁面上,選取 [新增憑證]:

    顯示如何將憑證新增至作業體驗中信任清單的螢幕快照。

  6. 選取 [上傳憑證],並選取 [OPC UA 信任清單] 作為憑證存放區,然後選擇您先前下載的 opcplc-000000.crt 檔案。 然後選取 [上傳]:

    顯示成功上傳憑證的螢幕快照。

  7. 選取 ,然後套用。

模擬器的應用程式實例憑證現在位於 OPC UA 信任清單的連接器中。

新增裝置

在此步驟中,您會使用操作體驗來新增裝置,以讓您連線至 OPC PLC 模擬器。 若要新增裝置:

  1. 選取 [裝置],然後選取 [建立新的]:

    顯示操作體驗中裝置頁面的螢幕擷取畫面。

  2. 輸入 opc-ua-connector 為裝置名稱,然後在 Microsoft.OpcUa 磚上選擇 New。

    螢幕擷取畫面:顯示如何在操作體驗中新增裝置。

  3. 輸入以下 Microsoft․OpcUa 入站端點資訊:

    欄位 值
    端點名稱 opc-ua-connector-0
    OPC UA 伺服器 URL opc.tcp://opcplc-000000:50000
    使用者驗證模式 Username password

在這個教學中,你會從 Operations Experience 的網頁介面為 Azure Key Vault 實例新增秘密。 秘密會自動同步至您的 Kubernetes 叢集:

  1. 若要新增使用者名稱參考,請選取 [ 新增參考],然後選取 [新建]。

  2. 輸入 plcusername 作為秘密名稱和 contosouser 秘密值。 接著選取套用。

  3. 若要新增密碼參考,請選取 [ 新增參考],然後選取 [新建]。

  4. 輸入 plcpassword 作為秘密名稱和您新增至 opc-plc-deployment.yaml 檔案的密碼作為秘密值。 接著選取套用。

  5. 在 [裝置詳細資料] 頁面上,選取 [下一步] 以移至 [其他資訊] 頁面。

  6. 在 [新增自訂屬性] 頁面上,您可以選擇性地更新或新增自訂屬性至裝置。 完成後,請選取 [下一步]。

  7. 若要在 [摘要] 頁面上儲存裝置定義,請選取 [建立]。

此設定會將新裝置部署至叢集,而此裝置稱為 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 命令來查看這些秘密。 您也可以在 [管理同步的秘密 ] 頁面上查看作業體驗中的秘密。

管理您的資產

在作業體驗中選取執行個體之後,您會在 [資產] 頁面上看到可用的資產清單。 如果還沒有資產,此清單會是空的:

Azure IoT 操作空資產清單截圖。

建立資產

若要建立資產,請選取 建立資產。 然後輸入下列資產資訊:

欄位 值
輸入端點 opc-ua-connector-0
資產名稱 thermostat
描述 A simulated thermostat asset

移除現有的 [自訂屬性],並新增下列自訂屬性。 務必使用精確的屬性名稱,因為後續教學中的 Power BI 範本會查詢這些名稱。

屬性名稱 屬性詳細資料
批次 102
客戶 Contoso
設備 樣板
isSpare 是
位置 西雅圖

Azure IoT 操作資產詳情頁面截圖。

選取 下一步 以移至 [資料集 ] 頁面。

建立資料集

若要建立資料集,請選取 建立資料集。 輸入下表中顯示的資料集詳細資料:

欄位 值
資料集名稱 thermostat
目的地 MQTT
主題 azure-iot-operations/data/thermostat

選取 建立並繼續以儲存資料集並前往資料點頁面。

提示

您可以選取 [管理預設設定] ,以變更每個資料點的預設取樣間隔和佇列大小。

建立 OPC UA 資料點

在 [ 資料點 ] 頁面上新增 OPC UA 資料點。 若要新增資料點,請選取 [ 新增資料點]。 輸入下表所示的資料點詳細資料:

數據源 資料點名稱
ns=3;s=SpikeData 溫度

這裏的資料來源值是特定 OPC UA 模擬器節點。 節點會在指定的範圍內產生隨機值,而且也有間歇性尖峰。

選取 [儲存]。

Azure IoT 操作新增資料點頁面的截圖。

選取 [ 下一步 ] 以移至 [事件群組 ] 頁面,然後選取 [ 下一步 ] 移至 [ 管理群組 ] 頁面,然後選取 [下一步 ] 移至 [ 檢閱 ] 頁面。

檢閱

在選取 [建立] 之前,請先檢閱您的資產和標籤詳細資料,並進行任何調整:

Azure IoT 操作建立資產評論頁面的截圖。

此設定會將名為 thermostat 的新資產部署至叢集。 您也可以使用 kubectl 在您的叢集本地檢視資產。

kubectl get assets.namespace -n azure-iot-operations

在 Azure 入口網站查看資源

要查看您在 Azure 入口網站中建立的裝置與資產,請前往 Azure 裝置登錄檔:

Azure入口網站截圖顯示Azure裝置登錄檔。

該入口網站可讓您瀏覽以下 Azure 裝置登錄資源:

  • 你可以查看你在前幾步建立的資產:thermostat。
  • 裝置:您可以查看在前幾步驟中建立的 opc-ua-connector 裝置。
  • 命名空間:你可以查看部署 Azure IoT 操作 時所建立的命名空間。 命名空間包含你在前幾步建立的資產和裝置。
  • 結構登錄:你可以查看建立資產時自動建立的結構登錄檔。

確認資料正在流動

使用 mosquitto_sub 工具,驗證資料流向 MQTT 代理程式。 在此範例中,您會在 Kubernetes 叢集內執行 mosquitto_sub 工具:

  1. 執行下列命令來部署 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
    

    注意

    此設定不安全。 請勿在實際執行環境中使用此設定。

  2. 當 mqtt-client Pod 執行時,請執行下列命令,在您所建立的 Pod 中建立殼層環境:

    kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh
    
  3. 在 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:

  1. 使用下列命令尋找 aio-opc-opc.tcp-1 Pod 的名稱:

    kubectl get pods -n azure-iot-operations
    

    您的 Pod 名稱看起來就像 aio-opc-opc.tcp-1-849dd78866-vhmz6。

  2. 使用類似下列範例的命令重新啟動 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 --name $AIO_INSTANCE_NAME --resource-group $RESOURCE_GROUP

如果你想刪除為這個快速入門建立的所有資源,請刪除你部署 Azure IoT 操作 的 Kubernetes 叢集,然後移除包含該叢集的 Azure 資源群組。

後續步驟

教學課程:使用數據流將訊息從您的資產傳送至雲端。