使用 MQTT 用戶端測試 MQTT 代理程式連線能力
重要
此頁面包含使用 Kubernetes 部署指令清單來管理 Azure IoT Operations 元件的指示,其處於預覽狀態。 這項功能隨附 數個限制,不應用於生產工作負載。
請參閱 Microsoft Azure 預覽版增補使用規定,以了解適用於 Azure 功能 (搶鮮版 (Beta)、預覽版,或尚未正式發行的版本) 的法律條款。
本文說明在非生產環境中,使用 MQTT 用戶端測試與 MQTT 訊息代理程式連線的不同方式。
根據預設,MQTT 訊息代理程式:
- 在 埠 18883 上部署啟用傳輸層安全性 (TLS) 的通訊協定接聽程式 ,並
ClusterIp
作為服務類型。ClusterIp
表示訊息代理程式只能從 Kubernetes 叢集中存取。 若要從叢集外部存取訊息代理程式,您必須設定 類型LoadBalancer
為 或NodePort
的服務。 - 接受 Kubernetes 服務帳戶對叢集內的連線進行驗證。 若要從叢集外部連線,您必須設定不同的驗證方法。
警告
針對生產案例,請使用 TLS 和服務帳戶驗證來保護IoT解決方案。 如需詳細資訊,請參閱
開始之前, 請先安裝或設定 Azure IoT 作業。 使用下列選項,在非生產環境中測試與 MQTT 代理程式與 MQTT 用戶端的連線。
線上到叢集內的預設接聽程式
第一個選項是從叢集內連線。 此選項會使用預設組態,而且不需要額外的更新。 下列範例示範如何使用純 Alpine Linux 和常用的 MQTT 用戶端,使用服務帳戶和預設跟證書授權單位 (CA) 憑證,從叢集中連線。
mqtt-client.yaml
從 GitHub 範例存放庫下載部署。
重要
請勿在生產環境中使用 MQTT 用戶端。 用戶端僅供測試之用。
wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/mqtt-client.yaml -O mqtt-client.yaml
使用 kubectl 套用部署檔案:
kubectl apply -f mqtt-client.yaml
pod/mqtt-client created
執行 Pod 之後,請使用 kubectl exec
在 Pod 內執行命令。
例如,若要將訊息發佈至訊息代理程式,請在 Pod 內開啟殼層:
kubectl exec --stdin --tty mqtt-client --namespace azure-iot-operations -- sh
在 Pod 的殼層內,執行下列命令,將訊息發佈至訊息代理程式:
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 憑證向訊息代理程式進行驗證,並訂閱主題。
若要移除 Pod,請執行 kubectl delete pod mqtt-client -n azure-iot-operations
。
從叢集外部連線用戶端
由於預設訊息代理程式接聽程式設定為ClusterIp
服務類型,因此您無法直接從叢集外部連線到訊息代理程式。 若要防止內部 IoT 作業元件之間的通訊意外中斷,建議您讓預設接聽程式保持未修改且專用於 IoT 作業內部通訊。 雖然可以建立個別的 Kubernetes LoadBalancer
服務來公開叢集 IP 服務,但最好建立具有不同設定的個別接聽程式,例如更常見的 MQTT 埠 1883 和 8883,以避免混淆和潛在的安全性風險。
節點埠
測試連線的最簡單方式是在接聽程式中使用 NodePort
服務類型。 透過該方法,您可以使用 <nodeExternalIP>:<NodePort>
來連線,如 Kubernetes 檔所示。
例如,若要使用服務類型、服務名稱aio-broker-nodeport
及接聽埠 1884(節點埠 31884)建立新的訊息代理程式接聽程式NodePort
,請遵循下列步驟。
在 Azure 入口網站 中,移至您的 IoT 作業實例。
在 [元件] 底下,選取 [MQTT Broker]。
選取 NodePort>Create 的 MQTT 訊息代理程式接聽程式。 每個服務類型只能建立一個接聽程式。 如果您已經有相同服務類型的接聽程式,您可以將更多埠新增至現有的接聽程式。
警告
將驗證設定為 [無 ],且未設定 TLS 只會關閉驗證,而 TLS 僅供測試之用。
輸入下列設定:
設定 值 名稱 aio-broker-nodeport
服務名稱 保留空白或使用 aio-broker-nodeport
。連接埠 1884 驗證 從現有的 或 [無] 中選擇。 授權 從現有的 或 [無] 中選擇。 通訊協定 選擇 [MQTT]。 節點埠 31884 選取埠上的 [TLS>新增],將 TLS 設定新增至接聽程式。 如果您不需要 TLS 進行測試,則不需要此步驟。 如需詳細資訊,請參閱 BrokerListener。
選取 [建立 ] 以建立接聽程式。
注意
根據 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,您可能會使用 Kubernetes 安裝程式,預設不會公開節點的外部IP位址,例如 k3s、k3d 或minikube的許多設定。 在此情況下,您可以使用內部 IP 以及來自相同網路上電腦的節點埠來存取訊息代理程式。 例如,若要取得節點的內部IP位址:
kubectl get nodes -o yaml | grep InternalIP -C 1
輸出應類似下列範例:
- address: 172.19.0.2
type: InternalIP
allocatable:
然後,使用內部IP位址和節點埠,從相同叢集內的電腦連線到訊息代理程式。 如果 Kubernetes 是在本機電腦上執行,就像使用單一節點 k3 一樣,您通常 localhost
可以使用,而不是內部 IP 位址。 如果 Kubernetes 正在 Docker 容器中執行,例如 k3d,內部 IP 位址會對應至容器的 IP 位址,而且應該可從主電腦連線。
負載平衡器
另一種向因特網公開訊息代理程式的方式是使用 LoadBalancer
服務類型。 此方法比較複雜,而且可能需要更多設定,例如設定埠轉送。
例如,若要使用服務類型、服務名稱aio-broker-loadbalancer
及接聽埠 1883 建立新的訊息代理程式接聽程式LoadBalancer
,請遵循下列步驟。
在 Azure 入口網站 中,移至您的 IoT 作業實例。
在 [元件] 底下,選取 [MQTT Broker]。
選取 NodePort>Create 的 MQTT 訊息代理程式接聽程式。 每個服務類型只能建立一個接聽程式。 如果您已經有相同服務類型的接聽程式,您可以將更多埠新增至現有的接聽程式。
警告
將驗證設定為 [無 ],且未設定 TLS 只會關閉驗證,而 TLS 僅供測試之用。
輸入下列設定:
設定 值 名稱 aio-broker-loadbalancer
服務名稱 保留空白或使用 aio-broker-loadbalancer
。連接埠 1883 驗證 從現有的 或 [無] 中選擇。 授權 從現有的 或 [無] 中選擇。 通訊協定 選擇 [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、種類及其他叢集模擬系統,可能不會自動指派外部 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 邊緣程式集上的連接埠轉送
針對 AKS 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 訊息代理程式。
如需連接埠轉送的詳細資訊,請參閱將 Kubernetes 服務公開至外部裝置。
透過localhost存取
某些 Kubernetes 散發套件可以將 MQTT 訊息代理程式公開 至主機系統 (localhost
) 上的埠,作為叢集設定的一部分。 使用此方法可讓相同主機上的用戶端更容易存取 MQTT 訊息代理程式。
例如,若要建立 k3d 叢集,將 MQTT 訊息代理程式的預設 MQTT 連接埠 1883 對應至 localhost:1883
:
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 和驗證。 在沒有驗證的情況下向因特網公開 MQTT 訊息代理程式,而 TLS 可能會導致未經授權的存取,甚至是分散式阻斷服務攻擊。
警告
如果您了解風險,而且需要在受控制良好的環境中使用不安全的埠,您可以從接聽程式組態中移除 tls
和 authenticationRef
設定,以關閉 TLS 和驗證以供測試之用。
在 Azure 入口網站 中,移至您的 IoT 作業實例。
在 [元件] 底下,選取 [MQTT Broker]。
針對 NodePort 選取 MQTT 訊息代理程式接聽程式,或針對 LoadBalancer Create 選取 MQTT 訊息代理程式接聽程式>。 每個服務類型只能建立一個接聽程式。 如果您已經有相同服務類型的接聽程式,您可以將更多埠新增至現有的接聽程式。
警告
將驗證設定為 [無 ],且未設定 TLS 只會關閉驗證,而 TLS 僅供測試之用。
輸入下列設定:
設定 值 名稱 輸入接聽程序的名稱。 服務名稱 輸入服務名稱。 連接埠 輸入埠號碼。 驗證 選擇 [無]。 授權 選擇 [無]。 通訊協定 選擇 [MQTT]。 節點埠 如果使用節點埠,請輸入介於 30000 到 32767 之間的數位。 選取 [建立 ] 以建立接聽程式。