Compartilhar via


Início Rápido: Configurar seu cluster

Importante

A Versão Prévia das Operações da Internet das Coisas do Azure – habilitadas pelo Azure Arc – está atualmente em versão prévia. Você não deve usar esse software em versão prévia em ambientes de produção.

Você precisará implantar uma nova instalação das Operações do Azure IoT quando uma versão geralmente disponível estiver disponível. Você não poderá atualizar uma instalação de versão prévia.

Para os termos legais que se aplicam aos recursos do Azure que estão em versão beta, versão prévia ou que, de outra forma, ainda não foram lançados em disponibilidade geral, confira os Termos de Uso Complementares para Versões Prévias do Microsoft Azure.

Nesse início rápido, você configurará os seguintes recursos no seu cluster de Operações do Azure IoT em visualização:

  • Um ponto de extremidade de ativo que define uma conexão com um servidor OPC PLC simulado que simula um forno em uma padaria.
  • Um ativo que representa o forno e define os pontos de dados que o forno expõe.
  • Um fluxo de dados que manipula as mensagens do forno simulado.

Um ativo é um dispositivo físico ou uma entidade lógica que representam um dispositivo, um computador, 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 aplicativos de software que se 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, o desempenho, a qualidade ou a condição dos ativos.

Nesse início rápido, você usará um arquivo Bicep para configurar sua instância de Operações do Azure IoT.

Pré-requisitos

Tenha uma instância do Visualização de Operações do Azure IoT implantada em um cluster do Kubernetes. O Início Rápido: executar a Visualização de Operações IoT do Azure nos GitHub Codespaces com K3s fornece instruções simples para implantar uma instância de Operações de IoT do Azure que você poderá usar para os inícios rápidos.

A menos que indicado de outra forma, execute os comandos do console neste início rápido em um ambiente do Bash ou do PowerShell.

Que problema vamos resolver?

Os dados que os servidores OPC UA expõem podem ter uma estrutura complexa e ser difíceis de entender. O recurso Operações do Azure IoT fornece uma maneira de modelar ativos OPC UA na forma de tags, eventos e propriedades. Essa modelagem facilita a compreensão dos dados e o uso deles em processos de downstream, como o agente MQTT e fluxos de dados. Os fluxos de dados permitem manipular e rotear dados para serviços de nuvem como os Hubs de Eventos do Azure. Nesse início rápido, o fluxo de dados altera os nomes de alguns campos no conteúdo e adiciona uma ID de ativo às mensagens.

Implantar o simulador de PLC OPC

Este início rápido usa o simulador OPC PLC para gerar dados de exemplo. Para implantar o simulador OPC PLC, 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

Cuidado

Essa configuração usa um certificado de instância de aplicativo autoassinado. Não use essa configuração em um ambiente de produção. Para saber mais, confira Configurar a infraestrutura de certificados OPC UA para o conector OPC UA.


Definir variáveis de ambiente

Se você estiver usando o ambiente do Codespaces, as variáveis de ambiente necessárias já estão definidas e você pode ignorar esta etapa. Caso contrário, defina as seguintes variáveis de ambiente em seu shell:

# Your subscription ID
SUBSCRIPTION_ID=<subscription-id>

# The name of the resource group where your Kubernetes cluster is deployed
RESOURCE_GROUP=<resource-group-name>

# The name of your Kubernetes cluster
CLUSTER_NAME=<kubernetes-cluster-name>

Configurar seu cluster

Execute os seguintes comandos para baixar e executar o arquivo Bicep que configura sua instância de Operações do Azure IoT. O arquivo Bicep:

  • Adiciona um ponto de extremidade de ativo que se conecta ao simulador OPC PLC.
  • Adiciona um ativo que representa o forno e define os pontos de dados que o forno expõe.
  • Adiciona um fluxo de dados que manipula as mensagens do forno simulado.
  • Cria uma instância dos Hubs de Eventos do Azure para receber os dados.
wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/quickstart.bicep -O quickstart.bicep

AIO_EXTENSION_NAME=$(az k8s-extension list -g $RESOURCE_GROUP --cluster-name $CLUSTER_NAME --cluster-type connectedClusters --query "[?extensionType == 'microsoft.iotoperations'].id" -o tsv | awk -F'/' '{print $NF}')
AIO_INSTANCE_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].name" -o tsv)
CUSTOM_LOCATION_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].extendedLocation.name" -o tsv | awk -F'/' '{print $NF}')

az deployment group create --subscription $SUBSCRIPTION_ID --resource-group $RESOURCE_GROUP --template-file quickstart.bicep --parameters clusterName=$CLUSTER_NAME customLocationName=$CUSTOM_LOCATION_NAME aioExtensionName=$AIO_EXTENSION_NAME aioInstanceName=$AIO_INSTANCE_NAME

Examinar configuração

O arquivo Bicep configurou os seguintes recursos:

  • Um ponto de extremidade de ativo que se conecta ao simulador OPC PLC.
  • Um ativo que representa o forno e define os pontos de dados que o forno expõe.
  • Dois fluxos de dados que processam as mensagens do forno simulado.
  • Um namespace dos Hubs de Eventos do Azure que contém um hub de destino para os fluxos de dados.

Para visualizar o ponto de extremidade de ativo, ativo e fluxos de dados, navegue até a interface do usuário de experiência de operações no seu navegador e conecte-se com suas credenciais do Microsoft Entra ID. Como você está trabalhando com uma nova implantação, ainda não há sites. Você pode encontrar o cluster criado no início rápido anterior selecionando Instâncias não atribuídas. Na experiência de operações, uma instância representa um cluster onde você implantou as Operações de IoT do Azure.

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

O ponto de extremidade de ativo define a conexão com o simulador OPC PLC:

Captura de tela na experiência de operações que mostra uma lista de pontos de extremidade de ativos.

O ativo do forno define os pontos de dados que o forno expõe:

Captura de tela na experiência de operações que mostra uma lista de ativos.

Os fluxos de dados definem como as mensagens do forno simulado são processadas e roteadas para os Hubs de Eventos na nuvem:

Captura de tela na experiência de operações que mostra uma lista de fluxos de dados.

A seguinte captura de tela mostra como o fluxo de dados de conversão de temperatura está configurado:

Captura de tela na experiência de operações que mostra o cálculo de conversão de temperatura.

Verificar se os dados estão fluindo para o agente MQTT

Verifique se os dados estão fluindo para o agente MQTT usando a ferramenta mosquitto_sub. Neste exemplo, execute 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 agente 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
    # 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
    

    Cuidado

    Essa 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 do Bash no pod mqtt-client, execute o seguinte comando para se conectar ao agente MQTT usando a ferramenta mosquitto_sub inscrita no tópico 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)
    

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

Para verificar se o ativo do forno que você adicionou está publicando dados, visualize a telemetria no tópico azure-iot-operations/data:

Client $server-generated/05a22b94-c5a2-4666-9c62-837431ca6f7e received PUBLISH (d0, q0, r0, m0, 'azure-iot-operations/data/oven', ... (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/oven', ... (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/oven', ... (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/oven', ... (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/oven', ... (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 nenhum fluxo de dados, reinicie o pod aio-opc-opc.tcp-1:

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

    kubectl get pods -n azure-iot-operations
    

    O nome do pod é semelhante a aio-opc-opc.tcp-1-849dd78866-vhmz6.

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

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

O ativo de exemplo que você adicionou anteriormente neste início rápido gera mensagens semelhantes ao seguinte exemplo:

{
   "Temperature":{
      "SourceTimestamp":"2024-11-04T21:30:31.9454188Z",
      "Value":357
   },
   "FillWeight":{
      "SourceTimestamp":"2024-11-04T21:30:31.9455619Z",
      "Value":357
   },
   "EnergyUse":{
      "SourceTimestamp":"2024-11-04T21:30:31.9455641Z",
      "Value":357
   }
}

Verificar se os dados estão fluindo para os Hubs de Eventos

Para verificar se os dados estão fluindo para a nuvem, você pode exibir a sua instância dos Hubs de Eventos no portal do Azure. Você pode precisar aguardar vários minutos para o fluxo de dados iniciar e para as mensagens fluírem para o hub de eventos.

A configuração Bicep que você aplicou anteriormente criou um namespace e um hub dos Hubs de Eventos do Azure que são usados como destino pelo fluxo de dados. Para visualizar o namespace e o hub, navegue até o grupo de recursos no portal do Azure que contém sua instância de Operações de IoT e selecione o namespace dos Hubs de Eventos.

Se as mensagens estiverem fluindo para a instância, você poderá ver a contagem de mensagens de entrada na página de visão geral da instância:

Captura de tela que mostra a página de visão geral da instância dos Hubs de Eventos com mensagens de entrada.

Se as mensagens estiverem fluindo, você poderá usar o Data Explorer para exibir as mensagens:

Captura de tela da página **Data Explorer** da instância dos Hubs de Eventos.

Dica

Talvez seja necessário atribuir-se à função Receptor de dados dos Hubs de Eventos do Azure para que o namespace dos Hubs de Eventos exiba as mensagens.

Como resolvemos o problema?

Nesse início rápido, você usou um arquivo bicep para configurar sua instância de Operações do Azure IoT com um ponto de extremidade de ativo, ativo e fluxo de dados. A configuração processa e roteia dados de um forno simulado. O fluxo de dados na configuração roteia as mensagens para uma instância dos Hubs de Eventos do Azure.

Limpar os recursos

Se você continuar no próximo início rápido, mantenha todos os seus recursos.

Se você quiser remover a implantação das Operações do Azure IoT, mas manter o 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 no qual você implantou as Operações do Azure IoT e remova o grupo de recursos do Azure que continha o cluster.

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

Próxima etapa

Se você quiser saber como criar um dashboard do Microsoft Fabric para obter insights dos seus dados de forno, confira Tutorial: Obter insights a partir dos seus dados processados.