MQTT 클라이언트를 사용하여 MQTT 브로커에 대한 연결 테스트
Important
이 페이지에는 미리 보기 상태인 Kubernetes 배포 매니페스트를 사용하여 Azure IoT Operations 구성 요소를 관리하기 위한 지침이 포함되어 있습니다. 이 기능은 몇 가지 제한 사항을 제공하며 프로덕션 워크로드에 사용하면 안 됩니다.
베타, 미리 보기로 제공되거나 아직 일반 공급으로 릴리스되지 않은 Azure 기능에 적용되는 약관은 Microsoft Azure 미리 보기에 대한 추가 사용 약관을 참조하세요.
이 문서에서는 비프로덕션 환경에서 MQTT 클라이언트를 사용하여 MQTT 브로커에 대한 연결을 테스트하는 다양한 방법을 보여 줍니다.
기본적으로 MQTT 브로커는 다음을 구성합니다.
ClusterIp를 서비스 유형으로 사용하여 포트 18883에 TLS 사용 수신기를 배포합니다. ClusterIp는 Kubernetes 클러스터 내에서만 broker에 액세스할 수 있음을 의미합니다. 클러스터 외부에서 broker에 액세스하려면 LoadBalancer 또는 NodePort 유형의 서비스를 구성해야 합니다.
클러스터 내 연결을 위해 인증을 위한 Kubernetes Service 계정을 허용합니다. 클러스터 외부에서 연결하려면 다른 인증 방법을 구성해야 합니다.
주의
프로덕션 시나리오의 경우 TLS 및 서비스 계정 인증을 사용하여 IoT 솔루션을 보호해야 합니다. 자세한 내용은 다음을 참조하세요.
- MQTT 브로커에서 MQTT 통신을 보호하도록 자동 인증서 관리를 사용하여 TLS 구성
- MQTT 브로커에서 인증 구성
- Azure Kubernetes Services Edge Essentials와 함께 포트 전달 또는 가상 스위치를 사용하여 Kubernetes Service를 외부 디바이스에 노출합니다.
시작하기 전에 IoT 작업을 설치하거나 구성합니다. 개발 및 테스팅 환경에서 MQTT 클라이언트를 사용하여 MQTT 브로커에 대한 연결을 테스트하려면 다음 옵션을 사용합니다.
클러스터 내의 기본 수신기에 연결
첫 번째 옵션은 클러스터 내에서 연결하는 것입니다. 이 옵션은 기본 구성을 사용하며 추가 업데이트가 필요하지 않습니다. 다음 예제에서는 서비스 계정 및 기본 루트 CA 인증서를 사용하여 일반 Alpine Linux 및 일반적으로 사용되는 MQTT 클라이언트를 사용하여 클러스터 내에서 연결하는 방법을 보여 줍니다.
먼저 다음 구성으로 명명된 파일을 만듭니다 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 내에서 명령을 실행합니다.
예를 들어 broker에 메시지를 게시하려면 Pod 내에서 셸을 엽니다.
kubectl exec --stdin --tty mqtt-client --namespace azure-iot-operations -- sh
Pod의 셸 내에서 다음 명령을 실행하여 broker에 메시지를 게시합니다.
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
에서 탑재된 서비스 계정 토큰을 사용하여 broker로 인증합니다. 토큰은 24시간 동안 유효합니다. 또한 클라이언트는 /var/run/certs/ca.crt
에서 탑재된 기본 루트 CA 인증서를 사용하여 broker의 TLS 인증서 체인을 확인합니다.
팁
다른 클라이언트와 함께 사용할 기본 루트 CA 인증서를 다운로드하는 데 사용할 kubectl
수 있습니다. 예를 들어 기본 루트 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 인증서를 사용하여 broker로 인증하고 토픽을 구독합니다.
Pod를 제거하려면 kubectl delete pod mqtt-client -n azure-iot-operations
를 실행합니다.
클러스터 외부에서 클라이언트 연결
기본 broker 수신기는 ClusterIp 서비스 유형으로 설정되므로 클러스터 외부에서 직접 broker에 연결할 수 없습니다. 내부 Azure IoT Operations 구성 요소 간의 통신에 의도하지 않은 중단을 방지하려면 기본 수신기를 수정되지 않고 AIO 내부 통신 전용으로 유지하는 것이 좋습니다. 클러스터 IP 서비스를 노출하는 별도의 Kubernetes LoadBalancer 서비스를 만들 수 있지만 혼동 및 잠재적인 보안 위험을 방지하기 위해 일반적인 MQTT 포트 1883 및 8883과 같은 다른 설정으로 별도의 수신기를 만드는 것이 좋습니다.
노드 포트
연결을 테스트하는 가장 쉬운 방법은 수신기에서 NodePort 서비스 유형을 사용하는 것입니다. 이를 통해 Kubernetes 설명서에서처럼 연결하는 데 사용할 <nodeExternalIP>:<NodePort>
수 있습니다.
예를 들어 노드 포트 서비스 유형, 서비스 이름 aio-broker-nodeport
및 포트 1884(노드 포트 31884)에서 수신 대기하는 새 broker 수신기를 만들려면
Azure Portal에서 IoT Operations 인스턴스로 이동합니다.
구성 요소 아래에서 MQTT Broker를 선택합니다.
NodePort>만들기에 대한 MQTT broker 수신기를 선택합니다. 서비스 유형당 하나의 수신기만 만들 수 있습니다. 동일한 서비스 유형의 수신기가 이미 있는 경우 기존 수신기에 더 많은 포트를 추가할 수 있습니다.
주의
인증을 None으로 설정하고 TLS를 구성하지 않으면 테스트 목적으로만 인증 및 TLS가 해제됩니다.
다음 설정을 입력합니다.
설정 값 속성 aio-broker-nodeport
서비스 이름 비워 두거나 aio-broker-nodeport
포트 1884 인증 기존 또는 없음 중에서 선택 Authorization 기존 또는 없음 중에서 선택 프로토콜 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 주소 및 노드 포트를 사용하여 브로커에 연결합니다. 예를 들어 broker에 메시지를 게시하려면 다음을 수행합니다.
mosquitto_pub --host <EXTERNAL_IP> --port 31884 --message "hello" --topic "world" --debug # Add authentication and TLS options matching listener settings
출력에 외부 IP가 없는 경우 k3s, k3d 또는 minikube의 많은 설정과 같이 기본적으로 노드의 외부 IP 주소를 노출하지 않는 Kubernetes 설정을 사용할 수 있습니다. 이 경우 동일한 네트워크의 컴퓨터에서 노드 포트와 함께 내부 IP를 사용하여 broker에 액세스할 수 있습니다. 예를 들어 노드의 내부 IP 주소를 얻으려면 다음을 수행합니다.
kubectl get nodes -o yaml | grep InternalIP -C 1
출력은 다음과 비슷해야 합니다.
- address: 172.19.0.2
type: InternalIP
allocatable:
그런 다음, 내부 IP 주소와 노드 포트를 사용하여 동일한 클러스터 내의 컴퓨터에서 broker에 연결합니다. Kubernetes가 단일 노드 k3과 같은 로컬 컴퓨터에서 실행되는 경우 내부 IP 주소 대신 사용할 localhost
수 있습니다. Kubernetes가 k3d와 같은 Docker 컨테이너에서 실행되는 경우 내부 IP 주소는 컨테이너의 IP 주소에 해당하며 호스트 컴퓨터에서 연결할 수 있어야 합니다.
부하 분산 장치
브로커를 인터넷에 노출하는 또 다른 방법은 LoadBalancer 서비스 유형을 사용하는 것입니다. 이 메서드는 더 복잡하며 포트 전달 설정과 같은 추가 구성이 필요할 수 있습니다.
예를 들어 부하 분산 장치 서비스 유형, 서비스 이름 aio-broker-loadbalancer
및 포트 1883에서 수신 대기하는 새 broker 수신기를 만들려면 다음을 수행합니다.
Azure Portal에서 IoT Operations 인스턴스로 이동합니다.
구성 요소 아래에서 MQTT Broker를 선택합니다.
NodePort>만들기에 대한 MQTT broker 수신기를 선택합니다. 서비스 유형당 하나의 수신기만 만들 수 있습니다. 동일한 서비스 유형의 수신기가 이미 있는 경우 기존 수신기에 더 많은 포트를 추가할 수 있습니다.
주의
인증을 None으로 설정하고 TLS를 구성하지 않으면 테스트 목적으로만 인증 및 TLS가 해제됩니다.
다음 설정을 입력합니다.
설정 값 속성 aio-broker-loadbalancer
서비스 이름 비워 두거나 aio-broker-loadbalancer
포트 1883 인증 기존 또는 없음 중에서 선택 Authorization 기존 또는 없음 중에서 선택 프로토콜 MQTT 선택 포트에서 TLS 추가를 선택하여 수신기에 TLS>설정을 추가합니다. 테스트에 TLS가 필요하지 않은 경우에는 이 단계가 필요하지 않습니다. 자세한 내용은 BrokerListener를 참조 하세요.
만들기를 선택하여 수신기를 만듭니다.
만들기를 선택하여 수신기를 만듭니다.
broker 서비스에 대한 외부 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 주소와 포트를 사용하여 브로커에 연결할 수 있습니다. 예를 들어 broker에 메시지를 게시하려면 다음을 수행합니다.
mosquitto_pub --host <EXTERNAL_IP> --port 1883 --message "hello" --topic "world" --debug # Add authentication and TLS options matching listener settings
외부 IP가 할당되지 않은 경우 포트 전달 또는 가상 스위치를 사용하여 브로커에 액세스해야 할 수 있습니다.
포트 전달 사용
minikube, 종류 및 기타 클러스터 에뮬레이션 시스템을 사용하면 외부 IP가 자동으로 할당되지 않을 수 있습니다. 예를 들어 보류 중인 상태로 표시될 수 있습니다.
broker에 액세스하려면 broker 수신기 포트를 호스트로 전달합니다.
# 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 구성을 사용하여 호스트 포트의 broker에 연결합니다.
Minikube에 대한 자세한 내용은 포트 전달을 사용하여 클러스터에서 애플리케이션에 액세스를 참조하세요
AKS Edge Essentials의 포트 전달
Azure Kubernetes Services 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 배포판은 클러스터 구성의 일부로 호스트 시스템(localhost)의 포트에 MQTT 브로커를 노출할 수 있습니다. 이 방법을 사용하면 동일한 호스트의 클라이언트가 MQTT broker에 더 쉽게 액세스할 수 있습니다.
예를 들어 MQTT broker의 기본 MQTT 포트 1883을 다음으로 매핑하여 K3d 클러스터를 만들려면 localhost:1883
k3d cluster create --port '1883:1883@loadbalancer'
또는 기존 클러스터를 업데이트하려면 다음을 수행합니다.
k3d cluster edit <CLUSTER_NAME> --port-add '1883:1883@loadbalancer'
그런 다음 포트를 사용하여 localhost
broker에 연결합니다. 예를 들어 broker에 메시지를 게시하려면 다음을 수행합니다.
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 공격도 발생할 수 있습니다.
Warning
위험을 이해하고 잘 제어된 환경에서 안전하지 않은 포트를 사용해야 하는 경우 수신기 구성에서 설정 및 제거하여 테스트 목적으로 TLS 및 authenticationRef
인증을 tls
해제할 수 있습니다.
Azure Portal에서 IoT Operations 인스턴스로 이동합니다.
구성 요소 아래에서 MQTT Broker를 선택합니다.
LoadBalancer 만들기에 대해 NodePort 또는 MQTT broker 수신기에 대한 MQTT broker 수신기를>선택합니다. 서비스 유형당 하나의 수신기만 만들 수 있습니다. 동일한 서비스 유형의 수신기가 이미 있는 경우 기존 수신기에 더 많은 포트를 추가할 수 있습니다.
주의
인증을 None으로 설정하고 TLS를 구성하지 않으면 테스트 목적으로만 인증 및 TLS가 해제됩니다.
다음 설정을 입력합니다.
설정 값 속성 수신기의 이름을 입력합니다. 서비스 이름 서비스 이름 입력 포트 포트 번호 입력 인증 없음 선택 Authorization 없음 선택 프로토콜 MQTT 선택 노드 포트 노드 포트를 사용하는 경우 30000-32767 사이의 숫자를 입력합니다. 만들기를 선택하여 수신기를 만듭니다.