Prueba de la conectividad con el corredor MQTT con clientes MQTT
Importante
Versión preliminar de operaciones de Azure IoT: habilitada por Azure Arc está actualmente en versión preliminar. No se debería usar este software en versión preliminar en entornos de producción.
Deberá implementar una nueva instalación de Azure IoT Operations cuando esté disponible una versión general. No podrá actualizar una instalación de versión preliminar.
Consulte Términos de uso complementarios para las versiones preliminares de Microsoft Azure para conocer los términos legales que se aplican a las características de Azure que se encuentran en la versión beta, en versión preliminar o que todavía no se han publicado para que estén disponibles con carácter general.
En este artículo se muestran diferentes formas de probar la conectividad con el corredor MQTT con clientes MQTT en un entorno de no producción.
De manera predeterminada, el corredor MQTT:
Implementa un cliente de escucha habilitado para TLS en el puerto 18883 con ClusterIp como tipo de servicio. ClusterIp significa que solo se puede acceder al agente desde el clúster de Kubernetes. Para acceder al agente desde fuera del clúster, debe configurar un servicio de tipo LoadBalancer o NodePort.
Acepta cuentas de servicio de Kubernetes para la autenticación de conexiones desde el clúster. Para conectarse desde fuera del clúster, debe configurar un método de autenticación diferente.
Precaución
En escenarios de producción, debe usar la autenticación de cuentas de servicio y TLS para proteger la solución de IoT. Para más información, vea:
- Configurar TLS con administración automática de certificados para asegurar la comunicación MQTT en el corredor MQTT
- Configuración de la autenticación en el corredor MQTT
- Exponga los servicios de Kubernetes a dispositivos externos mediante el reenvío de puertos o un conmutador virtual con Azure Kubernetes Services Edge Essentials.
Antes de comenzar, instale o configure operaciones de loT. Use las siguientes opciones para probar la conectividad con el corredor MQTT con clientes MQTT en un entorno de no producción.
Conexión desde un pod dentro del clúster con la configuración predeterminada
La primera opción es conectarse desde el clúster. Esta opción usa la configuración predeterminada y no requiere actualizaciones adicionales. En los ejemplos siguientes se muestra cómo conectarse desde dentro del clúster mediante Alpine Linux sin formato y un cliente MQTT usado habitualmente, mediante la cuenta de servicio y el certificado de CA raíz predeterminado.
Cree un archivo denominado
client.yaml
con el código de configuración siguiente: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 which comes with default deployment # 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: mq-sat mountPath: /var/run/secrets/tokens - name: trust-bundle mountPath: /var/run/certs volumes: - name: mq-sat projected: sources: - serviceAccountToken: path: mq-sat audience: aio-internal # Must match audience in BrokerAuthentication expirationSeconds: 86400 - name: trust-bundle configMap: name: aio-ca-trust-bundle-test-only # Default root CA cert
Use
kubectl apply -f client.yaml
para implementar la configuración. Solo debe tardar unos segundos en iniciarse.Una vez que se ejecuta el pod, use
kubectl exec
para ejecutar comandos dentro del pod.Por ejemplo, para publicar un mensaje en el agente, abra un shell dentro del pod:
kubectl exec --stdin --tty mqtt-client --namespace azure-iot-operations -- sh
Dentro del shell del pod, ejecute el siguiente comando para publicar un mensaje en el agente:
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/mq-sat)
La salida debe tener una apariencia similar a la siguiente:
Client (null) sending CONNECT Client (null) received CONNACK (0) Client (null) sending PUBLISH (d0, q0, r0, m1, 'world', ... (5 bytes)) Client (null) sending DISCONNECT
El cliente de mosquitto usa el token de cuenta de servicio montado en
/var/run/secrets/tokens/mq-sat
para autenticarse con el agente. El token es válido durante 24 horas. El cliente también usa el certificado de CA raíz predeterminado montado en/var/run/certs/ca.crt
para comprobar la cadena de certificados TLS del agente.Para suscribirse al tema, ejecute el siguiente comando:
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/mq-sat)
La salida debe tener una apariencia similar a la siguiente:
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
El cliente de mosquitto usa el mismo token de cuenta de servicio y certificado de CA raíz para autenticarse con el agente y suscribirse al tema.
Para quitar el pod, ejecute
kubectl delete pod mqtt-client -n azure-iot-operations
.
Conexión de clientes desde fuera del clúster al puerto TLS predeterminado
Cadena de confianza TLS
Dado que el agente usa TLS, el cliente debe confiar en la cadena de certificados TLS del agente. Debe configurar el cliente para que confíe en el certificado de entidad de certificación raíz usado por el agente.
Para usar el certificado de CA raíz predeterminado, descárguelo de ConfigMap aio-ca-trust-bundle-test-only
:
kubectl get configmap aio-ca-trust-bundle-test-only -n azure-iot-operations -o jsonpath='{.data.ca\.crt}' > ca.crt
Use el archivo ca.crt
descargado para configurar el cliente para que confíe en la cadena de certificados TLS del agente.
Si se conecta al agente desde otro espacio de nombres, debe usar el nombre de host de servicio completo aio-broker.azure-iot-operations.svc.cluster.local
. También debe agregar el nombre DNS al certificado de servidor mediante la inclusión de un campo DNS de nombre alternativo de firmante (SAN) al recurso BrokerListener. Para obtener más información, consulte Configuración de parámetros de certificado de servidor.
Autenticación con el agente
De manera predeterminada, el corredor MQTT solo acepta cuentas de servicio de Kubernetes para la autenticación para las conexiones desde dentro del clúster. Para conectarse desde fuera del clúster, debe configurar un método de autenticación diferente, como X.509. Para obtener más información, consulte Configuración de la autenticación.
Desactivar la autenticación sirve solo con fines de prueba
Para desactivar la autenticación con fines de prueba, edite el recurso BrokerListener
y establezca el campo authenticationEnabled
en false
:
Precaución
La desactivación de la autenticación solo debe usarse con fines de prueba con un clúster de prueba que no sea accesible desde Internet.
kubectl patch brokerlistener listener -n azure-iot-operations --type='json' -p='[{"op": "replace", "path": "/spec/authenticationEnabled", "value": false}]'
Conectividad del puerto
Algunas distribuciones de Kubernetes pueden exponer el corredor MQTT a un puerto en el sistema host (localhost). Debe usar este enfoque porque facilita que los clientes del mismo host accedan al corredor MQTT.
Por ejemplo, para crear un clúster K3d con la asignación del puerto MQTT predeterminado del corredor MQTT 18883 a localhost:18883:
k3d cluster create --port '18883:18883@loadbalancer'
Pero para que este método funcione con el corredor MQTT, debe configurarlo para que use un equilibrador de carga en lugar de la dirección IP del clúster. Hay dos maneras de hacerlo: crear un equilibrador de carga o aplicar revisiones al tipo de servicio de recursos BrokerListener predeterminado existente para el equilibrador de carga.
Opción 1: Crear un equilibrador de carga
Cree un archivo denominado
loadbalancer.yaml
con el código de configuración siguiente:apiVersion: v1 kind: Service metadata: name: iotmq-public-svc spec: type: LoadBalancer ports: - name: mqtt1 port: 18883 targetPort: 18883 selector: app: broker app.kubernetes.io/instance: broker app.kubernetes.io/managed-by: dmqtt-operator app.kubernetes.io/name: dmqtt tier: frontend
Aplique la configuración para crear un servicio de equilibrador de carga:
kubectl apply -f loadbalancer.yaml
Opción 2: Revisión del equilibrador de carga predeterminado
Edite el recurso
BrokerListener
y cambie el camposerviceType
aloadBalancer
.kubectl patch brokerlistener listener --namespace azure-iot-operations --type='json' --patch='[{"op": "replace", "path": "/spec/serviceType", "value": "loadBalancer"}]'
Espere a que se actualice el servicio.
kubectl get service aio-broker --namespace azure-iot-operations
La salida debe tener una apariencia similar a la siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE aio-broker LoadBalancer 10.43.107.11 XXX.XX.X.X 18883:30366/TCP 14h
Puede usar la dirección IP externa para conectarse al corredor MQTT a través de Internet. Asegúrese de usar la dirección IP externa en lugar de
localhost
.mosquitto_pub --qos 1 --debug -h XXX.XX.X.X --message hello --topic world --username client1 --pw password --cafile ca.crt
Sugerencia
Puede usar la dirección IP externa para conectarse al corredor MQTT desde fuera del clúster. Si ha usado el comando K3d con la opción de reenvío de puertos, puede usar localhost
para conectarse al agente MQTT. Por ejemplo, para conectarse con el cliente de mosquitto:
mosquitto_pub --qos 1 --debug -h localhost --message hello --topic world --username client1 --pw password --cafile ca.crt --insecure
En este ejemplo, el cliente de mosquitto usa el nombre de usuario y la contraseña para autenticarse con el agente junto con el certificado de CA raíz para comprobar la cadena de certificados TLS del agente. Aquí, la marca --insecure
es necesaria porque el certificado TLS predeterminado emitido al equilibrador de carga solo es válido para el nombre de servicio predeterminado del equilibrador de carga (aio-broker) y las direcciones IP asignadas, no localhost.
Nunca exponga el puerto del corredor MQTT a Internet sin autenticación ni TLS. Esto es peligroso y puede provocar un acceso no autorizado a los dispositivos IoT y traer tráfico no solicitado al clúster.
Para obtener información sobre cómo agregar localhost al nombre alternativo del firmante (SAN) del certificado para evitar el uso de la marca no segura, consulte Configuración de parámetros de certificado de servidor.
Uso del reenvío de puertos
Con minikube, kind y otros sistemas de emulación de clúster, es posible que no se asigne automáticamente una dirección IP externa. Por ejemplo, podría mostrarse como estado Pendiente.
Para acceder al corredor, reenvíe el puerto de escucha 18883 del corredor al host.
kubectl port-forward --namespace azure-iot-operations service/aio-broker 18883:mqtts-18883
Use 127.0.0.1 para conectarse al corredor en el puerto 18883 con la misma autenticación y configuración de TLS que el ejemplo sin reenvío de puertos.
El reenvío de puertos también es útil para probar el corredor MQTT localmente en la máquina de desarrollo sin tener que modificar la configuración del agente. Para más información sobre minikube, vea Uso del enrutamiento de puerto para acceder a aplicaciones en un clúster
Enrutamiento de puerto en AKS Edge Essentials
Para Edge Essentials de Azure Kubernetes Services, debe realizar algunos pasos adicionales. Para más información sobre el enrutamiento de puerto, vea Exposición de servicios de Kubernetes a dispositivos externos.
Imagine que el servicio del agente se expone a una dirección IP externa mediante un equilibrador de carga. Por ejemplo, si ha revisado el equilibrador de carga predeterminado
aio-broker
, obtenga la dirección IP externa del servicio.kubectl get service aio-broker --namespace azure-iot-operations
La salida debe tener una apariencia similar a la siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE aio-broker LoadBalancer 10.43.107.11 192.168.0.4 18883:30366/TCP 14h
Configure el enrutamiento de puerto al servicio
aio-broker
en la dirección IP externa192.168.0.4
y el puerto18883
:netsh interface portproxy add v4tov4 listenport=18883 connectport=18883 connectaddress=192.168.0.4
Abra el puerto en el firewall para permitir el tráfico al servicio del agente:
New-NetFirewallRule -DisplayName "AIO MQTT Broker" -Direction Inbound -Protocol TCP -LocalPort 18883 -Action Allow
Use la dirección IP pública del host para conectarse al agente MQTT.
Sin TLS y sin autenticación
La razón por la que el corredor MQTT usa la autenticación TLS y las cuentas de servicio de forma predeterminada es proporcionar una experiencia segura de manera predeterminada que minimiza la exposición involuntaria de la solución de IoT a los atacantes. No debe desactivar TLS ni la autenticación en producción.
Precaución
No use en producción. Exponer el corredor MQTT a Internet sin autenticación y TLS puede provocar accesos no autorizados e incluso ataques DDOS.
Si comprende los riesgos y necesita usar un puerto no seguro en un entorno bien controlado, puede desactivar TLS y la autenticación con fines de prueba siguiendo estos pasos:
Cree un nuevo recurso
BrokerListener
sin la configuración de TLS:apiVersion: mqttbroker.iotoperations.azure.com/v1beta1 kind: BrokerListener metadata: name: non-tls-listener namespace: azure-iot-operations spec: brokerRef: default serviceType: loadBalancer serviceName: my-unique-service-name authenticationEnabled: false authorizationEnabled: false port: 1883
Los campos
authenticationEnabled
yauthorizationEnabled
se establecen enfalse
para desactivar la autenticación y la autorización. El campoport
se establece en1883
para usar el puerto MQTT común.Espere a que se actualice el servicio.
kubectl get service my-unique-service-name --namespace azure-iot-operations
La salida debe tener una apariencia similar a la siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-unique-service-name LoadBalancer 10.43.144.182 XXX.XX.X.X 1883:31001/TCP 5m11s
El nuevo puerto 1883 está disponible.
Use el cliente mosquitto para conectarse al agente:
mosquitto_pub --qos 1 --debug -h localhost --message hello --topic world
La salida debe tener una apariencia similar a la siguiente:
Client mosq-7JGM4INbc5N1RaRxbW sending CONNECT Client mosq-7JGM4INbc5N1RaRxbW received CONNACK (0) Client mosq-7JGM4INbc5N1RaRxbW sending PUBLISH (d0, q1, r0, m1, 'world', ... (5 bytes)) Client mosq-7JGM4INbc5N1RaRxbW received PUBACK (Mid: 1, RC:0) Client mosq-7JGM4INbc5N1RaRxbW sending DISCONNECT