다음을 통해 공유


자습서: Azure Event Grid에 양방향 MQTT 브리지

Important

이 페이지에는 미리 보기 상태인 Kubernetes 배포 매니페스트를 사용하여 Azure IoT Operations 구성 요소를 관리하기 위한 지침이 포함되어 있습니다. 이 기능은 몇 가지 제한 사항을 제공하며 프로덕션 워크로드에 사용하면 안 됩니다.

베타, 미리 보기로 제공되거나 아직 일반 공급으로 릴리스되지 않은 Azure 기능에 적용되는 약관은 Microsoft Azure 미리 보기에 대한 추가 사용 약관을 참조하세요.

이 자습서에서는 Azure IoT Operations MQTT Broker와 Azure Event Grid 간에 양방향 MQTT 브리지를 설정합니다. 자습서를 단순하게 유지하려면 Azure IoT Operations MQTT Broker 및 Azure Event Grid 엔드포인트에 대한 기본 설정을 사용하며 변환이 적용되지 않습니다.

필수 조건

환경 변수 설정

Azure CLI로 로그인:

az login

나머지 설정에 대한 환경 변수를 설정합니다. <>의 값을 원하는 유효한 값이나 원하는 이름으로 대체합니다. 제공하는 이름을 기반으로 Azure 구독에 새 Azure Event Grid 네임스페이스 및 토픽 공간이 만들어집니다.

# For this tutorial, the steps assume the IoT Operations cluster and the Event Grid
# are in the same subscription, resource group, and location.

# Name of the resource group of Azure Event Grid and IoT Operations cluster 
export RESOURCE_GROUP=<RESOURCE_GROUP_NAME>

# Azure region of Azure Event Grid and IoT Operations cluster
export LOCATION=<LOCATION>

# Name of the Azure Event Grid namespace
export EVENT_GRID_NAMESPACE=<EVENT_GRID_NAMESPACE>

# Name of the Arc-enabled IoT Operations cluster 
export CLUSTER_NAME=<CLUSTER_NAME>

# Subscription ID of Azure Event Grid and IoT Operations cluster
export SUBSCRIPTION_ID=<SUBSCRIPTION_ID>

MQTT 브로커를 사용하도록 설정된 Event Grid 네임스페이스 만들기

Azure CLI를 사용하여 Event Grid 네임스페이스를 생성합니다. 위치는 Azure IoT 작업을 배포하는 데 사용한 위치와 동일해야 합니다.

az eventgrid namespace create \
  --namespace-name $EVENT_GRID_NAMESPACE \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --topic-spaces-configuration "{state:Enabled,maximumClientSessionsPerAuthenticationName:3}"

확장이 eventgrid 설치되지 않은 경우 확장을 설치할지 묻는 메시지가 표시됩니다. 확장을 설치하려면 선택합니다 Y .

topic-spaces-configuration을 설정하면 이 명령은 다음과 같은 네임스페이스를 만듭니다.

  • MQTT 브로커를 사용하도록 설정됨
  • 인증 이름당 최대 클라이언트 세션이 3

최대 클라이언트 세션 옵션을 사용하면 Azure IoT Operations MQTT가 여러 인스턴스를 생성하고 계속 연결할 수 있습니다. 자세한 내용은 다중 세션 지원을 참조하세요.

토픽 공간 만들기

Event Grid 네임스페이스에서 토픽 템플릿 telemetry/#을 사용하여 tutorial이라는 토픽 공간을 만듭니다.

az eventgrid namespace topic-space create \
  --resource-group $RESOURCE_GROUP \
  --namespace-name $EVENT_GRID_NAMESPACE \
  --name tutorial \
  --topic-templates "telemetry/#"

토픽 템플릿에서 # 와일드카드를 사용하면 telemetry 토픽 공간 아래의 모든 토픽에 게시할 수 있습니다. 예를 들어 telemetry/temperature 또는 telemetry/humidity입니다.

Azure IoT Operations에 Event Grid 토픽 공간에 대한 액세스 권한 부여

Azure CLI를 사용하여 Azure IoT Operations Arc 확장의 보안 주체 ID를 찾습니다. 이 명령은 나중에 사용할 수 있도록 변수에 보안 주체 ID를 저장합니다.

export PRINCIPAL_ID=$(az k8s-extension list \
  --resource-group $RESOURCE_GROUP \
  --cluster-name $CLUSTER_NAME \
  --cluster-type connectedClusters \
  --query "[?extensionType=='microsoft.iotoperations'].identity.principalId | [0]" -o tsv)
echo $PRINCIPAL_ID

다음 형식의 GUID 값인 identity.principalId의 출력 값을 기록해 둡니다.

d84481ae-9181-xxxx-xxxx-xxxxxxxxxxxx

그런 다음, Azure CLI를 사용하여 만든 토픽 공간에 대한 Azure IoT Operations MQTT에 게시자 및 구독자 역할을 할당합니다.

게시자 역할 할당:

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "EventGrid TopicSpaces Publisher" \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.EventGrid/namespaces/$EVENT_GRID_NAMESPACE/topicSpaces/tutorial

구독자 역할 할당:

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "EventGrid TopicSpaces Subscriber" \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.EventGrid/namespaces/$EVENT_GRID_NAMESPACE/topicSpaces/tutorial

범위는 이전 단계에서 az eventgrid namespace topic-space create를 사용하여 만든 토픽 공간의 id와 일치하며 명령 출력에서 찾을 수 있습니다.

Event Grid MQTT 브로커 호스트 이름

Azure CLI를 사용하여 Event Grid MQTT 브로커 호스트 이름을 가져옵니다.

az eventgrid namespace show \
  --resource-group $RESOURCE_GROUP \
  --namespace-name $EVENT_GRID_NAMESPACE \
  --query topicSpacesConfiguration.hostname \
  -o tsv

topicSpacesConfiguration.hostname의 출력 값을 기록해 둡니다. 이는 다음과 같은 호스트 이름 값입니다.

example.region-1.ts.eventgrid.azure.net

Azure Event Grid 데이터 흐름 엔드포인트 만들기

Azure Event Grid에 대한 데이터 흐름 엔드포인트를 만듭니다. 이 엔드포인트는 Azure Event Grid에 메시지를 보내는 데이터 흐름의 대상입니다. 이전 단계에서 가져온 MQTT 호스트 이름으로 바꿉 <EVENT_GRID_HOSTNAME> 습니다. 포트 번호를 8883포함합니다.

데이터 흐름 및 데이터 흐름 엔드포인트는 Azure RP(리소스 공급자) 구현이 있으므로 Azure Event Grid를 표준 Azure 리소스로 배포할 수 있습니다. MQTT 브리지 데이터 흐름 자습서용 Bicep 파일의 이 Bicep 템플릿 파일은 필요한 데이터 흐름 및 데이터 흐름 엔드포인트를 배포합니다.

로컬에 파일을 다운로드하고 , aioInstanceNameeventGridHostName 에 대한 customLocationName값을 사용자 값으로 바꿔야 합니다.

param customLocationName string = '<CUSTOM_LOCATION_NAME>'
param aioInstanceName string = '<AIO_INSTANCE_NAME>'
param eventGridHostName string = '<EVENT_GRID_HOSTNAME>:8883'

resource customLocation 'Microsoft.ExtendedLocation/customLocations@2021-08-31-preview' existing = {
  name: customLocationName
}

resource aioInstance 'Microsoft.IoTOperations/instances@2024-11-01' existing = {
  name: aioInstanceName
}
resource remoteMqttBrokerDataflowEndpoint 'Microsoft.IoTOperations/instances/dataflowEndpoints@2024-11-01' = {
  parent: aioInstance
  name: 'eventgrid'
  extendedLocation: {
    name: customLocation.id
    type: 'CustomLocation'
  }
  properties: {
    endpointType: 'Mqtt'
    mqttSettings: {
      host: eventGridHostName
      authentication: {
        method: 'SystemAssignedManagedIdentity'
        systemAssignedManagedIdentitySettings: {}
      }
      tls: {
        mode: 'Enabled'
      }
    }
  }
}

다음으로 터미널에서 다음 명령을 실행합니다. 다운로드한 Bicep 파일의 이름으로 바꿉 <FILE> 습니다.

az deployment group create --resource-group <RESOURCE_GROUP> --template-file <FILE>.bicep

여기서 인증 방법은 Azure IoT Operations 확장의 관리 ID를 사용하여 Event Grid MQTT 브로커로 인증하도록 설정 SystemAssignedManagedIdentity 됩니다. 이 설정은 Azure IoT Operations 확장에 Azure RBAC 역할을 통해 구성된 Event Grid 토픽 공간을 게시하고 구독하는 데 필요한 권한이 있기 때문에 작동합니다. 구성에는 사용자 이름 또는 암호와 같은 비밀이 필요하지 않습니다.

Event Grid MQTT Broker에는 TLS가 tls 필요하므로 설정이 사용하도록 설정됩니다. Event Grid MQTT 브로커는 널리 신뢰할 수 있는 인증 기관을 사용하므로 신뢰할 수 있는 CA 인증서를 제공할 필요가 없습니다.

데이터 흐름 만들기

Azure IoT Operations MQTT Broker 엔드포인트를 원본으로, Azure Event Grid 엔드포인트를 대상으로, 그 반대로 두 개의 데이터 흐름을 만듭니다. 변환을 구성할 필요가 없습니다.

param customLocationName string = '<CUSTOM_LOCATION_NAME>'
param aioInstanceName string = '<AIO_INSTANCE_NAME>'

resource customLocation 'Microsoft.ExtendedLocation/customLocations@2021-08-31-preview' existing = {
  name: customLocationName
}
resource aioInstance 'Microsoft.IoTOperations/instances@2024-11-01' existing = {
  name: aioInstanceName
}
resource defaultDataflowProfile 'Microsoft.IoTOperations/instances/dataflowProfiles@2024-11-01' existing = {
  parent: aioInstance
  name: 'default'
}
resource dataflow_1 'Microsoft.IoTOperations/instances/dataflowProfiles/dataflows@2024-11-01' = {
  parent: defaultDataflowProfile
  name: 'local-to-remote'
  extendedLocation: {
    name: customLocation.id
    type: 'CustomLocation'
  }
  properties: {
    mode: 'Enabled'
    operations: [
      {
        operationType: 'Source'
        sourceSettings: {
          endpointRef: 'default'
          serializationFormat: 'Json'
          dataSources: array('tutorial/local')
        }
      }
      {
        operationType: 'BuiltInTransformation'

        builtInTransformationSettings: {
        serializationFormat: 'Json'
        datasets: []
        filter: []
        map: [
          {
            type: 'PassThrough'
            inputs: [
              '*'
            ]
            output: '*'
          }
        ]
        }
      }
      {
        operationType: 'Destination'
        destinationSettings: {
          endpointRef: 'eventgrid'
          dataDestination: 'telemetry/aio'
        }
      }
    ]
  }
} 
resource dataflow_2 'Microsoft.IoTOperations/instances/dataflowProfiles/dataflows@2024-11-01' = {
  parent: defaultDataflowProfile
  name: 'remote-to-local'
  extendedLocation: {
    name: customLocation.id
    type: 'CustomLocation'
  }
  properties: {
    mode: 'Enabled'
    operations: [
      {
        operationType: 'Source'
        sourceSettings: {
          endpointRef: 'eventgrid'
          serializationFormat: 'Json'
          dataSources: array('telemetry/#')
        }
      }
      {
        operationType: 'BuiltInTransformation'

        builtInTransformationSettings: {
        serializationFormat: 'Json'
        datasets: []
        filter: []
        map: [
          {
            type: 'PassThrough'
            inputs: [
              '*'
            ]
            output: '*'
          }
        ]
        }
      }
      {
        operationType: 'Destination'
        destinationSettings: {
          endpointRef: 'default'
          dataDestination: 'tutorial/cloud'
        }
      }
    ]
  }
}

데이터 흐름 엔드포인트와 마찬가지로 터미널에서 다음 명령을 실행합니다.

az deployment group create --resource-group <RESOURCE_GROUP> --template-file <FILE>.bicep

두 데이터 흐름은 함께 MQTT 브리지를 형성합니다. 여기서 다음을 수행합니다.

  • Event Grid MQTT 브로커를 원격 브로커로 사용
  • 로컬 Azure IoT Operations MQTT broker를 로컬 브로커로 사용
  • 원격 및 로컬 브로커 모두에 TLS 사용
  • 원격 브로커에 대한 인증을 위해 시스템 할당 관리 ID 사용
  • 로컬 브로커에 대한 인증에 Kubernetes 서비스 계정 사용
  • 토픽 맵을 사용하여 tutorial/local 토픽을 원격 브로커의 telemetry/aio 토픽에 매핑
  • 토픽 맵을 사용하여 원격 브로커의 telemetry/# 토픽을 로컬 브로커의 tutorial/cloud 토픽에 매핑

참고 항목

기본적으로 Azure IoT Operations는 MQTT Broker와 MQTT broker 데이터 흐름 엔드포인트를 배포합니다. MQTT broker 데이터 흐름 엔드포인트는 MQTT broker에 연결하는 데 사용됩니다. 기본 구성은 인증에 기본 제공 서비스 계정 토큰을 사용합니다. 엔드포인트의 이름은 Azure default IoT Operations와 동일한 네임스페이스에서 사용할 수 있습니다. 엔드포인트는 이 자습서에서 만든 데이터 흐름의 원본으로 사용됩니다. 기본 MQTT broker 데이터 흐름 엔드포인트에 대한 자세한 내용은 Azure IoT Operations 로컬 MQTT broker 기본 엔드포인트를 참조 하세요.

로컬 Azure IoT Operations MQTT broker의 토픽에 게시 tutorial/local 하면 메시지가 원격 Event Grid MQTT Broker의 telemetry/aio 토픽에 브리지됩니다. 그런 다음, 메시지는 로컬 Azure IoT Operations MQTT 브로커에서 토픽에 다시 tutorial/cloud 브리지됩니다(와일드카드 토픽이 캡처하기 때문 telemetry/# ). 마찬가지로 원격 Event Grid MQTT broker의 토픽에 게시 telemetry/aio 하면 메시지가 로컬 Azure IoT Operations MQTT broker의 토픽에 브리지됩니다 tutorial/cloud .

MQTT 클라이언트 배포

MQTT 브리지가 작동하는지 확인하려면 Azure IoT Operations와 동일한 네임스페이스에 MQTT 클라이언트를 배포합니다. 이름이 client.yaml인 새 파일에서 클라이언트 배포를 지정합니다.

현재 bicep은 MQTT 클라이언트 배포에 적용되지 않습니다.

구독자 시작

kubectl exec를 사용하여 mosquitto 클라이언트 Pod에서 셸을 시작합니다.

kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh

셸 내에서 토픽 공간에서 mosquitto_subAzure IoT Operations broker에 대한 tutorial/# 구독자를 시작합니다.

mosquitto_sub --host aio-broker --port 18883 \
  -t "tutorial/#" \
  --debug --cafile /var/run/certs/ca.crt \
  -D CONNECT authentication-method 'K8S-SAT' \
  -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)

명령을 실행 상태로 두고 새 터미널 창을 엽니다.

브리지를 통해 클라우드에 MQTT 메시지 게시

새 터미널 창에서 mosquitto 클라이언트 Pod의 다른 셸을 시작합니다.

kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh

셸 내에서 mosquitto를 사용하여 tutorial/local 토픽에 5개의 메시지를 게시합니다.

mosquitto_pub -h aio-broker -p 18883 \
  -m "This message goes all the way to the cloud and back!" \
  -t "tutorial/local" \
  --repeat 5 --repeat-delay 1 -d \
  --debug --cafile /var/run/certs/ca.crt \
  -D CONNECT authentication-method 'K8S-SAT' \
  -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)

구독자의 메시지 보기

구독자 셸에 게시한 메시지가 표시됩니다.

여기서는 메시지가 토픽에 로컬 Azure IoT Operations Broker에 tutorial/local 게시되고 Event Grid MQTT 브로커에 브리지된 다음 토픽에서 다시 로컬 Azure IoT Operations Broker에 tutorial/cloud 브리지되는 것을 볼 수 있습니다. 그러면 메시지가 구독자에게 배달됩니다. 이 예제에서 왕복 시간은 약 80ms입니다.

Event Grid 메트릭을 확인하여 메시지 배달 확인

Event Grid 메트릭을 확인하여 메시지가 Event Grid MQTT 브로커에 배달되었는지 확인할 수도 있습니다. Azure Portal에서 만든 Event Grid 네임스페이스로 이동합니다. 메트릭>MQTT: 게시된 메시지 아래. 로컬 Azure IoT Operations broker에 메시지를 게시할 때 게시되고 배달된 메시지 수가 증가해야 합니다.

성공적인 MQTT 메시지를 표시하는 Azure Portal의 메트릭 보기 스크린샷.

다음 단계

이 자습서에서는 Azure Event Grid MQTT Broker를 사용하여 양방향 MQTT 브리지에 대한 Azure IoT Operations를 구성하는 방법을 알아보았습니다. 다음 단계에서는 다음 시나리오를 살펴봅니다.

  • MQTT 클라이언트를 사용하여 Event Grid MQTT 브로커에 직접 메시지를 게시하려면 Event Grid MQTT 브로커에 MQTT 메시지 게시를 참조하세요. 클라이언트에 사용자가 만든 토픽 공간에 대한 게시자 권한 바인딩을 부여하고 telemetry 아래의 모든 토픽(예: telemetry/temperature또는 telemetry/humidity)에 메시지를 게시할 수 있습니다. 이러한 모든 메시지는 로컬 Azure IoT Operations Broker의 토픽에 연결 tutorial/cloud 됩니다.
  • Event Grid MQTT 브로커에 대한 라우팅 규칙을 설정하려면 Event Grid MQTT 브로커에 대한 라우팅 규칙 구성을 참조하세요. 라우팅 규칙을 사용하여 토픽 이름을 기반으로 다른 토픽으로 메시지를 라우팅하거나 메시지 콘텐츠를 기반으로 메시지를 필터링할 수 있습니다.