EMQX4.x版本-Docker集群部署与Nginx负载均衡

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

安装

版本选用因为emqx5.x版本不支持tlsv1因此选用4.x版本。

Docker安装

docker pull emqx/emqx:v4.0.0
docker run -d --name emqx -p 1883:1883 -p 8081:8081 -p 8083:8083 -p 8883:8883 -p 8084:8084 -p 18083:18083 emqx/emqx:v4.0.0

# 1883	MQTT 协议端口
# 8883	MQTT/SSL 端口
# 8083	MQTT/WS 协议端口
# 8084	MQTT/WSS 协议端口
# 18083 Dashboard 管理控制台端口

# 8081	

docker exec -it emqx /bin/sh

身份认证

修改配置文件etc/emqx.conf并配置匿名认证开关allow_anonymous 为falseacl_nomatch为deny

## Allow anonymous authentication by default if no auth plugins loaded.
## Notice: Disable the option in production deployment!
##
## Value: true | false
allow_anonymous = false
 
## Allow or deny if no ACL rules matched.
##
## Value: allow | deny
acl_nomatch = deny

启用内置身份校验插件emqx_auth_username需在 EMQX 启动时就默认启动某插件则直接在 data/loaded_plugins 添加需要启动的插件名称。

{emqx_management, true}.
{emqx_recon, true}.
{emqx_retainer, true}.
{emqx_dashboard, true}.
{emqx_rule_engine, true}.
{emqx_bridge_mqtt, false}.
{emqx_auth_username, true}.     ## 加这一行备注不要加

然后配置身份校验的用户名和密码修改文件etc/plugins/emqx_auth_username.conf

# 之后可能需要用到acl因此这里加两个用户
auth.user.1.username = root
auth.user.1.password = zhkjhivemqroot@00239

auth.user.2.username = user
auth.user.2.password = zhkjhivemquser@002396

连接测试这里使用mosquitto进行测试

mosquitto_sub -h 10.27.106.14 -t '/device/1123/upward' -u root -p 1883 -P zhkjhivemqroot@002396

mosquitto_pub -h 10.27.106.14 -t '/device/1123/upward' -u root -p 1883 -P zhkjhivemqroot@002396 -m "hello"

能够在订阅界面获取到对应的消息说明订阅和发布都成功了。

这里遇到一个坑通过配置文件配置的用户名密码没法通过配置文件进行修改需要通过HTTP API修改。

更改指定用户名的密码

指定用户名传递新密码进行更改再次连接时需要使用新密码进行连接

API 定义

# Request
PUT api/v4/auth_username/${username}
{
    "password": "emqx_new_p"
}

# Response
{
    "code": 0
}

查看指定用户名信息

指定用户名查看相关用户名、密码信息注意此处返回的密码是使用配置文件指定哈希方式加密后的密码

API 定义

# Request
GET api/v4/auth_username/${username}

# Response
{
    "code": 0,
    "data": {
        "username": "emqx_u",
        "password": "091dc8753347e7dc5d348508fe6323735eecdb84fa800548870158117af8a0c0"
    }
}

TLS认证开启

生成秘钥文件的配置文件openssl.cnf内容如下

# CA key
openssl genrsa -out ca.key 2048
# CA csr
openssl req -new -subj "/CN=ca" -key ca.key -out ca.csr
# CA crt
openssl x509 -req -in ca.csr -out ca.crt -signkey ca.key -days 3650

# server key
openssl genrsa -out server.key 2048
# server.csr
openssl req -new -subj "/CN=aec.starnetuc.com" -key server.key -out server.csr
# server.crt
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
# server.crt verify
openssl verify -CAfile ca.crt  server.crt

# client key
openssl genrsa -out client.key 2048
# client.csr
openssl req -new -subj "/CN=aec.starnetuc.com" -key client.key -out client.csr
# client.crt
openssl x509 -req -in client.csr -out client.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
# client.crt verify
openssl verify -CAfile ca.crt  client.crt


## 一次性复制
openssl genrsa -out ca.key 2048
openssl req -new -subj "/CN=ca" -key ca.key -out ca.csr
openssl x509 -req -in ca.csr -out ca.crt -signkey ca.key -days 3650
openssl genrsa -out server.key 2048
openssl req -new -subj "/CN=aec.starnetuc.com" -key server.key -out server.csr
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
openssl verify -CAfile ca.crt  server.crt
openssl genrsa -out client.key 2048
openssl req -new -subj "/CN=aec.starnetuc.com" -key client.key -out client.csr
openssl x509 -req -in client.csr -out client.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
openssl verify -CAfile ca.crt  client.crt# 生成 CA key
openssl genrsa -out ca.key 2048
# 生成 EMQX 的根证书
openssl req -x509 -new -subj "/CN=aec.starnetuc.com" -nodes -key ca.key -sha256 -days 3650 -out ca.pem
# 查看 CA 证书信息可选
openssl x509 -in ca.pem -noout -text

# 生成 EMQX 的 key 即 服务端的key
openssl genrsa -out emqx.key 2048
# 生成 EMQX 服务端的csr文件
openssl req -new -key ./emqx.key -config openssl.cnf -out emqx.csr
# 根证书来签发 EMQX 的实体证书证书
openssl x509 -req -in ./emqx.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out emqx.pem -days 3650 -sha256 -extensions v3_req -extfile openssl.cnf
# 查看 EMQX 实体证书可选
openssl x509 -in emqx.pem -noout -text
# 验证 EMQX 实体证书确定证书是否正确
openssl verify -CAfile ca.pem emqx.pem

准备好证书后我们就可以启用 EMQX 的 TLS/SSL 功能了。

将以上所有文件拷贝到 EMQX 某个目录这里我放的是/opt/emqx/tls-conf下并参考如下配置修改 emqx.conf

## Path to the file containing the user's private PEM-encoded key.
##                                                   
## See: http://erlang.org/doc/man/ssl.html           
##                                                                             
## Value: File                                                                          
listener.ssl.external.keyfile = /opt/emqx/tls-conf/server.key
                                                                                        
## Path to a file containing the user certificate.                                      
##                                                                                      
## See: http://erlang.org/doc/man/ssl.html                                              
##                                                                                      
## Value: File                                                                          
listener.ssl.external.certfile = /opt/emqx/tls-conf/server.crt                                  
                                                                                        
## Path to the file containing PEM-encoded CA certificates. The CA certificates         
## are used during server authentication and when building the client certificate chain.
##                                                                    
## Value: File                                                        
listener.ssl.external.cacertfile = /opt/emqx/tls-conf/ca.crt

# 开启对端验证并强制要求客户端提供证书
## A server only does x509-path validation in mode verify_peer,
## as it then sends a certificate request to the client (this
## message is not sent if the verify option is verify_none).          
## You can then also want to specify option fail_if_no_peer_cert.
## More information at: http://erlang.org/doc/man/ssl.html
##                                                           
## Value: verify_peer | verify_none               
listener.ssl.external.verify = verify_peer 
                                                                               
## Used together with {verify, verify_peer} by an SSL server. If set to true,  
## the server fails if the client does not have a certificate to send, that is,
## sends an empty certificate.                                    
##                                                  
## Value: true | false                                                    
listener.ssl.external.fail_if_no_peer_cert = true 

当配置完成并重启 EMQX 后。

连接测试这里使用mosquitto进行测试

mosquitto_pub -h aec.starnetuc.com -t /device/1123/upward -u root -p 8883 -P zhkjhivemqroot@002396 --cafile /home/data/mosquitto/tls-conf/ca.crt --cert /home/data/mosquitto/tls-conf/client.crt --key /home/data/mosquitto/tls-conf/client.key -m "hello word"


mosquitto_sub -h aec.starnetuc.com -t /device/1123/upward -u root -p 8883 -P zhkjhivemqroot@002396 --cafile /home/data/mosquitto/tls-conf/ca.crt --cert /home/data/mosquitto/tls-conf/client.crt --key /home/data/mosquitto/tls-conf/client.key

支持多个版本的TLS

默认情况下emqx支持tlsv1.2要同时支持其他版本需要在etc/emqx.conf新增以下参数

## TLS versions only to protect from POODLE attack. 
##            
## See: http://erlang.org/doc/man/ssl.html                            
##                                                
## Value: String, seperated by ','                                                 
listener.ssl.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1 

这样emqx就能够支持tlsv1.2,tlsv1.1,tlsv1三个版本了。

常用命令

emqx restart

# 设置日志级别临时的容器重启就没了
emqx_ctl log set-level debug

集群部署

这里是调研因此采用最简单的手动(manual)方式来管理集群manual也是默认方式。

EMQ X 默认开启的 MQTT 服务 TCP 端口:

端口说明
1883MQTT 协议端口
8883MQTT/SSL 端口
8083MQTT/WebSocket 端口
8084MQTT/WebSocket/SSL 端口
8081管理 API 端口
18083Dashboard 端口

防火墙根据使用的 MQTT 接入方式开启上述端口的访问权限。

EMQ X 节点集群使用的 TCP 端口:

端口说明
4369集群节点发现端口
5369集群节点 PRC 通道
6369集群节点控制通道

集群节点间如有防护墙需开启上述 TCP 端口互访权限。

集群节点如下

节点名主机名 (FQDN)IP 地址
emqx@10.27.106.14-10.27.106.14
emqx@10.27.106.200-10.27.106.200

注意 节点名格式为Name@Host, Host 必须是 IP 地址或 FQDN (主机名。域名)

以14为例部署方式需要进行变更如下

docker run -d --network host --name emqx \
-e EMQX_LISTENER__TCP__EXTERNAL=1883 \ 
-e EMQX_NAME=emqx \ 
-e EMQX_HOST=10.27.106.14 \ 
-e EMQX_MANAGEMENT__LISTENER__HTTP=18080 \ 
-e EMQX_CLUSTER__NAME=aec_emqx_cluster \ 
-e EMQX_CLUSTER__DISCOVERY=manual \ 
-e EMQX_NODE__DIST_LISTEN_MIN=6369 \ 
-e EMQX_NODE__DIST_LISTEN_MAX=7369 \ 
-e EMQX_NODE__COOKIE=emqxsecretcookie \ 
emqx/emqx:v4.0.0

注意

  • EMQX_NODE__COOKIE和EMQX_CLUSTER__NAME在集群内部要保持一致

1、配置节点名称

配置emqx@10.27.106.14节点修改emqx/etc/emqx.conf:

node.name = emqx@10.27.106.14

注意: 节点启动加入集群后节点名称不能变更。

配置emqx@10.27.106.200节点修改emqx/etc/emqx.conf:

node.name = emqx@10.27.106.200

2、节点加入集群

启动两个节点之后任选一个节点加入另一个节点的集群

这里选择14去加入200

emqx_ctl cluster join emqx@10.27.106.200

Join the cluster successfully.
Cluster status: #{running_nodes => ['emqx@10.27.106.14','emqx@10.27.106.200'],
                  stopped_nodes => []}

在任意节点上查询集群状态:

emqx_ctl cluster status
Cluster status: #{running_nodes => ['emqx@10.27.106.14','emqx@10.27.106.200'],
                  stopped_nodes => []}

说明集群部署成功了。

集群效果为

当某个客户端1连接节点A订阅的主题在其他的节点收到消息之后节点A也能够收到消息然后通知给客户端1。

补充退出节点的命令

emqx_ctl cluster leave

Nginx负载均衡

安装时需要额外编译nginx的其他模块因此在执行./configure时需要携带额外参数

## 其中--with-stream --with-http_ssl_module --with-stream_ssl_module为额外参数
./configure --with-stream --with-http_ssl_module --with-stream_ssl_module --prefix=/usr/local/nginx

编译完成之后对nginx.conf进行配置需要加入的配置如下

stream {
  upstream stream_backend {
      hash $remote_addr;
      server 10.27.106.14:1883 max_fails=2 fail_timeout=30s;
      server 10.27.106.200:1883 max_fails=2 fail_timeout=30s;
      # server 192.168.0.3:1883 max_fails=2 fail_timeout=30s;
  }

  server {
      listen 38888 ssl;
      proxy_pass stream_backend;
      proxy_buffer_size 4k;
      ssl_handshake_timeout 15s;
      ssl_certificate      /home/data/emqx/tls-conf/server.crt;
      ssl_certificate_key  /home/data/emqx/tls-conf/server.key;
  }
}

## 其中ssl_certificate与emqx的certificate一致
## ssl_certificate_key与key文件一致

这里Nginx将会终结TLS。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: nginxDocker

“EMQX4.x版本-Docker集群部署与Nginx负载均衡” 的相关文章