我无法通过 Kubernetes(RPI 集群上的 K3s)连接到 MQTT
I cant connect to MQTT over Kubernetes (K3s on RPI Cluster)
大家好,我遇到了一些障碍。我能够成功 运行 我的 yaml 文件并为 MQTT 获取容器 运行ning。问题是当我尝试连接到它时,它就是不起作用。这是我的 YAML 文件
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: mqtt
name: mqtt
namespace: mqtt
spec:
replicas: 2
selector:
matchLabels:
io.kompose.service: mqtt
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: mqtt
spec:
containers:
- image: eclipse-mosquitto
name: mqtt
ports:
- containerPort: 1883
- containerPort: 9001
resources: {}
volumeMounts:
- name: mosquitto-config-file
mountPath: /mosquitto/config
- name: mosquitto-pwfile
mountPath: /mosquitto/config/pwfile
- name: mqtt-data-pvc
mountPath: /mosquitto/data
- name: mqtt-log-pvc
mountPath: /mosquitto/log
restartPolicy: Always
volumes:
- name: mosquitto-config-file
configMap:
name: mosquitto-config
- name: mosquitto-pwfile
secret:
secretName: mosquitto-pwfile
- name: mqtt-data-pvc
persistentVolumeClaim:
claimName: mqtt-data-pvc
- name: mqtt-log-pvc
persistentVolumeClaim:
claimName: mqtt-log-pvc
status: {}
---
apiVersion: v1
kind: Service
metadata:
name: mqtt
namespace: mqtt
spec:
ports:
- name: "1883"
port: 1883
targetPort: 1883
- name: "9001"
port: 9001
targetPort: 9001
selector:
io.kompose.service: mqtt
status:
loadBalancer: {}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mosquitto-config
namespace: mqtt
data:
mosquitto.conf: |
persistence true
persistence_location /mosquitto/data
log_dest file /mosquitto/log/mosquitto.log
listener 1883
protocol mqtt
listener 9001
protocol websockets
allow_anonymous false
password_file /mosquitto/config/pwfile/pwfile
---
apiVersion: v1
kind: Secret
metadata:
name: mosquitto-pwfile
namespace: mqtt
type: Opaque
data:
pwfile: |
<BASE64 USERNAME:PW>
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mosquitto-data-pv
namespace: mqtt
spec:
capacity:
storage: 100Mi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-path
local:
path: /home/pi/Software/mqtt/storage/mosquitto/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- masternode
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mqtt-data-pvc
namespace: mqtt
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mosquitto-log-pv
namespace: mqtt
spec:
capacity:
storage: 100Mi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-path
local:
path: /home/pi/Software/mqtt/storage/mosquitto/log
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- masternode
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mqtt-log-pvc
namespace: mqtt
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mqtt-ingress
namespace: mqtt
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
rules:
- host: mqtt.local
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: mqtt
port:
number: 1883
当我检查我的容器是否 运行ning 时,它们 运行ning 正常。当我检查日志时,它显示以下内容
1618785757: mosquitto version 2.0.10 starting
1618785757: Config loaded from /mosquitto/config/mosquitto.conf.
1618785757: Opening ipv4 listen socket on port 1883.
1618785757: Opening ipv6 listen socket on port 1883.
1618785757: Opening websockets listen socket on port 9001.
1618785757: mosquitto version 2.0.10 running
我尝试在端口 1883 上连接 mqtt.local(根据入口),但日志没有更新,它只是说使用我的 iPad 应用连接
如果我在浏览器上访问 mqtt.local,日志会更新(我相信他们正在使用 websockets)
它显示以下内容
1618786368: Client <unknown> disconnected due to protocol error.
1618786368: New connection from 10.42.1.3:48912 on port 1883.
1618786368: Client <unknown> disconnected due to protocol error.
1618786368: New connection from 10.42.1.3:57298 on port 1883.
1618786368: Client <unknown> disconnected due to protocol error.
我会说实话。我很困惑。十几次确认用户名和密码。如果有人想分享一些想法,请敞开心扉。提前致谢
您的 Ingress 声明指向端口 1883,它是 运行 基于 TCP 的本机 MQTT。
Ingress 设置一个指向该服务的 HTTP 反向代理,因为 MQTT 不是 HTTP,所以这将不起作用。
正如评论中所指出的,一种选择是将 Ingress 更改为指向端口 9001,这是代理上的 WebSocket 侦听器
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mqtt-ingress
namespace: mqtt
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
rules:
- host: mqtt.local
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: mqtt
port:
number: 9001
然后您将能够连接任何支持 MQTT over Websockets 的 MQTT 客户端,因为该协议是通过 HTTP 引导的。
还值得指出的是,Ingress 反向代理将在端口 80 上公开此路由。
唯一的其他连接方式是直接连接到作为 运行 MQTT 代理的集群节点。但这意味着将 ServiceType 更改为 NodePort 或 LoadBalancer 并映射外部 IP 地址。
我刚刚检查了上面的 post,我猜问题是“应用”的顺序 - 如果 kubectl 应用是使用上面的 yaml 文件创建的,那么首先加载部署,然后加载 configMap (s) 稍后。必须首先加载 configMap,以便部署组件可以使用它们。
大家好,我遇到了一些障碍。我能够成功 运行 我的 yaml 文件并为 MQTT 获取容器 运行ning。问题是当我尝试连接到它时,它就是不起作用。这是我的 YAML 文件
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: mqtt
name: mqtt
namespace: mqtt
spec:
replicas: 2
selector:
matchLabels:
io.kompose.service: mqtt
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: mqtt
spec:
containers:
- image: eclipse-mosquitto
name: mqtt
ports:
- containerPort: 1883
- containerPort: 9001
resources: {}
volumeMounts:
- name: mosquitto-config-file
mountPath: /mosquitto/config
- name: mosquitto-pwfile
mountPath: /mosquitto/config/pwfile
- name: mqtt-data-pvc
mountPath: /mosquitto/data
- name: mqtt-log-pvc
mountPath: /mosquitto/log
restartPolicy: Always
volumes:
- name: mosquitto-config-file
configMap:
name: mosquitto-config
- name: mosquitto-pwfile
secret:
secretName: mosquitto-pwfile
- name: mqtt-data-pvc
persistentVolumeClaim:
claimName: mqtt-data-pvc
- name: mqtt-log-pvc
persistentVolumeClaim:
claimName: mqtt-log-pvc
status: {}
---
apiVersion: v1
kind: Service
metadata:
name: mqtt
namespace: mqtt
spec:
ports:
- name: "1883"
port: 1883
targetPort: 1883
- name: "9001"
port: 9001
targetPort: 9001
selector:
io.kompose.service: mqtt
status:
loadBalancer: {}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mosquitto-config
namespace: mqtt
data:
mosquitto.conf: |
persistence true
persistence_location /mosquitto/data
log_dest file /mosquitto/log/mosquitto.log
listener 1883
protocol mqtt
listener 9001
protocol websockets
allow_anonymous false
password_file /mosquitto/config/pwfile/pwfile
---
apiVersion: v1
kind: Secret
metadata:
name: mosquitto-pwfile
namespace: mqtt
type: Opaque
data:
pwfile: |
<BASE64 USERNAME:PW>
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mosquitto-data-pv
namespace: mqtt
spec:
capacity:
storage: 100Mi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-path
local:
path: /home/pi/Software/mqtt/storage/mosquitto/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- masternode
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mqtt-data-pvc
namespace: mqtt
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mosquitto-log-pv
namespace: mqtt
spec:
capacity:
storage: 100Mi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-path
local:
path: /home/pi/Software/mqtt/storage/mosquitto/log
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- masternode
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mqtt-log-pvc
namespace: mqtt
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mqtt-ingress
namespace: mqtt
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
rules:
- host: mqtt.local
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: mqtt
port:
number: 1883
当我检查我的容器是否 运行ning 时,它们 运行ning 正常。当我检查日志时,它显示以下内容
1618785757: mosquitto version 2.0.10 starting
1618785757: Config loaded from /mosquitto/config/mosquitto.conf.
1618785757: Opening ipv4 listen socket on port 1883.
1618785757: Opening ipv6 listen socket on port 1883.
1618785757: Opening websockets listen socket on port 9001.
1618785757: mosquitto version 2.0.10 running
我尝试在端口 1883 上连接 mqtt.local(根据入口),但日志没有更新,它只是说使用我的 iPad 应用连接
如果我在浏览器上访问 mqtt.local,日志会更新(我相信他们正在使用 websockets) 它显示以下内容
1618786368: Client <unknown> disconnected due to protocol error.
1618786368: New connection from 10.42.1.3:48912 on port 1883.
1618786368: Client <unknown> disconnected due to protocol error.
1618786368: New connection from 10.42.1.3:57298 on port 1883.
1618786368: Client <unknown> disconnected due to protocol error.
我会说实话。我很困惑。十几次确认用户名和密码。如果有人想分享一些想法,请敞开心扉。提前致谢
您的 Ingress 声明指向端口 1883,它是 运行 基于 TCP 的本机 MQTT。
Ingress 设置一个指向该服务的 HTTP 反向代理,因为 MQTT 不是 HTTP,所以这将不起作用。
正如评论中所指出的,一种选择是将 Ingress 更改为指向端口 9001,这是代理上的 WebSocket 侦听器
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mqtt-ingress
namespace: mqtt
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
rules:
- host: mqtt.local
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: mqtt
port:
number: 9001
然后您将能够连接任何支持 MQTT over Websockets 的 MQTT 客户端,因为该协议是通过 HTTP 引导的。
还值得指出的是,Ingress 反向代理将在端口 80 上公开此路由。
唯一的其他连接方式是直接连接到作为 运行 MQTT 代理的集群节点。但这意味着将 ServiceType 更改为 NodePort 或 LoadBalancer 并映射外部 IP 地址。
我刚刚检查了上面的 post,我猜问题是“应用”的顺序 - 如果 kubectl 应用是使用上面的 yaml 文件创建的,那么首先加载部署,然后加载 configMap (s) 稍后。必须首先加载 configMap,以便部署组件可以使用它们。