问题描述
订阅和发布到运行在Kubernetes集群上的Mosquitto服务器时遇到麻烦。
我知道我的服务和吊舱正在运行。我可以使用mosquitto服务作为主机从集群内部进行订阅和发布。
我还有一个正常工作的HTTPS网关,因此我可以从外部访问https://mosquittourl.com.br,并且可以看到它到达了端口1883上的mosquitto容器。容器日志:
New connection from 127.0.0.1 on port 1883.
Client <unkNown> disconnected due to protocol error.
我猜这是预期的行为。因为我通过https而不是mqtt访问它。
现在,我无法使用以下方式连接到容器
$ mosquitto_pub --url mqtt://mosquittourl.com.br:<port>/test
如何正确设置Istio资源,以便可以订阅和发布到mosquitto服务器?有没有一种方法可以配置Istio接受mqtt请求并将其重定向到我的mosquitto服务?
解决方法
我最近能够设置 Istio 以将 TLS 加密的 MQTT 连接路由到
Mosquitto 在 Kubernetes 的容器中运行。您应该使用 TLS 作为 Istio Gateway 中端口的 protocol
。最终,Istio 可能会像支持 gRPC 和 Mongo 一样支持 MQTT,但现在您需要使用 TCP 来处理未加密的 MQTT 流量,并使用 TLS 来确保安全的 MQTT 连接。
您需要确保正确配置才能使其正常工作。
-
Istio 操作员配置文件 yaml 文件
对于为 Istio 配置主负载均衡器的
IstioOperator
,您需要确保设置正确的端口。对于安全的 MQTT 流量,即 8883(从技术上讲,您可以使用任何端口,但 8883 是默认端口)。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
accessLogFile: /dev/stdout
components:
egressGateways:
- name: istio-egressgateway
enabled: true
k8s:
resources:
requests:
cpu: 10m
memory: 40Mi
ingressGateways:
- name: istio-ingressgateway
enabled: true
k8s:
resources:
requests:
cpu: 10m
memory: 40Mi
service:
ports:
- port: 15021
targetPort: 15021
name: status-port
- port: 31400
targetPort: 31400
name: tcp
# This is the port where sni routing happens
- port: 15443
targetPort: 15443
name: tls
- port: 8883
targetPort: 8883
name: mqtt-secure
pilot:
k8s:
env:
- name: PILOT_TRACE_SAMPLING
value: "100"
resources:
requests:
cpu: 10m
memory: 100Mi
values:
global:
proxy:
resources:
requests:
cpu: 10m
memory: 40Mi
pilot:
autoscaleEnabled: false
gateways:
istio-egressgateway:
autoscaleEnabled: false
istio-ingressgateway:
autoscaleEnabled: false
runAsRoot: true
- Istio 网关 yaml 文件
这里的重要部分是确保您指定您在 Kubernetes 机密中已有的 SSL 证书的名称,并使用您在 IstioOperator 中所做的相同端口,并确保协议是 TLS。 tls:
块告诉网关使用指定的 SSL 证书进行 TLS 终止。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-mqtt-ssl-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 8883
name: mqtt-secure
protocol: TLS
hosts:
- "*"
tls:
credentialName: cert-my.certname.com
mode: SIMPLE
privateKey: sds
serverCertificate: sds
- Istio 虚拟服务 yaml 文件
最后一步是设置 Istio 虚拟服务,该服务从 Istio 网关获取流量并将其路由到正确的 Pod。更新目标中的 pod 名称。另一方面是匹配 8883 端口,并将流量重新路由到 1883 端口上的 mosquitto,因为流量已经在 Istio 网关中被 TLS 终止。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-mqtt-vs
spec:
hosts:
- "*"
gateways:
- my-mqtt-ssl-gateway
tcp:
- match:
- port: 8883
route:
- destination:
host: my-mqtt-broker-pod-name
port:
number: 1883