Partilhar via


Tutorial: Adicionar ativos OPC UA ao cluster de Operações IoT do Azure

Neste tutorial, você adiciona manualmente ativos OPC UA ao cluster de Operações IoT do Azure. Esses ativos publicam mensagens no agente MQTT em seu cluster de Operações do Azure IoT. Normalmente, um usuário OT conclui essas etapas.

Um ativo é um dispositivo físico ou entidade lógica que representa um dispositivo, uma máquina, um sistema ou um processo. Por exemplo, um ativo físico pode ser uma bomba, um motor, um tanque ou uma linha de produção. Um ativo lógico que você define pode ter propriedades, transmitir telemetria ou gerar eventos.

Os servidores OPC UA são aplicações de software que comunicam com ativos. As tags OPC UA são pontos de dados que os servidores OPC UA expõem. As tags OPC UA podem fornecer dados históricos ou em tempo real sobre o status, desempenho, qualidade ou condição dos ativos.

Neste tutorial, você usa a interface do usuário da Web da experiência de operações para criar seus ativos. Você também pode usar a CLI do Azure para concluir algumas dessas tarefas.

Pré-requisitos

Uma instância do Azure IoT Operations implantada em um cluster Kubernetes. Para criar uma instância, use uma das seguintes opções para implantar as Operações do Azure IoT:

Para entrar na interface do usuário da Web da experiência de operações, você precisa de uma conta de ID do Microsoft Entra com pelo menos permissões de colaborador para o grupo de recursos que contém sua instância do Kubernetes - Azure Arc . Para saber mais, consulte Interface do usuário da Web da experiência de operações.

Salvo indicação em contrário, você pode executar os comandos do console neste tutorial em um ambiente Bash ou PowerShell.

Que problema vamos resolver?

Os dados que os servidores OPC UA expõem podem ter uma estrutura complexa e podem ser difíceis de entender. O Azure IoT Operations fornece uma maneira de modelar ativos OPC UA como tags, eventos e propriedades. Essa modelagem torna mais fácil entender os dados e usá-los em processos downstream, como o broker MQTT e fluxos de dados.

Implante o simulador de PLC OPC

Este tutorial usa o simulador de PLC OPC para gerar dados de exemplo. Para implantar o simulador de PLC OPC, execute o seguinte comando:

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

O trecho a seguir mostra o arquivo YAML que você aplicou:

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

Atenção

Esta configuração não é segura. Não use essa configuração em um ambiente de produção.

Entrar na experiência de operações

Para criar pontos de extremidade de ativos, ativos e assinar tags e eventos OPC UA, use a experiência de operações.

Navegue até a experiência de operações em seu navegador e entre com suas credenciais de ID do Microsoft Entra.

Selecione o seu site

Um site é um conjunto de instâncias de Operações do Azure IoT. Os sites normalmente agrupam instâncias por local físico e facilitam a localização e o gerenciamento de ativos pelos usuários de OT. O administrador de TI cria sites e atribui instâncias do Azure IoT Operations a eles. Como você está trabalhando com uma nova implantação, ainda não há sites. Você pode encontrar o cluster criado anteriormente selecionando Exibir instâncias não atribuídas. Na experiência de operações, uma instância representa um cluster no qual você implantou as Operações do Azure IoT.

Captura de tela que mostra o nó de instâncias não atribuídas na experiência de operações.

Selecione sua instância

Selecione a instância em que você implantou as Operações do Azure IoT no tutorial anterior:

Captura de ecrã da lista de instâncias de Operações do Azure IoT.

Gorjeta

Se você não vir nenhuma instância, talvez não esteja no locatário correto do Microsoft Entra ID. Você pode alterar o locatário no menu superior direito da experiência de operações.

Adicionar um ponto de extremidade de ativo

Ao implantar o Azure IoT Operations no artigo anterior, você incluiu um simulador de PLC OPC interno. Nesta etapa, você adiciona um ponto de extremidade de ativo que permite que você se conecte ao simulador de PLC OPC.

Para adicionar um ponto de extremidade de ativo:

  1. Selecione Pontos de extremidade de ativos e, em seguida, Criar ponto de extremidade de ativos:

    Captura de tela que mostra a página de pontos de extremidade do ativo na experiência de operações.

  2. Insira as seguintes informações do ponto final:

    Campo Value
    Nome do ponto de extremidade do ativo opc-ua-connector-0
    URL do servidor OPC UA opc.tcp://opcplc-000000:50000
    Modo de autenticação do usuário Anonymous
  3. Para salvar a definição, selecione Criar.

    Essa configuração implanta um novo ponto de extremidade de ativo chamado opc-ua-connector-0 para o cluster. Você pode usar kubectl para exibir os pontos de extremidade do ativo:

    kubectl get assetendpointprofile -n azure-iot-operations
    

Gerir os seus recursos

Depois de selecionar sua instância na experiência de operações, você verá a lista disponível de ativos na página Ativos . Se ainda não houver ativos, esta lista está vazia:

Captura de ecrã da lista de ativos vazia das Operações IoT do Azure.

Criar um ativo

Para criar um ativo, selecione Criar ativo. Em seguida, insira as seguintes informações de ativos:

Campo Value
Ponto de extremidade de ativos opc-ua-connector-0
Nome do ativo thermostat
Description A simulated thermostat asset
Tópico MQTT padrão azure-iot-operations/data/thermostat

Remova as propriedades personalizadas existentes e adicione as seguintes propriedades personalizadas. Tenha cuidado para usar os nomes de propriedade exatos, como o modelo do Power BI em um tutorial posterior consulta para eles:

Nome da propriedade Detalhe do imóvel
batch 102
cliente Contoso
Equipamentos Caldeira
isSpare verdadeiro
localização Porto

Captura de ecrã da página de detalhes do ativo Azure IoT Operations.

Selecione Avançar para ir para a página Adicionar tags .

Criar tags OPC UA

Adicione duas tags OPC UA na página Adicionar tags . Para adicionar cada etiqueta, selecione Adicionar etiqueta ou CSV e, em seguida, selecione Adicionar etiqueta. Insira os detalhes da tag mostrados na tabela a seguir:

ID do Nó Nome da etiqueta Modo de observabilidade
ns=3; s=FastUInt10 temperatura Nenhuma
ns=3; s=FastUInt100 Etiqueta 10 Nenhuma

O modo de Observabilidade é um dos seguintes valores: None, Gauge, Counter, Histogram, ou Log.

Você pode selecionar Gerenciar configurações padrão para alterar o intervalo de amostragem padrão e o tamanho da fila para cada tag.

Captura de ecrã da página de adicionar etiqueta das Operações IoT do Azure.

Selecione Avançar para ir para a página Adicionar eventos e, em seguida, Avançar para ir para a página Revisão .

Rever

Revise os detalhes do ativo e da tag e faça os ajustes necessários antes de selecionar Criar:

Captura de ecrã da página de revisão de ativos de criação de Operações IoT do Azure.

Essa configuração implanta um novo ativo chamado thermostat para o cluster. Você pode usar kubectl para visualizar os ativos:

kubectl get assets -n azure-iot-operations

Exibir recursos no portal do Azure

Para exibir o ponto de extremidade do ativo e o ativo que você criou no portal do Azure, vá para o grupo de recursos que contém sua instância do Azure IoT Operations. Você pode ver o ativo termostato no grupo de recursos Operações IoT do Azure. Se você selecionar Mostrar tipos ocultos, também poderá ver o ponto de extremidade do ativo:

Captura de ecrã do portal do Azure a mostrar o grupo de recursos do Azure IoT Operations, incluindo o ativo e o ponto de extremidade do ativo.

O portal permite visualizar os detalhes do ativo. Selecione JSON View para obter mais detalhes:

Captura de ecrã dos detalhes do ativo Azure IoT Operations no portal do Azure.

Verificar se os dados estão fluindo

Verifique se os dados estão fluindo para o broker MQTT usando a ferramenta mosquitto_sub . Neste exemplo, você executa a ferramenta mosquitto_sub dentro do cluster do Kubernetes:

  1. Execute o seguinte comando para implantar um pod que inclua as ferramentas mosquitto_pub e mosquitto_sub que são úteis para interagir com o broker MQTT no cluster:

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

    O trecho a seguir mostra o arquivo YAML que você aplicou:

    # 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
    

    Atenção

    Esta configuração não é segura. Não use essa configuração em um ambiente de produção.

  2. Quando o pod mqtt-client estiver em execução, execute o seguinte comando para criar um ambiente de shell no pod que você criou:

    kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh
    
  3. No shell Bash no pod mqtt-client , execute o seguinte comando para se conectar ao broker MQTT usando a ferramenta mosquitto_sub inscrita no data/thermostat tópico:

    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)
    

    Este comando continua a ser executado e exibe as mensagens à medida que chegam ao data/thermostat tópico até que você pressione Ctrl+C para pará-lo. Para sair do ambiente de shell, digite exit.

Para verificar se o ativo de termostato adicionado está publicando dados, exiba a telemetria azure-iot-operations/data no tópico:

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 não houver fluxo de dados, reinicie o aio-opc-opc.tcp-1 pod:

  1. Encontre o nome do seu aio-opc-opc.tcp-1 pod usando o seguinte comando:

    kubectl get pods -n azure-iot-operations
    

    O nome do seu pod é parecido com aio-opc-opc.tcp-1-849dd78866-vhmz6.

  2. Reinicie o aio-opc-opc.tcp-1 pod usando um comando semelhante ao exemplo a seguir. Use o nome do aio-opc-opc.tcp-1 pod da etapa anterior:

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

As tags de exemplo que você adicionou no tutorial anterior geram mensagens do seu ativo que se parecem com o exemplo a seguir:

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

Como resolvemos o problema?

Neste tutorial, você adicionou um ponto de extremidade de ativo e, em seguida, definiu um ativo e tags. Os ativos e tags modelam dados do servidor OPC UA para tornar os dados mais fáceis de usar em um broker MQTT e outros processos downstream. Você usa o recurso de termostato definido no próximo tutorial.

Clean up resources (Limpar recursos)

Se você continuar para o próximo tutorial, mantenha todos os seus recursos.

Se você quiser remover a implantação do Azure IoT Operations mas manter seu cluster, use o comando az iot ops delete :

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

Se você quiser excluir todos os recursos criados para este início rápido, exclua o cluster do Kubernetes onde você implantou as Operações do Azure IoT e, em seguida, remova o grupo de recursos do Azure que continha o cluster.

Se você usou Codespaces para esses inícios rápidos, exclua seu Codespace do GitHub.

Próximo passo

Tutorial: Envie telemetria de ativos para a nuvem usando um fluxo de dados.