文章目录
- 安装方式一:快速部署
- 安装方式二:定制化部署
- 1. 使用 Pod 直接部署 EMQX Broker
- 2. 使用 Deoloyment 部署 Pod
- 3. 使用 Services 公开 EMQX Broker Pod 服务
- 4. 通过 kubernetes 自动集群 EMQX MQTT 服务器
- 5. 修改 EMQX Broker 的配置
安装方式一:快速部署
添加 helm 仓库:
$ helm repo add emqx https://repos.emqx.io/charts# 查询 EMQX
$ helm search repo emqx
启动 EMQX 集群,设置 service.type=NodePort
$ helm install my-emqx emqx/emqx --set service.type=NodePort
NAME: my-emqx
LAST DEPLOYED: Thu Jul 11 10:56:16 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
查看 EMQX 集群情况:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-emqx-0 0/1 ContainerCreating 0 12s <none> master-01 <none> <none>
my-emqx-1 0/1 ContainerCreating 0 12s <none> worker-02 <none> <none>
my-emqx-2 0/1 ContainerCreating 0 12s <none> worker-01 <none> <none>$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-emqx-0 1/1 Running 0 3m7s 172.20.32.158 master-01 <none> <none>
my-emqx-1 1/1 Running 0 3m7s 172.20.58.232 worker-02 <none> <none>
my-emqx-2 1/1 Running 0 3m7s 172.20.85.250 worker-01 <none> <none>$ kubectl exec -it my-emqx-0 -- emqx_ctl status
Node 'my-emqx@my-emqx-0.my-emqx-headless.default.svc.cluster.local' 5.7.1 is started$ kubectl exec -it my-emqx-0 -- emqx_ctl cluster status
Cluster status: #{running_nodes =>['my-emqx@my-emqx-0.my-emqx-headless.default.svc.cluster.local','my-emqx@my-emqx-1.my-emqx-headless.default.svc.cluster.local','my-emqx@my-emqx-2.my-emqx-headless.default.svc.cluster.local'],stopped_nodes => []}
查看 EMQX service:
$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
service/my-emqx NodePort 10.68.183.22 <none> 1883:32596/TCP,8883:31933/TCP,8083:32522/TCP,8084:32535/TCP,18083:32717/TCP 10m app.kubernetes.io/instance=my-emqx,app.kubernetes.io/name=emqx
service/my-emqx-headless ClusterIP None <none> 1883/TCP,8883/TCP,8083/TCP,8084/TCP,18083/TCP,4370/TCP 10m app.kubernetes.io/instance=my-emqx,app.kubernetes.io/name=emqx# 也可以执行该命令查看全部
$ sudo kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/my-emqx-0 1/1 Running 0 10m 172.20.32.158 master-01 <none> <none>
pod/my-emqx-1 1/1 Running 0 10m 172.20.58.232 worker-02 <none> <none>
pod/my-emqx-2 1/1 Running 0 10m 172.20.85.250 worker-01 <none> <none>NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
service/my-emqx NodePort 10.68.183.22 <none> 1883:32596/TCP,8883:31933/TCP,8083:32522/TCP,8084:32535/TCP,18083:32717/TCP 10m app.kubernetes.io/instance=my-emqx,app.kubernetes.io/name=emqx
service/my-emqx-headless ClusterIP None <none> 1883/TCP,8883/TCP,8083/TCP,8084/TCP,18083/TCP,4370/TCP 10m app.kubernetes.io/instance=my-emqx,app.kubernetes.io/name=emqxNAME READY AGE CONTAINERS IMAGES
statefulset.apps/my-emqx 3/3 10m emqx emqx/emqx:5.7.1
可以看到 my-emqx 的 18083 端口对应的宿主机的 32717 端口。(NodePort 在每次部署的时候都会变化,以实际部署时为准。)
访问 Kubernetes 的任意一台节点 IP 的 32717 端口,输入默认用户名:admin,默认密码:public,登陆 EMQX dashboard。
删除 EMQX 集群:
$ helm uninstall my-emqx
release "my-emqx" uninstalled
参考:
在K8S上部署EMQX企业版集群
安装方式二:定制化部署
参考自:从零开始建立 EMQX MQTT 服务器的 K8S 集群
1. 使用 Pod 直接部署 EMQX Broker
EMQX Broker 在 docker hub 上提供了镜像, 因此可以很方便的在单个的 pod 上部署 EMQX Broker,使用 kubectl run 命令创建一个运行着 EMQX Broker 的 Pod:
$ kubectl run emqx --image=emqx/emqx:v4.1-rc.1 --generator=run-pod/v1
error: unknown flag: --generator
See 'kubectl run --help' for usage.$ kubectl run emqx --image=emqx/emqx:v4.1-rc.1
pod/emqx created
查看 EMQX Broker 的状态:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
emqx 0/1 ContainerCreating 0 8s <none> master-01 <none> <none>$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
emqx 1/1 Running 0 97s 172.20.32.139 master-01 <none> <none>$ kubectl exec emqx -- emqx_ctl status
Node 'emqx@172.20.32.139' is started
emqx 4.1-rc.1 is running
删除 Pod:
$ kubectl delete pods emqx
pod "emqx" deleted
Pod 并不是被设计成一个持久化的资源,它不会在调度失败,节点崩溃,或者其他回收中(比如因为资源的缺乏,或者其他的维护中)幸存下来,因此,还需要一个控制器来管理 Pod。
2. 使用 Deoloyment 部署 Pod
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的 ReplicationController 来方便的管理应用。典型的应用场景包括:
- 定义Deployment来创建Pod和ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续Deployment
使用 Deployment 部署一个 EMQX Broker Pod:
$ vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: emqx-deploymentlabels:app: emqx
spec:replicas: 1selector:matchLabels:app: emqxtemplate:metadata:labels:app: emqxspec:containers:- name: emqximage: emqx/emqx:v4.1-rc.1ports:- name: mqttcontainerPort: 1883- name: mqttsslcontainerPort: 8883- name: mgmtcontainerPort: 8081- name: wscontainerPort: 8083- name: wsscontainerPort: 8084- name: dashboardcontainerPort: 18083
部署 Deployment:
$ kubectl apply -f deployment.yaml
deployment.apps/emqx-deployment created
查看部署情况:
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
emqx-deployment 0/1 1 0 49s$ kubectl get pods
NAME READY STATUS RESTARTS AGE
emqx-deployment-75bd4f75b6-wf9sh 1/1 Running 0 73s$ kubectl exec pod/emqx-deployment-75bd4f75b6-wf9sh -- emqx_ctl status
Node 'emqx-deployment-75bd4f75b6-wf9sh@172.20.58.199' is started
emqx 4.1-rc.1 is running$ kubectl get pods
NAME READY STATUS RESTARTS AGE
emqx-deployment-75bd4f75b6-8njhv 1/1 Running 0 55s
尝试手动删除 Pod:
$ kubectl delete pods emqx-deployment-75bd4f75b6-8njhv
pod "emqx-deployment-75bd4f75b6-8njhv" deleted$ kubectl get pods
NAME READY STATUS RESTARTS AGE
emqx-deployment-68fcb4bfd6-2nhh6 1/1 Running 0 59s
输出结果表明成功用 Deployment 部署了 EMQX Broker Pod,即使是此 Pod 被意外终止,Deployment 也会重新创建一个新的 Pod。
3. 使用 Services 公开 EMQX Broker Pod 服务
Kubernetes Pods 是有生命周期的。他们可以被创建,而且销毁不会再启动。 如果使用 Deployment 来运行应用程序,则它可以动态创建和销毁 Pod。
每个 Pod 都有自己的 IP 地址,但是在 Deployment 中,在同一时刻运行的 Pod 集合可能与稍后运行该应用程序的 Pod 集合不同。
这导致了一个问题:如果使用 EMQX Broker Pod 为 MQTT 客户端提供服务,那么客户端应该如何如何找出并跟踪要连接的 IP 地址,以便客户端使用 EMQX Broker 服务呢?
答案是:Service
Service 是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用 Service 将 EMQX Broker Pod 公开为网络服务:
vim service.yaml
apiVersion: v1
kind: Service
metadata:name: emqx-service
spec:selector:app: emqxports:- name: mqttport: 1883protocol: TCPtargetPort: mqtt- name: mqttsslport: 8883protocol: TCPtargetPort: mqttssl- name: mgmtport: 8081protocol: TCPtargetPort: mgmt- name: wsport: 8083protocol: TCPtargetPort: ws- name: wssport: 8084protocol: TCPtargetPort: wss- name: dashboardport: 18083protocol: TCPtargetPort: dashboard
部署 Service:
$ kubectl apply -f service.yaml
service/emqx-service created
查看部署情况
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
emqx-service ClusterIP 10.68.228.164 <none> 1883/TCP,8883/TCP,8081/TCP,8083/TCP,8084/TCP,18083/TCP 16s
使用 Service 提供的 IP 查看 EMQX Broker 的 API
$ curl 10.68.228.164:8081/status
Node emqx-deployment-75bd4f75b6-8njhv@172.20.32.140 is started
emqx is running
至此,单个 EMQX Broker 节点在 kubernetes 上部署完毕,通过 Deployment 管理 EMQX Broker Pod,通过 Service 将 EMQX Broker 服务暴露出去。
4. 通过 kubernetes 自动集群 EMQX MQTT 服务器
上文中通过 Deployment 部署了单个的 EMQX Broker Pod,通过 Deployment 扩展 Pod 的数量是极为方便的,执行 kubectl scale deployment ${deployment_name} --replicas ${numer}
命令即可扩展 Pod 的数量,下面将 EMQX Broker Pod 扩展为 3 个:
$ kubectl scale deployment emqx-deployment --replicas 3
deployment.apps/emqx-deployment scaled$ kubectl get pods
NAME READY STATUS RESTARTS AGE
emqx-deployment-75bd4f75b6-8njhv 1/1 Running 0 8m41s
emqx-deployment-75bd4f75b6-kjv22 0/1 ContainerCreating 0 12s
emqx-deployment-75bd4f75b6-thcbv 1/1 Running 0 12s$ kubectl exec emqx-deployment-75bd4f75b6-8njhv -- emqx_ctl status
Node 'emqx-deployment-75bd4f75b6-8njhv@172.20.32.140' is started
emqx 4.1-rc.1 is running$ kubectl exec emqx-deployment-75bd4f75b6-8njhv -- emqx_ctl cluster status
Cluster status: #{running_nodes =>['emqx-deployment-75bd4f75b6-8njhv@172.20.32.140'],stopped_nodes => []}
可以看到 EMQX Broker Pod 的数量被扩展为 3 个,但是每个 Pod 都是独立的,并没有集群,接下来尝试通过 kubernetes 自动集群 EMQX Broker Pod。
5. 修改 EMQX Broker 的配置
查看 EMQX Broker 文档中关于 自动集群 的内容,可以看到需要修改 EMQX Broker 的配置:
cluster.discovery = kubernetes
cluster.kubernetes.apiserver = http://10.110.111.204:8080
cluster.kubernetes.service_name = ekka
cluster.kubernetes.address_type = ip
cluster.kubernetes.app_name = ekka
其中 cluster.kubernetes.apiserver
为 kubernetes apiserver
的地址,可以通过 kubectl cluster-info
命令获取,cluster.kubernetes.service_name
为上文中 Service 的 name, cluster.kubernetes.app_name
为 EMQX Broker 的 node.name
中 @
符号之前的部分,所以还需要将集群中 EMQX Broker 设置为统一的 node.name
的前缀。
EMQX Broker 的 docker 镜像提供了通过环境变量修改配置的功能,具体可以查看 docker hub 或 Github。
$ vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: emqx-deploymentlabels:app: emqx
spec:replicas: 3selector:matchLabels:app: emqxtemplate:metadata:labels:app: emqxspec:containers:- name: emqximage: emqx/emqx:v4.1-rc.1ports:- name: mqttcontainerPort: 1883- name: mqttsslcontainerPort: 8883- name: mgmtcontainerPort: 8081- name: wscontainerPort: 8083- name: wsscontainerPort: 8084- name: dashboardcontainerPort: 18083env:- name: EMQX_NAMEvalue: emqx- name: EMQX_CLUSTER__DISCOVERYvalue: k8s- name: EMQX_CLUSTER__K8S__APP_NAMEvalue: emqx- name: EMQX_CLUSTER__K8S__SERVICE_NAMEvalue: emqx-service- name: EMQX_CLUSTER__K8S__APISERVERvalue: "https://kubernetes.default.svc:443"- name: EMQX_CLUSTER__K8S__NAMESPACEvalue: default
因为 kubectl scale deployment ${deployment_name} --replicas ${numer}
命令不会修改 yaml 文件,所以修改 yaml 时需要设置 spec.replicas: 3
。
Pod 中内建 kubernetes 的 DNS 规则,所以 https://kubernetes.default.svc:443
会被解析为 kubernetes apiserver
的地址。
删除之前的 Deployment,重新部署:
$ kubectl delete deployment emqx-deployment
deployment.apps "emqx-deployment" deleted$ root@k8s-master01:/home/ubuntu/huiq/emqx# kubectl apply -f deployment.yaml
deployment.apps/emqx-deployment created