Kubernetes

從我的 kubernetes 集群外部訪問 Mosquitto MQTT

  • October 14, 2021

我的 minikube 上有以下 Mosquitto 設置:

部署:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: mosquitto
 namespace: mosquitto
spec:
 replicas: 1
 selector:
   matchLabels:
     name: mosquitto
 template:
   metadata:
     labels:
       name: mosquitto
   spec:
     containers:
       - name: mosquitto
         image: eclipse-mosquitto:2.0.12
         ports:
         - containerPort: 1883
         volumeMounts:
         - name: mosquitto-config
           mountPath: /mosquitto/config/mosquitto.conf
           subPath: mosquitto.conf
     volumes:
     - name: mosquitto-config
       configMap:
         name: mosquitto-configmap  

配置圖:

apiVersion: v1
kind: ConfigMap
metadata:
 name: mosquitto-configmap
 namespace: mosquitto
data:
 mosquitto.conf: |-
   listener 1883
   allow_anonymous true  

服務:

apiVersion: v1
kind: Service
metadata:
 name: mosquitto-service
spec:
 type: NodePort
 selector:
   name: mosquitto
 ports:
   - protocol: TCP
     port: 1883
     targetPort: 1883
     nodePort: 30007  

現在我想從我的區域網路訪問我的部署。在我的主機 Windows 機器上使用 MQTT-Explorer 進行測試。使用 mqtt://localhost:30007 不起作用。已知該設置與埠轉發一起使用。

$ k port-forward mosquitto-66d69df7c9-zrvgt 1111:1883
Forwarding from 127.0.0.1:1111 -> 1883
Forwarding from [::1]:1111 -> 1883
Handling connection for 1111

我想我誤解了服務部分。最後,服務應該可以從我的 LAN 中訪問:

額外問題:如何將服務路由到 mqtt.local 之類的東西?Kubernetes Ingress 對我也不起作用,猜測是因為它僅用於 HTTP

ANodePort分配集群內部的 IP,因此需要埠轉發。

要將內部埠傳遞給外部埠,您需要spec.typeLoadBalancer.

我發現術語“LoadBalancer”令人困惑,因為它與 AWS 等服務用於他們自己的負載均衡器(例如 Amazon 中的 ELB)的術語相衝突。在 Kubernetes 中,LoadBalancer服務將在與您指定的條件匹配的任何 pod 之間進行負載平衡,或者在本例中僅匹配一個。

訣竅是,如果您在具有實際負載均衡器的環境中,那麼該服務將自動映射到外部負載均衡器,以便您可以使用真實 IP 訪問該服務。

這也可以使用 an 來完成,Ingress但只能用於帶有入口控制器(例如 NGINX)的 http 和 https 服務。因為 MQTT 是一種不同的協議,所以服務用於傳遞連接。

就我而言,我不在雲服務上,因此預設情況下沒有像 ELB 這樣的負載均衡器 - 您必須添加自己的負載均衡器(請參閱我的意思是混淆)。我在集群中安裝了一個本地 MetalLB 負載均衡器,該埠神奇地出現在我分配的一個本地 IP 池中。

從那裡您只需要設置 DNS(可能在您的路由器中),以便您想要的名稱與分配的 IP 相對應。我的代理現在出現在mqtt.local1883 埠

這是對我有用的yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: mosquitto
 namespace: mosquitto
spec:
 replicas: 1
 selector:
   matchLabels:
     name: mosquitto
 template:
   metadata:
     labels:
       name: mosquitto
   spec:
     containers:
       - name: mosquitto
         image: eclipse-mosquitto:2.0.12
         ports:
         - containerPort: 1883
         volumeMounts:
         - name: mosquitto-config
           mountPath: /mosquitto/config/mosquitto.conf
           subPath: mosquitto.conf
     volumes:
     - name: mosquitto-config
       configMap:
         name: mosquitto-configmap  
---
apiVersion: v1
kind: ConfigMap
metadata:
 name: mosquitto-configmap
 namespace: mosquitto
data:
 mosquitto.conf: |-
   listener 1883
   allow_anonymous true 
---
apiVersion: v1
kind: Service
metadata:
 name: mosquitto-service
 namespace: mosquitto
 annotations:           # <-- Which IP pool to use
   metallb.universe.tf/address-pool: lb-static-ips
spec:
 type: LoadBalancer # <-- Changed
 selector:
   name: mosquitto
 ports:
   - name: mosquitto
     protocol: TCP
     port: 1883
     targetPort: 1883
     # nodePort: 30007  <--- LoadBalancer will figure this out

…這是 metalLB 的 YAML:

apiVersion: v1
kind: ConfigMap
metadata:
 namespace: metallb-system
 name: config
data:
 config: |
   address-pools:
   - name: http # one IP address for virtual http hosts
     protocol: layer2
     addresses:
     - 10.3.3.152/32

   - name: lb-static-ips #  IP addresses for services
     protocol: layer2
     addresses:
     - 10.3.3.153-10.3.3.160

引用自:https://serverfault.com/questions/1079642