共用方式為


使用 MQTT 用戶端測試 MQTT 代理程式連線能力

重要

此頁面包含使用 Kubernetes 部署指令清單來管理 Azure IoT Operations 元件的指示,其處於預覽狀態。 這項功能隨附 數個限制,不應用於生產工作負載。

請參閱 Microsoft Azure 預覽版增補使用規定,以了解適用於 Azure 功能 (搶鮮版 (Beta)、預覽版,或尚未正式發行的版本) 的法律條款。

本文展示在非商業執行環境中使用 MQTT 用戶端來測試 MQTT 代理程式連線能力的不同方式。

根據預設,MQTT 代理程式會:

警告

針對實際執行案例,您應該使用 TLS 和服務帳戶驗證來保護 IoT 解決方案。 如需詳細資訊,請參閱

在開始之前,請先安裝或設定 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):

  1. 在 Azure 入口網站 中,移至您的 IoT 作業實例。

  2. 在 [Azure IoT 作業資源] 底下,選取 [MQTT 訊息代理程式]。

  3. 選取 NodePort>Create 的 MQTT 訊息代理程式接聽程式。 每個服務類型只能建立一個接聽程式。 如果您已經有相同服務類型的接聽程式,您可以將更多埠新增至現有的接聽程式。

    警告

    將驗證設定為 [無 ],且未設定 TLS 只會關閉驗證,而 TLS 僅供測試之用。

    輸入下列設定:

    設定
    名稱 aio-broker-nodeport
    服務名稱 保留空白或 aio-broker-nodeport
    連接埠 1884
    驗證 從現有或 無中選擇
    授權 從現有或 無中選擇
    通訊協定 選擇 MQTT
    節點埠 31884
  4. 選取埠上的 [TLS>新增],將 TLS 設定新增至接聽程式。 如果您不需要 TLS 進行測試,則不需要此步驟。 如需詳細資訊,請參閱 BrokerListener

  5. 選取 [建立 ] 以建立接聽程式。

注意

根據 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 建立新的訊息代理程式接聽程式:

  1. 在 Azure 入口網站 中,移至您的 IoT 作業實例。

  2. 在 [Azure IoT 作業資源] 底下,選取 [MQTT 訊息代理程式]。

  3. 選取 NodePort>Create 的 MQTT 訊息代理程式接聽程式。 每個服務類型只能建立一個接聽程式。 如果您已經有相同服務類型的接聽程式,您可以將更多埠新增至現有的接聽程式。

    警告

    將驗證設定為 [無 ],且未設定 TLS 只會關閉驗證,而 TLS 僅供測試之用。

    輸入下列設定:

    設定
    名稱 aio-broker-loadbalancer
    服務名稱 保留空白或 aio-broker-loadbalancer
    連接埠 1883
    驗證 從現有或 無中選擇
    授權 從現有或 無中選擇
    通訊協定 選擇 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,您可能需要使用埠轉送或虛擬交換器來存取訊息代理程式。

使用連接埠轉送

對於 minikube種類及其他叢集模擬系統,可能不會自動指派外部 IP。 例如,它可能會顯示為擱置狀態。

  1. 若要存取訊息代理程式,請將接聽埠 18883 的訊息代理程序轉送至主機。

    kubectl port-forward --namespace azure-iot-operations service/aio-broker 18883:mqtts-18883
    
  2. 使用 127.0.0.1 連線到埠 18883 的訊息代理程式,其驗證和 TLS 組態與範例相同,而不需埠轉送。

如需 minikube 的詳細資訊,請參閱使用連接埠轉送來存取叢集中的應用程式

AKS 邊緣程式集上的連接埠轉送

針對 Azure Kubernetes Services 邊緣程式集,您需要執行一些額外的步驟。 使用 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 訊息代理程式。

如需連接埠轉送的詳細資訊,請參閱將 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 攻擊。

警告

如果您了解風險,而且需要在受控制良好的環境中使用不安全的埠,您可以從接聽程式組態中移除 tlsauthenticationRef 設定,以關閉 TLS 和驗證以供測試之用。

  1. 在 Azure 入口網站 中,移至您的 IoT 作業實例。

  2. 在 [Azure IoT 作業資源] 底下,選取 [MQTT 訊息代理程式]。

  3. 針對 NodePort 選取 MQTT 訊息代理程式接聽程式,或針對 LoadBalancer Create 選取 MQTT 訊息代理程式接聽程式>。 每個服務類型只能建立一個接聽程式。 如果您已經有相同服務類型的接聽程式,您可以將更多埠新增至現有的接聽程式。

    警告

    將驗證設定為 [無 ],且未設定 TLS 只會關閉驗證,而 TLS 僅供測試之用。

    輸入下列設定:

    設定
    名稱 輸入接聽程序的名稱
    服務名稱 輸入服務名稱
    連接埠 輸入埠號碼
    驗證 選擇 [無]
    授權 選擇 [無]
    通訊協定 選擇 MQTT
    節點埠 如果使用節點埠,請輸入介於 30000-32767 之間的數位
  4. 選取 [建立 ] 以建立接聽程式。