Condividi tramite


Esercitazione: Aggiungere asset OPC UA al cluster operazioni IoT di Azure

In questa esercitazione si aggiungono manualmente asset OPC UA al cluster operazioni IoT di Azure. Questi asset pubblicano messaggi nel broker MQTT nel cluster Operazioni di Azure IoT. In genere, un utente OT completa questi passaggi.

Un asset è un dispositivo fisico o un'entità logica che rappresenta un dispositivo, un computer, un sistema o un processo. Ad esempio, un asset fisico può essere una pompa, un motore, un serbatoio o una linea di produzione. Un asset logico definito può avere proprietà, trasmettere dati di telemetria o generare eventi.

I server OPC UA sono applicazioni software che comunicano con gli asset. Tag OPC UA sono punti dati esposti dai server OPC UA. I tag OPC UA possono fornire dati in tempo reale o cronologici sullo stato, le prestazioni, la qualità o la condizione degli asset.

In questa esercitazione si usa l'interfaccia utente Web dell'esperienza operativa per creare gli asset. È anche possibile usare l'Interfaccia della riga di comando di Azure per completare alcune di queste attività.

Prerequisiti

Istanza di Operazioni IoT di Azure distribuite in un cluster Kubernetes. Per creare un'istanza di , usare una delle operazioni seguenti per distribuire le operazioni di Azure IoT:

Per accedere all'interfaccia utente Web dell'esperienza operativa, è necessario un account MICROSOFT Entra ID con almeno autorizzazioni di collaboratore per il gruppo di risorse che contiene l'istanza di Kubernetes - Azure Arc . Per altre informazioni, vedere Interfaccia utente Web dell'esperienza operativa.

Se non diversamente specificato, è possibile eseguire i comandi della console in questa esercitazione in un ambiente Bash o PowerShell.

Quale problema risolveremo?

I dati esposti dai server OPC UA possono avere una struttura complessa e possono essere difficili da comprendere. Le operazioni di Azure IoT consentono di modellare gli asset OPC UA come tag, eventi e proprietà. Questa modellazione semplifica la comprensione dei dati e l'uso nei processi downstream, ad esempio il broker MQTT e i flussi di dati.

Distribuire il simulatore OPC PLC

Questa esercitazione usa il simulatore OPC PLC per generare dati di esempio. Per distribuire il simulatore OPC PLC, eseguire il comando seguente:

kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/opc-plc-deployment.yaml

Il frammento di codice seguente mostra il file YAML applicato:

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

Attenzione

Questa configurazione non è sicura. Non usare questa configurazione in un ambiente di produzione.

Accedere all'esperienza operativa

Per creare degli endpoint dell’asset, asset e sottoscrivere tag ed eventi OPC UA, usare l'esperienza operativa.

Passare all'esperienza operativa nel browser e accedere con le credenziali di Microsoft Entra ID.

Selezionare il sito

Un sito è una raccolta di istanze di Operazioni IoT di Azure. I siti raggruppano in genere le istanze in base alla posizione fisica e semplificano l'individuazione e la gestione degli asset da parte degli utenti OT. Un amministratore IT crea siti e assegna le istanze di Operazioni di Azure IoT. Poiché si usa una nuova distribuzione, non sono ancora presenti siti. È possibile trovare il cluster creato in precedenza selezionando Visualizza istanze non firmate. Nell'esperienza operativa un'istanza rappresenta un cluster in cui sono state distribuite le Operazioni di Azure IoT.

Screenshot che mostra il nodo delle istanze non assegnate nell'esperienza operativa.

Selezionare l'istanza

Selezionare l'istanza in cui sono state distribuite le operazioni di Azure IoT nell'esercitazione precedente:

Screenshot dell'elenco di istanze di Operazioni di Azure IoT.

Suggerimento

Se non vengono visualizzate istanze, potrebbe non trovarsi nel tenant di Microsoft Entra ID corretto. È possibile modificare il tenant dal menu in alto a destra nel portale.

Aggiungere un endpoint di asset

Quando sono state distribuite le Operazioni di Azure IoT nell'articolo precedente, è stato incluso un simulatore OPC PLC predefinito. In questo passaggio si aggiunge un endpoint dell’asset che consente di connettersi al simulatore OPC PLC.

Per aggiungere un endpoint di asset:

  1. Selezionare Endpoint asset e quindi Crea endpoint asset:

    Screenshot che mostra la pagina degli endpoint dell'asset nell'esperienza operativa.

  2. Immettere le informazioni sull'endpoint seguenti:

    Campo valore
    Nome endpoint dell’asset opc-ua-connector-0
    Server URL di OPC UA opc.tcp://opcplc-000000:50000
    Modalità di autenticazione utente Anonymous
  3. Per salvare la definizione, selezionare Crea.

    Questa configurazione distribuisce un nuovo endpoint dell’asset denominato opc-ua-connector-0 nel cluster. È possibile usare kubectl per visualizzare gli endpoint degli asset:

    kubectl get assetendpointprofile -n azure-iot-operations
    

Gestire le risorse

Dopo aver selezionato l'istanza nell'esperienza operativa, viene visualizzato l'elenco disponibile di asset nella pagina Asset. Se non sono ancora presenti asset, questo elenco è vuoto:

Screenshot dell'elenco di asset vuoti di Operazioni di Azure IoT.

Creazione di un cespite

Per creare un asset, selezionare Crea asset. Immettere quindi le informazioni seguenti sull'asset:

Campo valore
Endpoint dell’asset opc-ua-connector-0
Nome del cespite thermostat
Descrizione A simulated thermostat asset
Argomento MQTT predefinito azure-iot-operations/data/thermostat

Rimuovere le proprietà personalizzate esistenti e aggiungere le proprietà personalizzate seguenti. Prestare attenzione a usare i nomi di proprietà esatti, come modello di Power BI in una query successiva dell'esercitazione:

Nome della proprietà Dettagli proprietà
batch 102
Cliente Contoso
equipaggiamento Caldaia
isSpare true
location Seattle

Screenshot della pagina dei dettagli dell'asset di Operazioni di Azure IoT.

Selezionare Avanti per passare alla pagina Aggiungi tag.

Creare tag OPC UA

Aggiungere due tag OPC UA nella pagina Aggiungi tag. Per aggiungere ogni tag, selezionare Aggiungi tag o CSV e quindi selezionare Aggiungi tag. Immettere i dettagli del tag illustrati nella tabella seguente:

ID nodo Nome tag Modalità di osservabilità
ns=3;s=FastUInt10 temperatura None
ns=3;s=FastUInt100 Tag 10 None

La Modalità Osservabilità è uno dei valori seguenti: None, Gauge, Counter, Histogram o Log.

È possibile selezionare Gestisci impostazioni predefinite per modificare l'intervallo di campionamento predefinito e le dimensioni della coda per ogni tag.

Screenshot della pagina Aggiunta tag di Azure IoT Operations.

Selezionare Avanti per passare alla pagina Aggiungi eventi e quindi Avanti per passare alla pagina Revisione.

Revisione

Esaminare i dettagli dell'asset e del tag e apportare eventuali modifiche necessarie prima di selezionare Crea:

Screenshot della pagina di revisione dell'asset per la creazione di Operazioni di Azure IoT.

Questa configurazione distribuisce un nuovo asset chiamato thermostat nel cluster. È possibile usare kubectl per visualizzare gli asset:

kubectl get assets -n azure-iot-operations

Visualizzare le risorse nel portale di Azure

Per visualizzare l'endpoint dell'asset e l'asset creati nella portale di Azure, passare al gruppo di risorse che contiene l'istanza di Operazioni IoT di Azure. È possibile visualizzare l'asset termostato nel gruppo di risorse Operazioni IoT di Azure. Se si seleziona Mostra tipi nascosti, è anche possibile visualizzare l'endpoint dell'asset:

Screenshot di portale di Azure che mostra il gruppo di risorse Operazioni IoT di Azure, inclusi l'asset e l'endpoint dell'asset.

Il portale consente di visualizzare i dettagli dell'asset. Selezionare Visualizzazione JSON per altri dettagli:

Screenshot dei dettagli dell'asset operazioni IoT di Azure nel portale di Azure.

Verificare che i dati vengano trasmessi

Verificare che i dati vengano trasmessi al broker MQTT usando lo strumento mosquitto_sub. In questo esempio si esegue lo strumento mosquitto_sub all'interno del cluster Kubernetes:

  1. Eseguire il comando seguente per distribuire un pod che include gli strumenti mosquitto_pub e mosquitto_sub utili per interagire con il broker MQTT nel cluster:

    kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/mqtt-client.yaml
    

    Il frammento di codice seguente mostra il file YAML applicato:

    # 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
    

    Attenzione

    Questa configurazione non è sicura. Non usare questa configurazione in un ambiente di produzione.

  2. Quando il pod mqtt-client è in esecuzione, eseguire il comando seguente per creare un ambiente shell nel pod creato:

    kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh
    
  3. Nella shell Bash nel pod mqtt-client eseguire il comando seguente per connettersi al broker MQTT usando lo strumento mosquitto_sub sottoscritto all'argomento data/thermostat :

    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)
    

    Questo comando continua a essere eseguito e visualizza i messaggi quando arrivano nell'argomento data/thermostat finché non si preme CTRL+C per arrestarlo. Per uscire dall'ambiente della shell, digitare exit.

Per verificare che l'asset del termostato aggiunto stia pubblicando i dati, visualizzare i dati di telemetria nell'argomento 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}}

Se non è presente alcun flusso di dati, riavviare il pod aio-opc-opc.tcp-1:

  1. Trovare il nome del pod aio-opc-opc.tcp-1 usando il comando seguente:

    kubectl get pods -n azure-iot-operations
    

    Il nome del pod è simile a aio-opc-opc.tcp-1-849dd78866-vhmz6.

  2. Riavviare il pod aio-opc-opc.tcp-1 usando un comando simile all'esempio seguente. Usare il nome del pod aio-opc-opc.tcp-1 del passaggio precedente:

    kubectl delete pod aio-opc-opc.tcp-1-849dd78866-vhmz6 -n azure-iot-operations
    

I tag di esempio aggiunti nell'esercitazione precedente generano messaggi dall'asset simili all'esempio seguente:

{
    "temperature": {
        "SourceTimestamp": "2024-08-02T13:52:15.1969959Z",
        "Value": 2696
    },
    "Tag 10": {
        "SourceTimestamp": "2024-08-02T13:52:15.1970198Z",
        "Value": 2696
    }
}

Come abbiamo risolto il problema?

In questa esercitazione è stato aggiunto un endpoint di asset e quindi sono stati definiti un asset e tag. Gli asset e i tag modellano i dati del server OPC UA per semplificare l'uso dei dati in un broker MQTT e in altri processi downstream. Usare l'asset termostato definito nell'esercitazione successiva.

Pulire le risorse

Se si continua con l'esercitazione successiva, mantenere tutte le risorse.

Se si vuole rimuovere la distribuzione di Operazioni IoT di Azure ma mantenere il cluster, usare il comando az iot ops delete :

az iot ops delete --cluster $CLUSTER_NAME --resource-group $RESOURCE_GROUP

Per eliminare tutte le risorse create per questa guida introduttiva, eliminare il cluster Kubernetes in cui sono state distribuite le operazioni IoT di Azure e quindi rimuovere il gruppo di risorse di Azure che conteneva il cluster.

Se per questi argomenti della guida introduttiva è stato usato Codespaces, eliminare Codespace da GitHub.

Passaggio successivo

Esercitazione: Inviare dati di telemetria degli asset al cloud usando un flusso di dati.