次の方法で共有


MQTT クライアントを使用して MQTT ブローカーへの接続をテストする

重要

このページには、プレビュー段階にある Kubernetes デプロイ マニフェストを使用して Azure IoT Operations コンポーネントを管理する手順が含まれます。 この機能はいくつかの制限を設けて提供されており、運用環境のワークロードには使用しないでください。

ベータ版、プレビュー版、または一般提供としてまだリリースされていない Azure の機能に適用される法律条項については、「Microsoft Azure プレビューの追加使用条件」を参照してください。

この記事では、MQTT クライアントを使用して非運用環境で MQTT ブローカーへの接続をテストするさまざまな方法について説明します。

既定値の MQTT ブローカー:

  • サービスの種類として ClusterIp を指定し、ポート 18883 に TLS 対応リスナーを配置します。 ClusterIp は、ブローカーが Kubernetes クラスター内からのみアクセス可能であることを意味します。 クラスターの外部からブローカーにアクセスするには、サービスの種類を LoadBalancer または NodePort として構成する必要があります。

  • クラスター内からの接続に対して認証用の Kubernetes サービス アカウントのみを受け入れます。 クラスターの外部から接続するには、別の認証方法を構成する必要があります。

注意事項

運用環境のシナリオでは、TLS とサービス アカウント認証を使用して IoT ソリューションをセキュリティで保護する必要があります。 詳細については、以下を参照してください:

始める前に、IoT Operations をインストールまたは構成します。 非運用環境で MQTT クライアントを使用して MQTT ブローカーへの接続をテストするには、次のオプションを使用します。

クラスター内の既定のリスナーに接続する

最初のオプションは、クラスター内から接続するものです。 このオプションでは既定の構成が使用され、追加の更新は必要ありません。 次の例は、プレーンな Alpine Linux と一般的に使用される MQTT クライアントを使用してクラスター内から接続する方法を示しています。サービス アカウントと既定のルート CA 証明書を使用します。

まず、次の構成を使用して client.yaml という名前のファイルを作成します:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: mqtt-client
  namespace: azure-iot-operations
---
apiVersion: v1
kind: Pod
metadata:
  name: mqtt-client
  # Namespace must match MQTT broker 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 created from above
  # Otherwise create it with `kubectl create serviceaccount mqtt-client -n azure-iot-operations`
  serviceAccountName: mqtt-client
  containers:
    # Mosquitto and mqttui on Alpine
  - image: alpine
    name: mqtt-client
    command: ["sh", "-c"]
    args: ["apk add mosquitto-clients mqttui && sleep infinity"]
    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

次に、kubectl を使用して構成をデプロイします。 わずか数秒で開始します。

kubectl apply -f client.yaml

ポッドが実行されたら、kubectl exec を使用してポッド内でコマンドを実行します。

たとえば、ブローカーにメッセージを発行するには、ポッド内でシェルを開きます。

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

ポッドのシェルで次のコマンドを実行し、ブローカーにメッセージを発行します。

mosquitto_pub --host aio-broker --port 18883 --message "hello" --topic "world" --debug --cafile /var/run/certs/ca.crt -D CONNECT authentication-method 'K8S-SAT' -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)

出力は次のようになります。

Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m1, 'world', ... (5 bytes))
Client (null) sending DISCONNECT

mosquitto クライアントは、/var/run/secrets/tokens/broker-sat にマウントされたサービス アカウント トークンを使用してブローカーで認証します。 トークンの有効期間は 24 時間です。 また、クライアントは、/var/run/certs/ca.crt にマウントされている既定のルート CA 証明書を使用して、ブローカーの TLS 証明書チェーンを検証します。

ヒント

kubectl を使用して、他のクライアントで使用する既定のルート CA 証明書をダウンロードできます。 たとえば、既定のルート CA 証明書を ca.crtという名前のファイルにダウンロードするには、次のようにします:

kubectl get configmap azure-iot-operations-aio-ca-trust-bundle -n azure-iot-operations -o jsonpath='{.data.ca\.crt}' > ca.crt

トピックにサブスクライブするには、次のコマンドを実行します。

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

出力は次のようになります。

Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 1, Topic: world, QoS: 0, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 1): 0

mosquitto クライアントは、同じサービス アカウント トークンとルート CA 証明書を使用してブローカーで認証し、トピックにサブスクライブします。

ポッドを削除するには、kubectl delete pod mqtt-client -n azure-iot-operations を実行します。

クラスターの外部からクライアントを接続する

既定のブローカー リスナー のサービスの種類が ClusterIp に設定されているため、クラスターの外部からブローカーに直接接続することはできません。 内部 Azure IoT Operations コンポーネント間の通信が意図せず中断されないようにするには、既定のリスナーに変更を加えずに、AIO 内部通信専用にしておくことをお勧めします。 クラスター IP サービスを公開するために別の Kubernetes LoadBalancer サービスを作成することは可能ですが、混乱や潜在的なセキュリティ リスクを回避するために、より一般的な MQTT ポート 1883 や 8883 など、異なる設定で個別のリスナーを作成することをお勧めします。

ノード ポート

接続をテストする最も簡単な方法は、リスナーで NodePort というサービスの種類を使用することです。 これを使用すると、「Kubernetes のドキュメント」にあるように、<nodeExternalIP>:<NodePort> を使用して接続できます。

たとえば、ノード ポート サービスの種類、サービス名 aio-broker-nodeport、および ポート 1884 (ノード ポート 31884) でリッスンする新しいブローカー リスナーを作成します。

  1. Azure portal で、IoT Operations インスタンスに移動します。

  2. [コンポーネント] で、[MQTT ブローカー] を選択します。

  3. [MQTT broker listener for NodePort]\(NodePort の MQTT ブローカー リスナー\)>[作成] を選択します。 サービスの種類ごとにリスナーを 1 つだけ作成できます。 同じサービスの種類のリスナーが既にある場合は、既存のリスナーにポートをさらに追加できます。

    注意事項

    認証を [なし] に設定し、TLS をテスト用にのみ認証と TLS をオフにするように構成しません。

    次の情報を入力します :

    設定
    名前 aio-broker-nodeport
    サービス名 空のままにするか aio-broker-nodeport
    ポート 1884
    認証 既定または [なし] を選択します
    承認 既定または [なし] を選択します
    Protocol [MQTT] を選択します
    ノード ポート 31884
  4. ポートで [TLS]>[追加] を選択して、リスナーに TLS 設定を追加します。 テストに TLS が必要ない場合は、この手順は必要ありません。 詳細については、BrokerListener を参照してください。

  5. [作成] を選択し、リスナーを作成します。

Note

Kubernetes の既定では、ノード ポート番号は 30000 から 32767 の範囲である必要があります

ノードの外部 IP アドレスを取得します。

kubectl get nodes -o yaml | grep ExternalIP -C 1

出力は次のようになります。

    - address: 104.197.41.11
      type: ExternalIP
    allocatable:
--
    - address: 23.251.152.56
      type: ExternalIP
    allocatable:
...

外部 IP アドレスとノード ポートを使用してブローカーに接続します。 たとえば、ブローカーにメッセージを発行するには、次のようにします:

mosquitto_pub --host <EXTERNAL_IP> --port 31884 --message "hello" --topic "world" --debug # Add authentication and TLS options matching listener settings

出力に外部 IP がない場合は、k3s、k3d、minikube の多くのセットアップのように、ノードの外部 IP アドレスを既定で公開しない Kubernetes セットアップを使用している可能性があります。 その場合は、同じネットワーク上のマシンから、内部 IP とノード ポートを使用してブローカーにアクセスできます。 たとえば、ノードの内部 IP アドレスを取得するには、次のようにします:

kubectl get nodes -o yaml | grep InternalIP -C 1

出力は次のようになります。

    - address: 172.19.0.2
      type: InternalIP
    allocatable:

次に、内部 IP アドレスとノード ポートを使用して、同じクラスター内のマシンからブローカーに接続します。 Kubernetes がローカル コンピューター上で実行されている場合 (単一ノード k3 など)、内部 IP アドレスの代わりに localhost を使用できることがよくあります。 Kubernetes が k3d のように Docker コンテナーで実行されている場合、内部 IP アドレスはコンテナーの IP アドレスに対応し、ホスト コンピューターから到達可能であるはずです。

Load Balancer

ブローカーをインターネットに公開するもう 1 つの方法は、 LoadBalancer サービスの種類を使用することです。 この方法はより複雑であり、ポート フォワーディングの設定など、追加の構成が必要になる場合があります。

たとえば、ロード バランサー サービスの種類、サービス名 aio-broker-loadbalancer を持ち、ポート 1883 でリッスンする新しいブローカー リスナーを作成するには、次のようにします。

  1. Azure portal で、IoT Operations インスタンスに移動します。

  2. [コンポーネント] で、[MQTT ブローカー] を選択します。

  3. [MQTT broker listener for NodePort]\(NodePort の MQTT ブローカー リスナー\)>[作成] を選択します。 サービスの種類ごとにリスナーを 1 つだけ作成できます。 同じサービスの種類のリスナーが既にある場合は、既存のリスナーにポートをさらに追加できます。

    注意事項

    認証を [なし] に設定し、TLS をテスト用にのみ認証と TLS をオフにするように構成しません。

    次の情報を入力します :

    設定
    名前 aio-broker-loadbalancer
    サービス名 空のままにするか aio-broker-loadbalancer
    ポート 1883
    認証 既定または [なし] を選択します
    承認 既定または [なし] を選択します
    Protocol [MQTT] を選択します
  4. ポートで [TLS]>[追加] を選択して、リスナーに TLS 設定を追加します。 テストに TLS が必要ない場合は、この手順は必要ありません。 詳細については、BrokerListener を参照してください。

  5. [作成] を選択し、リスナーを作成します。

  6. [作成] を選択し、リスナーを作成します。

次のように、ブローカーのサービスの外部 IP アドレスを取得します。

kubectl get service aio-broker-loadbalancer --namespace azure-iot-operations

出力が、次のようになった場合:

NAME                      TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
aio-broker-loadbalancer   LoadBalancer   10.x.x.x        x.x.x.x       1883:30382/TCP   83s

これは、外部 IP がロード バランサー サービスに割り当てられていることを意味し、外部 IP アドレスとポートを使用してブローカーに接続できます。 たとえば、ブローカーにメッセージを発行するには、次のようにします:

mosquitto_pub --host <EXTERNAL_IP> --port 1883 --message "hello" --topic "world" --debug # Add authentication and TLS options matching listener settings

外部 IP が割り当てられていない場合は、ポート フォワーディングまたは仮想スイッチを使用してブローカーにアクセスすることが必要になる場合があります。

ポート フォワーディングの使用

minikubekind、およびその他のクラスター エミュレーション システムでは、外部 IP が自動的に割り当てられない可能性があります。 たとえば、保留中状態として表示される場合があります。

  1. ブローカーにアクセスするには、ブローカー リスニング ポートをホストに転送します。

    # Using aio-broker-loadbalancer service name and listener port 1883 as example
    kubectl port-forward --namespace azure-iot-operations service/aio-broker-loadbalancer <HOST_PORT>:1883
    
  2. ターミナルでポート フォワーディング コマンドを実行したままにします。

  3. ポート フォワーディングを行わずに、例と同じ認証と TLS 構成でホスト ポートでブローカーに接続します。

minikube の詳細については、ポート フォワーディングを使用してクラスターにあるアプリケーションにアクセスすることに関する記事をご覧ください

AKS Edge Essentials でのポート フォワーディング

Azure Kubernetes Services Edge Essentials の場合は、いくつかの手順を追加で実行する必要があります。 AKS Edge Essentials では、外部 IP アドレスを取得するだけではブローカーに接続できない場合があります。 ブローカーのサービスへのトラフィックを許可するには、ポート フォワーディングを設定し、ファイアウォールでポートを開く必要がある場合があります。

  1. まず、ブローカーのロード バランサー リスナーの外部 IP アドレスを取得します:

    kubectl get service broker-loadbalancer --namespace azure-iot-operations
    

    出力は次のようになります。

    NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    broker-loadbalancer     LoadBalancer   10.x.x.x       192.168.0.4   1883:30366/TCP   14h
    
  2. 外部 IP アドレス 192.168.0.4 とポート 1883 で、broker-loadbalancer サービスへのポート フォワーディングを設定します。

    netsh interface portproxy add v4tov4 listenport=1883 connectport=1883 connectaddress=192.168.0.4
    
  3. ファイアウォールでポートを開き、ブローカーのサービスへのトラフィックを許可します。

    New-NetFirewallRule -DisplayName "AIO MQTT Broker" -Direction Inbound -Protocol TCP -LocalPort 1883 -Action Allow
    
  4. ホストのパブリック IP アドレスを使用して MQTT ブローカーに接続します。

ポート フォワーディングの詳細については、Expose Kubernetes サービスを外部デバイスに公開するに関する記事をご覧くださいください。

localhost を使用したアクセス

一部の Kubernetes ディストリビューションでは、クラスターの構成の一部として、ホスト システム (localhost) 上のポートで MQTT ブローカーを公開できます。 この方法を使用すると、同じホスト上のクライアントが MQTT ブローカーに簡単にアクセスできるようになります。

たとえば、MQTT ブローカーの既定の MQTT ポート 1883 を localhost:1883 にマッピングした K3d クラスターを作成するには、次のようにします:

k3d cluster create --port '1883:1883@loadbalancer'

または、既存のクラスターを更新します:

k3d cluster edit <CLUSTER_NAME> --port-add '1883:1883@loadbalancer'

次に、localhost とポートを使用してブローカーに接続します。 たとえば、ブローカーにメッセージを発行するには、次のようにします:

mosquitto_pub --host localhost --port 1883 --message "hello" --topic "world" --debug # Add authentication and TLS options matching listener settings

テスト用に TLS と認証のみをオフにする

MQTT ブローカーが既定で TLS とサービス アカウント認証を使用する理由は、最初からセキュリティで保護されたエクスペリエンスを提供することで、IoT ソリューションが攻撃者に対して不注意にさらされるのを最小限に抑えるためです。 運用環境では TLS と認証をオフにしないでください。 認証と TLS なしで MQTT ブローカーをインターネットに公開すると、不正アクセスや DDOS 攻撃につながる可能性があります。

警告

リスクを理解したうえで、必要があり、管理の行き届いた環境で安全でないポートを使用する場合は、リスナーの構成から tlsauthenticationRef を削除することで、テスト目的で TLS と認証をオフにすることができます。

  1. Azure portal で、IoT Operations インスタンスに移動します。

  2. [コンポーネント] で、[MQTT ブローカー] を選択します。

  3. [NodePort の MQTT ブローカー リスナー] または [LoadBalancer の MQTT ブローカー リスナー]>[作成] を選択します。 サービスの種類ごとにリスナーを 1 つだけ作成できます。 同じサービスの種類のリスナーが既にある場合は、既存のリスナーにポートをさらに追加できます。

    注意事項

    認証を [なし] に設定し、TLS をテスト用にのみ認証と TLS をオフにするように構成しません。

    次の情報を入力します :

    設定
    名前 リスナーの名前を入力します
    サービス名 サービスの名前を入力します
    ポート ポート番号を入力します
    認証 [なし] を選択します
    承認 [なし] を選択します
    Protocol [MQTT] を選択します
    ノード ポート ノード ポートを使用している場合は、30000 から 32767 の範囲の値を入力します
  4. [作成] を選択し、リスナーを作成します。