MQTT クライアントを使用して MQTT ブローカーへの接続をテストする
重要
このページには、プレビュー段階にある Kubernetes デプロイ マニフェストを使用して Azure IoT Operations コンポーネントを管理する手順が含まれます。 この機能はいくつかの制限を設けて提供されており、運用環境のワークロードには使用しないでください。
ベータ版、プレビュー版、または一般提供としてまだリリースされていない Azure の機能に適用される法律条項については、「Microsoft Azure プレビューの追加使用条件」を参照してください。
この記事では、MQTT クライアントを使用して非運用環境で MQTT ブローカーへの接続をテストするさまざまな方法について説明します。
既定値の MQTT ブローカー:
サービスの種類として ClusterIp を指定し、ポート 18883 に TLS 対応リスナーを配置します。 ClusterIp は、ブローカーが Kubernetes クラスター内からのみアクセス可能であることを意味します。 クラスターの外部からブローカーにアクセスするには、サービスの種類を LoadBalancer または NodePort として構成する必要があります。
クラスター内からの接続に対して認証用の Kubernetes サービス アカウントのみを受け入れます。 クラスターの外部から接続するには、別の認証方法を構成する必要があります。
注意事項
運用環境のシナリオでは、TLS とサービス アカウント認証を使用して IoT ソリューションをセキュリティで保護する必要があります。 詳細については、以下を参照してください:
- MQTT ブローカーで MQTT 通信をセキュリティで保護するために、自動の証明書管理で TLS を構成する
- MQTT ブローカーで認証を構成する
- Azure Kubernetes Services Edge Essentials でポート フォワーディングまたは仮想スイッチを使用して、Kubernetes サービスを外部デバイスに公開する。
始める前に、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) でリッスンする新しいブローカー リスナーを作成します。
Azure portal で、IoT Operations インスタンスに移動します。
[コンポーネント] で、[MQTT ブローカー] を選択します。
[MQTT broker listener for NodePort]\(NodePort の MQTT ブローカー リスナー\)>[作成] を選択します。 サービスの種類ごとにリスナーを 1 つだけ作成できます。 同じサービスの種類のリスナーが既にある場合は、既存のリスナーにポートをさらに追加できます。
注意事項
認証を [なし] に設定し、TLS をテスト用にのみ認証と TLS をオフにするように構成しません。
次の情報を入力します :
設定 値 名前 aio-broker-nodeport
サービス名 空のままにするか aio-broker-nodeport
ポート 1884 認証 既定または [なし] を選択します 承認 既定または [なし] を選択します Protocol [MQTT] を選択します ノード ポート 31884 ポートで [TLS]>[追加] を選択して、リスナーに TLS 設定を追加します。 テストに TLS が必要ない場合は、この手順は必要ありません。 詳細については、BrokerListener を参照してください。
[作成] を選択し、リスナーを作成します。
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 でリッスンする新しいブローカー リスナーを作成するには、次のようにします。
Azure portal で、IoT Operations インスタンスに移動します。
[コンポーネント] で、[MQTT ブローカー] を選択します。
[MQTT broker listener for NodePort]\(NodePort の MQTT ブローカー リスナー\)>[作成] を選択します。 サービスの種類ごとにリスナーを 1 つだけ作成できます。 同じサービスの種類のリスナーが既にある場合は、既存のリスナーにポートをさらに追加できます。
注意事項
認証を [なし] に設定し、TLS をテスト用にのみ認証と TLS をオフにするように構成しません。
次の情報を入力します :
設定 値 名前 aio-broker-loadbalancer
サービス名 空のままにするか aio-broker-loadbalancer
ポート 1883 認証 既定または [なし] を選択します 承認 既定または [なし] を選択します Protocol [MQTT] を選択します ポートで [TLS]>[追加] を選択して、リスナーに TLS 設定を追加します。 テストに TLS が必要ない場合は、この手順は必要ありません。 詳細については、BrokerListener を参照してください。
[作成] を選択し、リスナーを作成します。
[作成] を選択し、リスナーを作成します。
次のように、ブローカーのサービスの外部 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 が割り当てられていない場合は、ポート フォワーディングまたは仮想スイッチを使用してブローカーにアクセスすることが必要になる場合があります。
ポート フォワーディングの使用
minikube、kind、およびその他のクラスター エミュレーション システムでは、外部 IP が自動的に割り当てられない可能性があります。 たとえば、保留中状態として表示される場合があります。
ブローカーにアクセスするには、ブローカー リスニング ポートをホストに転送します。
# 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
ターミナルでポート フォワーディング コマンドを実行したままにします。
ポート フォワーディングを行わずに、例と同じ認証と TLS 構成でホスト ポートでブローカーに接続します。
minikube の詳細については、ポート フォワーディングを使用してクラスターにあるアプリケーションにアクセスすることに関する記事をご覧ください
AKS Edge Essentials でのポート フォワーディング
Azure Kubernetes Services Edge Essentials の場合は、いくつかの手順を追加で実行する必要があります。 AKS Edge Essentials では、外部 IP アドレスを取得するだけではブローカーに接続できない場合があります。 ブローカーのサービスへのトラフィックを許可するには、ポート フォワーディングを設定し、ファイアウォールでポートを開く必要がある場合があります。
まず、ブローカーのロード バランサー リスナーの外部 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
外部 IP アドレス
192.168.0.4
とポート1883
で、broker-loadbalancer
サービスへのポート フォワーディングを設定します。netsh interface portproxy add v4tov4 listenport=1883 connectport=1883 connectaddress=192.168.0.4
ファイアウォールでポートを開き、ブローカーのサービスへのトラフィックを許可します。
New-NetFirewallRule -DisplayName "AIO MQTT Broker" -Direction Inbound -Protocol TCP -LocalPort 1883 -Action Allow
ホストのパブリック 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 攻撃につながる可能性があります。
警告
リスクを理解したうえで、必要があり、管理の行き届いた環境で安全でないポートを使用する場合は、リスナーの構成から tls
と authenticationRef
を削除することで、テスト目的で TLS と認証をオフにすることができます。
Azure portal で、IoT Operations インスタンスに移動します。
[コンポーネント] で、[MQTT ブローカー] を選択します。
[NodePort の MQTT ブローカー リスナー] または [LoadBalancer の MQTT ブローカー リスナー]>[作成] を選択します。 サービスの種類ごとにリスナーを 1 つだけ作成できます。 同じサービスの種類のリスナーが既にある場合は、既存のリスナーにポートをさらに追加できます。
注意事項
認証を [なし] に設定し、TLS をテスト用にのみ認証と TLS をオフにするように構成しません。
次の情報を入力します :
設定 値 名前 リスナーの名前を入力します サービス名 サービスの名前を入力します ポート ポート番号を入力します 認証 [なし] を選択します 承認 [なし] を選択します Protocol [MQTT] を選択します ノード ポート ノード ポートを使用している場合は、30000 から 32767 の範囲の値を入力します [作成] を選択し、リスナーを作成します。