Udostępnij za pośrednictwem


Samouczek: dodawanie zasobów OPC UA do klastra operacji usługi Azure IoT

W tym samouczku ręcznie dodasz zasoby OPC UA do klastra operacji usługi Azure IoT. Te zasoby publikują komunikaty w brokerze MQTT w klastrze operacji usługi Azure IoT. Zazwyczaj użytkownik OT wykonuje te kroki.

Zasób to urządzenie fizyczne lub jednostka logiczna reprezentująca urządzenie, maszynę, system lub proces. Na przykład zasób fizyczny może być pompą, silnikiem, zbiornikiem lub linią produkcyjną. Zdefiniowany zasób logiczny może mieć właściwości, przesyłać strumieniowo dane telemetryczne lub generować zdarzenia.

Serwery OPC UA to aplikacje oprogramowania komunikujące się z elementami zawartości. Tagi OPC UA to punkty danych uwidaczniane przez serwery OPC UA. Tagi OPC UA mogą udostępniać dane historyczne dotyczące stanu, wydajności, jakości lub stanu zasobów w czasie rzeczywistym.

W tym samouczku użyjesz internetowego interfejsu użytkownika środowiska operacji do utworzenia zasobów. Możesz również użyć interfejsu wiersza polecenia platformy Azure, aby wykonać niektóre z tych zadań.

Wymagania wstępne

Wystąpienie operacji usługi Azure IoT wdrożone w klastrze Kubernetes. Aby utworzyć wystąpienie, użyj jednego z następujących elementów, aby wdrożyć operacje usługi Azure IoT:

Aby zalogować się do internetowego interfejsu użytkownika środowiska operacji, musisz mieć konto Microsoft Entra ID z co najmniej uprawnieniami współautora dla grupy zasobów zawierającej wystąpienie usługi Kubernetes — Azure Arc . Aby dowiedzieć się więcej, zobacz Interfejs użytkownika sieci Web środowiska operacji.

O ile nie określono inaczej, możesz uruchomić polecenia konsoli w tym samouczku w środowisku powłoki Bash lub programu PowerShell.

Jaki problem rozwiążemy?

Dane udostępniane przez serwery OPC UA mogą mieć złożoną strukturę i mogą być trudne do zrozumienia. Operacje usługi Azure IoT umożliwiają modelowanie zasobów OPC UA jako tagów, zdarzeń i właściwości. Modelowanie ułatwia zrozumienie danych i używanie ich w procesach podrzędnych, takich jak broker MQTT i przepływy danych.

Wdrażanie symulatora OPC PLC

W tym samouczku jest używany symulator OPC PLC do generowania przykładowych danych. Aby wdrożyć symulator OPC PLC, uruchom następujące polecenie:

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

Poniższy fragment kodu przedstawia zastosowany plik 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

Uwaga

Ta konfiguracja nie jest bezpieczna. Nie używaj tej konfiguracji w środowisku produkcyjnym.

Logowanie do środowiska operacji

Aby utworzyć punkty końcowe zasobów, zasoby i subskrybować tagi i zdarzenia OPC UA, użyj środowiska operacji.

Przejdź do środowiska operacji w przeglądarce i zaloguj się przy użyciu poświadczeń identyfikatora Entra firmy Microsoft.

Wybierz witrynę

Witryna to zbiór wystąpień operacji usługi Azure IoT. Witryny zazwyczaj grupują wystąpienia według lokalizacji fizycznej i ułatwiają użytkownikom OT lokalizowanie zasobów i zarządzanie nimi. Administrator IT tworzy lokacje i przypisuje do nich wystąpienia operacji usługi Azure IoT. Ponieważ pracujesz z nowym wdrożeniem, nie ma jeszcze żadnych witryn. Klaster utworzony wcześniej można znaleźć, wybierając pozycję Wyświetl nieprzypisane wystąpienia. W środowisku operacji wystąpienie reprezentuje klaster, w którym wdrożono operacje usługi Azure IoT.

Zrzut ekranu przedstawiający węzeł nieprzypisane wystąpienia w środowisku operacji.

Wybierz wystąpienie

Wybierz wystąpienie, w którym wdrożono operacje usługi Azure IoT w poprzednim samouczku:

Zrzut ekranu przedstawiający listę wystąpień operacji usługi Azure IoT.

Napiwek

Jeśli nie widzisz żadnych wystąpień, być może nie jesteś we właściwej dzierżawie identyfikatora Entra firmy Microsoft. Dzierżawę można zmienić z menu w prawym górnym rogu w środowisku operacji.

Dodawanie punktu końcowego zasobu

Po wdrożeniu operacji usługi Azure IoT w poprzednim artykule dołączono wbudowany symulator OPC PLC. W tym kroku dodasz punkt końcowy zasobu, który umożliwia nawiązywanie połączenia z symulatorem OPC PLC.

Aby dodać punkt końcowy zasobu:

  1. Wybierz pozycję Punkty końcowe zasobu, a następnie pozycję Utwórz punkt końcowy zasobu:

    Zrzut ekranu przedstawiający stronę punktów końcowych zasobu w środowisku operacji.

  2. Wprowadź następujące informacje o punkcie końcowym:

    Pole Wartość
    Nazwa punktu końcowego zasobu opc-ua-connector-0
    Adres URL serwera OPC UA opc.tcp://opcplc-000000:50000
    Tryb uwierzytelniania użytkownika Anonymous
  3. Aby zapisać definicję, wybierz pozycję Utwórz.

    Ta konfiguracja umożliwia wdrożenie nowego punktu końcowego zasobu wywoływanego opc-ua-connector-0 w klastrze. Możesz użyć kubectl polecenia , aby wyświetlić punkty końcowe zasobu:

    kubectl get assetendpointprofile -n azure-iot-operations
    

Zarządzanie zasobami

Po wybraniu wystąpienia w środowisku operacji zostanie wyświetlona lista dostępnych zasobów na stronie Zasoby . Jeśli jeszcze nie ma żadnych zasobów, ta lista jest pusta:

Zrzut ekranu przedstawiający pustą listę elementów zawartości operacji usługi Azure IoT.

Tworzenie składnika majątku

Aby utworzyć zasób, wybierz pozycję Utwórz zasób. Następnie wprowadź następujące informacje o zasobie:

Pole Wartość
Punkt końcowy elementu zawartości opc-ua-connector-0
Nazwa zasobu thermostat
opis A simulated thermostat asset
Domyślny temat MQTT azure-iot-operations/data/thermostat

Usuń istniejące właściwości niestandardowe i dodaj następujące właściwości niestandardowe. Zachowaj ostrożność, aby używać dokładnych nazw właściwości, ponieważ szablon usługi Power BI w późniejszym samouczku wykonuje dla nich zapytania:

Nazwa właściwości Szczegóły właściwości
batch 102
klient Contoso
indywidualnej Kocioł
isSpare prawda
lokalizacja Seattle

Zrzut ekranu przedstawiający stronę szczegółów zasobu operacji usługi Azure IoT.

Wybierz przycisk Dalej , aby przejść do strony Dodawanie tagów .

Tworzenie tagów OPC UA

Dodaj dwa tagi OPC UA na stronie Dodawanie tagów . Aby dodać każdy tag, wybierz pozycję Dodaj tag lub csv , a następnie wybierz pozycję Dodaj tag. Wprowadź szczegóły tagu pokazane w poniższej tabeli:

Identyfikator węzła Nazwa tagu Tryb obserwacji
ns=3; s=FastUInt10 temperature Brak
ns=3; s=FastUInt100 Tag 10 Brak

Tryb obserwacji jest jedną z następujących wartości: None, , CounterGauge, Histogramlub Log.

Możesz wybrać pozycję Zarządzaj ustawieniami domyślnymi, aby zmienić domyślny interwał próbkowania i rozmiar kolejki dla każdego tagu.

Zrzut ekranu przedstawiający stronę dodawania tagu operacje usługi Azure IoT.

Wybierz przycisk Dalej, aby przejść do strony Dodawanie zdarzeń, a następnie przycisk Dalej, aby przejść do strony Przegląd.

Wykonaj przegląd

Przed wybraniem pozycji Utwórz przejrzyj szczegóły zasobu i tagu i wprowadź potrzebne zmiany:

Zrzut ekranu przedstawiający stronę tworzenia zasobów operacji usługi Azure IoT.

Ta konfiguracja wdraża nowy zasób wywoływany thermostat w klastrze. Możesz użyć kubectl polecenia , aby wyświetlić zasoby:

kubectl get assets -n azure-iot-operations

Wyświetlanie zasobów w witrynie Azure Portal

Aby wyświetlić punkt końcowy i zasób zasobu utworzony w witrynie Azure Portal, przejdź do grupy zasobów zawierającej wystąpienie operacji usługi Azure IoT. Zasób termostatu można zobaczyć w grupie zasobów Operacje usługi Azure IoT. Jeśli wybierzesz pozycję Pokaż ukryte typy, możesz również zobaczyć punkt końcowy elementu zawartości:

Zrzut ekranu witryny Azure Portal przedstawiający grupę zasobów Operacje usługi Azure IoT, w tym punkt końcowy zasobu i zasobu.

Portal umożliwia wyświetlanie szczegółów zasobu. Wybierz widok JSON, aby uzyskać więcej szczegółów:

Zrzut ekranu przedstawiający szczegóły zasobu operacji usługi Azure IoT w witrynie Azure Portal.

Sprawdzanie, czy dane przepływają

Sprawdź, czy dane przepływają do brokera MQTT przy użyciu narzędzia mosquitto_sub . W tym przykładzie uruchomisz narzędzie mosquitto_sub w klastrze Kubernetes:

  1. Uruchom następujące polecenie, aby wdrożyć zasobnik zawierający narzędzia mosquitto_pub i mosquitto_sub przydatne do interakcji z brokerem MQTT w klastrze:

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

    Poniższy fragment kodu przedstawia zastosowany plik 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
    

    Uwaga

    Ta konfiguracja nie jest bezpieczna. Nie używaj tej konfiguracji w środowisku produkcyjnym.

  2. Po uruchomieniu zasobnika mqtt-client uruchom następujące polecenie, aby utworzyć środowisko powłoki w utworzonym zasobniku:

    kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh
    
  3. W powłoce powłoki Bash w zasobniku mqtt-client uruchom następujące polecenie, aby nawiązać połączenie z brokerem MQTT przy użyciu narzędzia mosquitto_sub subskrybowanego do tematu 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)
    

    To polecenie będzie nadal uruchamiane i wyświetla komunikaty po nadejściu tematu data/thermostat do momentu naciśnięcia Ctrl+C , aby go zatrzymać. Aby zamknąć środowisko powłoki, wpisz exit.

Aby sprawdzić, czy dodany zasób termostatu publikuje dane, wyświetl dane telemetryczne w temacie 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}}

Jeśli nie ma przepływanych danych, uruchom ponownie zasobnik aio-opc-opc.tcp-1 :

  1. Znajdź nazwę aio-opc-opc.tcp-1 zasobnika przy użyciu następującego polecenia:

    kubectl get pods -n azure-iot-operations
    

    Nazwa zasobnika wygląda następująco: aio-opc-opc.tcp-1-849dd78866-vhmz6.

  2. Uruchom ponownie zasobnik aio-opc-opc.tcp-1 , używając polecenia, które wygląda jak w poniższym przykładzie. aio-opc-opc.tcp-1 Użyj nazwy zasobnika z poprzedniego kroku:

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

Przykładowe tagi dodane w poprzednim samouczku generują komunikaty z zasobu, które wyglądają jak w poniższym przykładzie:

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

Jak rozwiązaliśmy ten problem?

W tym samouczku dodano punkt końcowy zasobu, a następnie zdefiniowano zasób i tagi. Dane modelu zasobów i tagów z serwera OPC UA ułatwiają korzystanie z danych w brokerze MQTT i innych procesach podrzędnych. Użyj zasobu termostatu zdefiniowanego w następnym samouczku.

Czyszczenie zasobów

Jeśli przejdziesz do następnego samouczka, zachowaj wszystkie zasoby.

Jeśli chcesz usunąć wdrożenie operacji usługi Azure IoT, ale zachować klaster, użyj polecenia az iot ops delete :

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

Jeśli chcesz usunąć wszystkie zasoby utworzone na potrzeby tego przewodnika Szybki start, usuń klaster Kubernetes, w którym wdrożono operacje usługi Azure IoT, a następnie usuń grupę zasobów platformy Azure zawierającą klaster.

Jeśli na potrzeby tych przewodników Szybki start użyto usługi Codespaces, usuń środowisko Codespace z usługi GitHub.

Następny krok

Samouczek: wysyłanie danych telemetrycznych zasobów do chmury przy użyciu przepływu danych.