如何使用 emqx-operator 建立 EMQX 服務到 Kubernetes 上。
Note
emqx-operator 是用 Helm 的腳本,可以快速定義 EMXQ 服務。
引用 Github 上的架構圖,如下:
從架構圖上可以看到兩款 EMQX Operator、EMQX Cluster 則為我們要建立的服務。
EMQX Operator
為 EMQX 的 CRD,是需要最先建立的資源,建立命令如下。
helm upgrade --install emqx-operator emqx/emqx-operator \
--namespace emqx-operator-system \
--create-namespace \
--version 2.2.5 -f values.yaml
上面命令包括了 values.yaml 檔案,內容如下。主要是使服務更可以建立在指定的 nodes 中。
image:
repository: emqx/emqx-operator-controller
tag: 2.2.5
imagePullSecrets: []
replicaCount: 1
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "lindu-tech/server"
operator: In
values:
- "infra"
tolerations:
- key: "lindu-tech/server"
operator: "Exists"
effect: "NoSchedule"
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app.kubernetes.io/name"
operator: In
values:
- "emqx-operator"
topologyKey: "kubernetes.io/hostname"
EMQX Cluster
建立好 EMQX Operator 後,可以使用 Kind: EMQX,接著才建立 EMQX Cluster。
創建一個 emqx-cluster.yaml 檔案,內容如下。服務只開啟了 listeners.tcp.default,其他因為使用不到所以皆關閉。其服務是使用 nodePort 的方式揭露,port 的位置需自行地義,不要衝突。
apiVersion: apps.emqx.io/v2beta1
kind: EMQX
metadata:
name: emqx
spec:
image: emqx:5.3.2
config:
data: |
listeners.tcp.default {
enable = true
bind = "0.0.0.0:1883"
max_connections = 1024
max_conn_rate = "1000/s"
}
listeners.wss.default {
enable = false
}
listeners.ssl.default {
enable = false
}
listeners.ws.default {
enable = false
}
coreTemplate:
spec:
volumeClaimTemplates:
storageClassName: sas
resources:
requests:
storage: 5Mi
accessModes:
- ReadWriteOnce
replicas: 1
resources:
requests:
cpu: 200m
memory: 256Mi
replicantTemplate:
spec:
replicas: 1
resources:
requests:
cpu: 250m
memory: 256Mi
listenersServiceTemplate:
spec:
type: NodePort
ports:
# - name: wss-default
# nodePort: 31081
# port: 8084
# protocol: TCP
# targetPort: 8084
# - name: ssl-default
# nodePort: 31082
# port: 8883
# protocol: TCP
# targetPort: 8883
- name: tcp-default
nodePort: 31083
port: 1883
protocol: TCP
targetPort: 1883
# - name: ws-default
# nodePort: 31084
# port: 8083
# protocol: TCP
# targetPort: 8083
dashboardServiceTemplate:
spec:
type: NodePort
ports:
- name: tcp-default
nodePort: 32083
port: 18083
protocol: TCP
targetPort: 18083
定義建立好後,運行下面命令創建資源,資源會建立在預設的 namespace 中。
kubectl apply -f emqx-cluster.yaml
# 確認資源狀態
kubectl get emqx
NAME STATUS AGE
emqx Ready 5d18h
配置 SSL 連線
EMQX 有整合 cert-manager 服務,可以透過配置執行憑證的申請,但是憑證只能在與 EMQX Operator 同個 namespace 中,以上面的命令為例就會建立在 namespace emqx-operator-system 裡面。
如果 EMQX Operator 與 EMQX Cluster 不在同個 namespace 中的話,就會取不到憑證,所以要另外配置,下面為配置方式。
收先要先使用 cert-manager 做憑證的申請並建立 secret,建立一個 test-mqtt.example.com.yaml 檔案,內容如下。
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
labels:
app.kubernetes.io/instance: emqx
app.kubernetes.io/name: emqx
name: test-mqtt.example.com
spec:
dnsNames:
- test-mqtt.example.com
duration: 2160h0m0s
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-http01
renewBefore: 360h0m0s
secretName: test-mqtt.example.com
usages:
- digital signature
- key encipherment
運行上面定義的 yaml 來建立資源,執行憑證的申請。
kubectl apply -f test-mqtt.example.com.yaml
接著配置 EMQX Cluster 的憑證掛載,
apiVersion: apps.emqx.io/v2beta1
kind: EMQX
metadata:
name: emqx
spec:
image: emqx:5.3.2
config:
data: |
listeners.tcp.default {
enable = true
bind = "0.0.0.0:1883"
max_connections = 1024
max_conn_rate = "1000/s"
}
listeners.ssl.default {
enable = true
bind = "0.0.0.0:8883"
max_connections = 1024
max_conn_rate = "1000/s"
ssl_options {
cacertfile = "/mounted/cert/ca.crt"
certfile = "/mounted/cert/tls.crt"
keyfile = "/mounted/cert/tls.key"
gc_after_handshake = true
handshake_timeout = 5s
}
}
listeners.wss.default {
enable = false
}
listeners.ws.default {
enable = false
}
coreTemplate:
spec:
volumeClaimTemplates:
storageClassName: sas
resources:
requests:
storage: 5Mi
accessModes:
- ReadWriteOnce
replicas: 1
resources:
requests:
cpu: 200m
memory: 256Mi
extraVolumes:
- name: emqx-tls
secret:
secretName: test-mqtt.example.com
extraVolumeMounts:
- name: emqx-tls
mountPath: /mounted/cert
replicantTemplate:
spec:
replicas: 1
resources:
requests:
cpu: 250m
memory: 256Mi
extraVolumes:
- name: emqx-tls
secret:
secretName: test-mqtt.example.com
extraVolumeMounts:
- name: emqx-tls
mountPath: /mounted/cert
listenersServiceTemplate:
spec:
type: NodePort
ports:
# - name: wss-default
# nodePort: 30712
# port: 8084
# protocol: TCP
# targetPort: 8084
- name: ssl-default
nodePort: 31082
port: 8883
protocol: TCP
targetPort: 8884
- name: tcp-default
nodePort: 31083
port: 1883
protocol: TCP
targetPort: 1884
# - name: ws-default
# nodePort: 31394
# port: 8083
# protocol: TCP
# targetPort: 8083
dashboardServiceTemplate:
spec:
type: NodePort
ports:
- name: tcp-default
nodePort: 32084
port: 18083
protocol: TCP
targetPort: 18083
接著執行配置更新,就可以使用 mqtts:// 來做連線。
kubectl apply -f emqx-cluster.yaml
test
使用工具 mqttx 工具做測試,看連線次是否有成功建立。