你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
重要
本页包含使用 Kubernetes 部署清单(目前为预览版)管理 Azure IoT 操作组件的说明。 此功能存在若干限制,不应该用于生产工作负载。
有关 beta 版本、预览版或尚未正式发布的版本的 Azure 功能所适用的法律条款,请参阅 Microsoft Azure 预览版的补充使用条款。
本文展示了在非生产性环境中使用 MQTT 客户端测试与 MQTT 代理的连接的不同方法。
默认情况下,MQTT 代理:
- 在端口 18883 上部署启用了传输层安全性 (TLS) 协议的侦听器,服务类型为
ClusterIp。ClusterIp只能从 Kubernetes 群集内访问代理。 要从群集外部访问代理,必须配置LoadBalancer或NodePort类型的服务。 - 仅接受 用于身份验证的 Kubernetes 服务帐户,用于从群集内部进行连接。 若要从群集外部进行连接,则必须配置不同的身份验证方法。
注意
对于生产场景,请使用 TLS 和服务帐户身份验证来保护 IoT 解决方案。 有关详细信息,请参阅:
- 使用自动证书管理来配置 TLS,以保护 MQTT 代理中的 MQTT 通信。
- 在 MQTT 代理中配置身份验证。
- 使用端口转发或 Azure Kubernetes Services (AKS) Edge Essentials 中的虚拟交换机向外部设备暴露 Kubernetes 服务。
在开始之前,请安装或配置 Azure IoT 操作。 使用以下选项在非生产性环境中使用 MQTT 客户端测试与 MQTT 客户端的连接。
连接到群集内的默认侦听器
第一个选项是从群集内部进行连接。 此选项使用默认配置,无需额外的更新。 以下示例显示了如何使用普通 Alpine Linux 和常用的 MQTT 客户端,通过使用服务帐户和默认根证书颁发机构 (CA) 证书,在群集内进行连接。
从 GitHub 示例存储库下载 mqtt-client.yaml 部署。
重要
请勿在生产环境中使用 MQTT 客户端。 该客户端仅用于测试目的。
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/mqtt-client.yaml
pod/mqtt-client created
Pod 运行后,使用 kubectl exec 在 Pod 中运行命令。
例如,若要将消息发布到中转站,请在 Pod 中打开 shell:
kubectl exec --stdin --tty mqtt-client --namespace azure-iot-operations -- sh
在 Pod 的 shell 中运行以下命令,以将消息发布到中转站:
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 文档所示。
例如,要使用 NodePort 服务类型、服务名称 aio-broker-nodeport 和侦听端口 1884(节点端口 31884)创建新的代理侦听器,请执行以下步骤。
在 Azure 门户中,转到 IoT 操作实例。
在“组件”下,选择“MQTT 代理”。
选择“NodePort 的 MQTT 代理监听器”“创建”>。 每个服务类型只能创建一个侦听器。 如果已有相同服务类型的侦听器,则可以向现有侦听器添加更多端口。
输入以下设置:
设置 值 名称 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,则可能使用的是默认情况下不会公开节点的外部 IP 地址的 Kubernetes 设置,例如 k3s、k3d 或 minikube 的许多设置。 在这种情况下,可以使用内部 IP 以及节点端口从同一网络上的计算机访问代理。 例如,若要获取节点的内部 IP 地址,请使用以下代码:
kubectl get nodes -o yaml | grep InternalIP -C 1
输出应类似于以下示例:
- address: 172.19.0.2
type: InternalIP
allocatable:
然后,使用内部 IP 地址和节点端口从同一群集中的计算机连接到代理。 如果 Kubernetes 在本地计算机上运行(例如使用单节点 k3s 时),则通常可以使用 localhost,而不是内部 IP 地址。 如果 Kubernetes 在 Docker 容器中运行(例如使用 k3d 时),则内部 IP 地址对应于容器的 IP 地址,并且应该可从主机访问。
负载均衡器
向 Internet 暴露代理的另一种方法是使用 LoadBalancer 服务类型。 此方法更为复杂,可能需要更多配置,例如设置端口转移。
例如,要使用 LoadBalancer 服务类型、服务名称 aio-broker-loadbalancer 和侦听端口 1883 创建新的代理侦听器,请执行以下步骤。
在 Azure 门户中,转到 IoT 操作实例。
在“组件”下,选择“MQTT 代理”。
选择“NodePort 的 MQTT 代理监听器”“创建”>。 每个服务类型只能创建一个侦听器。 如果已有相同服务类型的侦听器,则可以向现有侦听器添加更多端口。
输入以下设置:
设置 值 名称 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、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 边缘软件包上的端口转移
对于 AKS 边缘软件包,还需执行几个步骤。 使用 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 地址
broker-loadbalancer和端口192.168.0.4上设置到1883服务的端口转移: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 代理。
例如,要创建将 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 代理暴露于互联网可能会导致未授权的访问,甚至分布式拒绝服务攻击。
警告
如果你了解相关风险,并且需要在控制良好的环境中使用不安全的端口,可以通过从侦听器配置中移除 tls 和 authenticationRef 设置来关闭 TLS 和身份验证,以便进行测试。
在 Azure 门户中,转到 IoT 操作实例。
在“组件”下,选择“MQTT 代理”。
选择适用于 NodePort 的 MQTT 代理侦听器,或者适用于 LoadBalancer 的 MQTT 代理侦听器>创建。 每个服务类型只能创建一个侦听器。 如果已有相同服务类型的侦听器,则可以向现有侦听器添加更多端口。
输入以下设置:
设置 值 名称 输入侦听器的名称。 服务名称 输入服务名称。 端口 输入端口号。 身份验证 选择“无”。 授权 选择“无”。 协议 选择“MQTT”。 节点端口 如果使用节点端口,请输入介于 30000 到 32767 之间的数字。 选择“创建”以创建侦听器。