使用 MQTT 用戶端測試 MQTT 代理程式連線能力
重要
此頁面包含使用 Kubernetes 部署指令清單來管理 Azure IoT Operations 元件的指示,其處於預覽狀態。 這項功能隨附 數個限制,不應用於生產工作負載。
請參閱 Microsoft Azure 預覽版增補使用規定,以了解適用於 Azure 功能 (搶鮮版 (Beta)、預覽版,或尚未正式發行的版本) 的法律條款。
本文展示在非商業執行環境中使用 MQTT 用戶端來測試 MQTT 代理程式連線能力的不同方式。
根據預設,MQTT 代理程式會:
使用 ClusterIp 作為服務類型,在埠 18883 上部署已啟用 TLS 的接聽程式。 ClusterIp 表示訊息代理程式只能從 Kubernetes 叢集中存取。 若要從叢集外部存取訊息代理程式,您必須設定類型為 LoadBalancer 或 NodePort 的服務。
接受 Kubernetes 服務帳戶對叢集內的連線進行驗證。 若要從叢集外部連線,您必須設定不同的驗證方法。
警告
針對實際執行案例,您應該使用 TLS 和服務帳戶驗證來保護 IoT 解決方案。 如需詳細資訊,請參閱
- 在 MQTT 代理程式中使用自動憑證管理設定 TLS 以保護 MQTT 通訊 (部分機器翻譯)
- 在 MQTT 訊息代理程式中設定驗證 (部分機器翻譯)
- 搭配使用連接埠轉送或虛擬交換器與 Azure Kubernetes Services 邊緣程式集,以將 Kubernetes 服務公開至外部裝置。
在開始之前,請先安裝或設定 IoT 作業 (部分機器翻譯)。 使用下列選項,以在非商業執行環境中測試 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
執行 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 服務類型,因此您無法直接從叢集外部連線到訊息代理程式。 若要防止內部 Azure IoT 作業元件之間的通訊意外中斷,建議您讓預設接聽程式保持未修改且專用於 AIO 內部通訊。 雖然可以建立個別的 Kubernetes LoadBalancer 服務來公開叢集 IP 服務,但最好建立具有不同設定的個別接聽程式,例如更常見的 MQTT 埠 1883 和 8883,以避免混淆和潛在的安全性風險。
節點埠
測試連線的最簡單方式是在接聽程式中使用 NodePort 服務類型。 如此一來,您可以使用 <nodeExternalIP>:<NodePort>
來像 Kubernetes 檔中一樣連線。
例如,若要使用節點埠服務類型、服務名稱 aio-broker-nodeport
及接聽埠 1884 建立新的訊息代理程式接聽程式(節點埠 31884):
在 Azure 入口網站 中,移至您的 IoT 作業實例。
在 [Azure IoT 作業資源] 底下,選取 [MQTT 訊息代理程式]。
選取 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 建立新的訊息代理程式接聽程式:
在 Azure 入口網站 中,移至您的 IoT 作業實例。
在 [Azure IoT 作業資源] 底下,選取 [MQTT 訊息代理程式]。
選取 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。 例如,它可能會顯示為擱置狀態。
若要存取訊息代理程式,請將接聽埠 18883 的訊息代理程序轉送至主機。
kubectl port-forward --namespace azure-iot-operations service/aio-broker 18883:mqtts-18883
使用 127.0.0.1 連線到埠 18883 的訊息代理程式,其驗證和 TLS 組態與範例相同,而不需埠轉送。
如需 minikube 的詳細資訊,請參閱使用連接埠轉送來存取叢集中的應用程式
AKS 邊緣程式集上的連接埠轉送
針對 Azure Kubernetes Services 邊緣程式集,您需要執行一些額外的步驟。 使用 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 和驗證。 在沒有驗證和 TLS 的情況下將 MQTT 代理程式公開至網際網路,可能會導致未經授權的存取,甚至是 DDOS 攻擊。
警告
如果您了解風險,而且需要在受控制良好的環境中使用不安全的埠,您可以從接聽程式組態中移除 tls
和 authenticationRef
設定,以關閉 TLS 和驗證以供測試之用。
在 Azure 入口網站 中,移至您的 IoT 作業實例。
在 [Azure IoT 作業資源] 底下,選取 [MQTT 訊息代理程式]。
針對 NodePort 選取 MQTT 訊息代理程式接聽程式,或針對 LoadBalancer Create 選取 MQTT 訊息代理程式接聽程式>。 每個服務類型只能建立一個接聽程式。 如果您已經有相同服務類型的接聽程式,您可以將更多埠新增至現有的接聽程式。
警告
將驗證設定為 [無 ],且未設定 TLS 只會關閉驗證,而 TLS 僅供測試之用。
輸入下列設定:
設定 值 名稱 輸入接聽程序的名稱 服務名稱 輸入服務名稱 連接埠 輸入埠號碼 驗證 選擇 [無] 授權 選擇 [無] 通訊協定 選擇 MQTT 節點埠 如果使用節點埠,請輸入介於 30000-32767 之間的數位 選取 [建立 ] 以建立接聽程式。