docker consul 集群部署

docker consul 集群部署

本文档演示的在一台服务器上部署节点=3的consul集群

准备

1.在宿主机上分别建立目录 server1server2server3 文件夹,并对应创建configdatalog 文件夹

其中:

  • config :配置文件路径。也是docker启动时读取的配置文件路径
  • data :数据存储路径。docker启动时挂载到容器中的指定路径
  • log :日志输出路径。(可以不落盘日志,本文档演示的是落盘日志)

image-20240226144216083


单点部署

server1

1.进入到 config 目录下

1
cd server1/config

2.创建 config.json 配置文件

1
vim config.json

image-20240226151703284

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"datacenter": "dc1",
"bootstrap_expect": 1,
"data_dir": "/consul/data",
"log_file": "/consul/log",
"log_level": "INFO",
"node_name": "consul_server_1",
"client_addr": "0.0.0.0",
"server": true,
"ui": true,
"enable_script_checks": true,
"addresses": {
"https": "0.0.0.0",
"dns": "0.0.0.0"
}
}

参数说明:

  • datacenter:指定consul的数据中心名称
  • bootstrap_expect:指定启动时需要的最少节点数
  • data_dir:指定consul在运行过程中存储数据的目录路径(容器内路径)
  • log_file:指定consul输出的日志路径(容器内路径)
  • log_level:指定consul日志输出的等级
  • node_name:指定consul的节点名称
  • client_addr:指定consul客户端访问地址
  • server:指定是否是server节点
  • ui:指定是否启用consul的web管理界面
  • enable_script_checks:指定是否启用支持脚本检查(Script Checks)功能。脚本检查允许用户通过自定义的脚本来检查服务的健康状态。
  • addresses:指定Consul agent监听的IP地址

image-20240226172420932

log_file: 也可以是 “/consul/log/” //根据版本来的,consul容器内本身是没有log文件夹的,如果没有权限在容器内创建log文件夹,则使用 /consul/log

3.配置启动命令

server1 目录下 创建启动脚本run.sh

1
vim run.sh
1
2
3
#!/bin/bash

docker run -d -p 8500:8500 --name=consul_server_1 -v $PWD/data:/consul/data -v $PWD/config:/consul/config -v $PWD/log:/consul/log -e CONSUL_BIND_INTERFACE='eth0' consul agent -config-dir=/consul/config/config.json

参数说明

  • -d:在后台运行容器。

  • -p 8500:8500:指定容器内端口和宿主机端口的映射关系,将容器内的8500端口映射到宿主机的8500端口上。

  • --name=consul_server_1 :指定容器名称为consul_server_1。

  • -v $PWD/data:/consul/data:挂载宿主机上的数据存储目录到容器中的/consul/data 目录

  • -v $PWD/config:/consul/config:挂载宿主机上的配置文件目录到容器中的/consul/config 目录

  • -v $PWD/log:/consul/log:挂载宿主机上的日志输出目录到容器中的/consul/log 目录

  • -e CONSUL_BIND_INTERFACE='eth0':通过环境变量CONSUL_BIND_INTERFACE指定Consul绑定的网卡接口为eth0

  • consul agent :启动consul agent

  • -config-dir=/consul/config/config.json:指定配置文件路径(容器内),consul会自动读取配置文件中的参数

image-20240226161814054

4.启动服务

1
sh run.sh

image-20240226172625032

5.通过网页打开http://127.0.0.1:8500/ui看是否能看到consul看板

加入ACL认证

1.使用linux的命令生成一个64位的UUID作为master token

1
2
3
4
uuidgen

output:
487d910a-a599-49b5-979e-57855e53b3b0

image-20240226174005313

2.编写acl.hcl文件

1
vim config/acl.hcl
1
2
3
4
5
6
7
8
acl {
enabled = true
default_policy = "deny"
enable_token_persistence = true
tokens {
master = "487d910a-a599-49b5-979e-57855e53b3b0"
}
}

image-20240226174126814

3.重启服务

1
docker restart consul_server_1

4.访问UI,提示需要输入token,输入上面配置的master token即可

image-20240226174320743


集群部署

一台服务器部署

在一台服务器上部署consul集群,docker run命令可以使用-p 和 -e CONSUL_BIND_INTERFACE=‘eth0’ 的方式。因为在同一台服务器上,容器网卡是eth0。

server1

1.进入到 config 目录下

1
cd server1/config

2.创建 config.json 配置文件

1
vim config.json

image-20240226151703284

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"datacenter": "dc1",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"log_file": "/consul/log/",
"log_level": "INFO",
"node_name": "consul_server_1",
"client_addr": "0.0.0.0",
"server": true,
"ui": true,
"enable_script_checks": true,
"addresses": {
"https": "0.0.0.0",
"dns": "0.0.0.0"
}
}

参数说明:

  • datacenter:指定consul的数据中心名称
  • bootstrap_expect:指定启动时需要的最少节点数
  • data_dir:指定consul在运行过程中存储数据的目录路径(容器内路径)
  • log_file:指定consul输出的日志路径(容器内路径)
  • log_level:指定consul日志输出的等级
  • node_name:指定consul的节点名称
  • client_addr:指定consul客户端访问地址
  • server:指定是否是server节点
  • ui:指定是否启用consul的web管理界面
  • enable_script_checks:指定是否启用支持脚本检查(Script Checks)功能。脚本检查允许用户通过自定义的脚本来检查服务的健康状态。
  • addresses:指定Consul agent监听的IP地址

image-20240226161334661

log_file: 也可以是 “/consul/log/” //根据版本来的,consul容器内本身是没有log文件夹的,如果没有权限在容器内创建log文件夹,则使用 /consul/log

3.配置启动命令

server1 目录下 创建启动脚本run.sh

1
vim run.sh
1
2
3
#!/bin/bash

docker run -d -p 8500:8500 --name=consul_server_1 -v $PWD/data:/consul/data -v $PWD/config:/consul/config -v $PWD/log:/consul/log -e CONSUL_BIND_INTERFACE='eth0' consul agent -config-dir=/consul/config/config.json

参数说明

  • -d:在后台运行容器。

  • -p 8500:8500:指定容器内端口和宿主机端口的映射关系,将容器内的8500端口映射到宿主机的8500端口上。

  • --name=consul_server_1 :指定容器名称为consul_server_1。

  • -v $PWD/data:/consul/data:挂载宿主机上的数据存储目录到容器中的/consul/data 目录

  • -v $PWD/config:/consul/config:挂载宿主机上的配置文件目录到容器中的/consul/config 目录

  • -v $PWD/log:/consul/log:挂载宿主机上的日志输出目录到容器中的/consul/log 目录

  • -e CONSUL_BIND_INTERFACE='eth0':通过环境变量CONSUL_BIND_INTERFACE指定Consul绑定的网卡接口为eth0

  • consul agent :启动consul agent

  • -config-dir=/consul/config/config.json:指定配置文件路径(容器内),consul会自动读取配置文件中的参数

image-20240226161814054

4.启动服务

1
sh run.sh

启动后,因为配置了bootstrap_expect=3,但只启动了一个server,所以会报错:没有集群领导者

4

需要把另外2个服务也启动起来!

server2

1.进入到 config 目录下

1
cd server2/config

2.创建 config.json 配置文件

1
vim config.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"datacenter": "dc1",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"log_file": "/consul/log/",
"log_level": "INFO",
"node_name": "consul_server_2",
"client_addr": "0.0.0.0",
"server": true,
"ui": true,
"enable_script_checks": true,
"addresses": {
"https": "0.0.0.0",
"dns": "0.0.0.0"
}
}

3.配置启动令

server2 目录下 创建启动脚本run.sh

1
vim run.sh
1
2
3
#!/bin/bash

docker run -d -p 8510:8500 --name=consul_server_2 -v $PWD/data:/consul/data -v $PWD/config:/consul/config -v $PWD/log:/consul/log -e CONSUL_BIND_INTERFACE='eth0' consul agent -config-dir=/consul/config/config.json

4.启动服务

1
sh run.sh

5.加入集群

1
docker exec -it consul_server_3 consul join {consul_server_1.IP}
server3

1.进入到 config 目录下

1
cd server3/config

2.创建 config.json 配置文件

1
vim config.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"datacenter": "dc1",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"log_file": "/consul/log/",
"log_level": "INFO",
"node_name": "consul_server_3",
"client_addr": "0.0.0.0",
"server": true,
"ui": true,
"enable_script_checks": true,
"addresses": {
"https": "0.0.0.0",
"dns": "0.0.0.0"
}
}

3.配置启动命令

server3 目录下 创建启动脚本run.sh

1
mkdir run.sh
1
2
3
#!/bin/bash

docker run -d -p 8520:8500 --name=consul_server_3 -v $PWD/data:/consul/data -v $PWD/config:/consul/config -v $PWD/log:/consul/log -e CONSUL_BIND_INTERFACE='eth0' consul agent -config-dir=/consul/config/config.json

4.启动服务

1
sh run.sh

5.加入集群

1
docker exec -it consul_server_3 consul join {consul_server_1.IP}
加入ACL认证

1.生成UUID

1
2
3
4
uuidgen

output:

2.分别在consul_server_1consul_server_2consul_server_3config 文件夹中新增acl.hcl 配置文件

1
vim config/acl.hcl
1
2
3
4
5
6
7
8
9
primary_datacenter = "dc1"
acl {
enabled = true
default_policy = "deny"
enable_token_persistence = true
tokens {
master = "487d910a-a599-49b5-979e-57855e53b3b0"
}
}

参数说明:

  • enabled = true:代表开启ACL
  • default_policy=“deny”:默认为allow,如果需要自定义权限,需要将其设置为deny
  • enable_token_persistence =true: 开启token持久化,将token持久化到磁盘上

3.重启 consul_server_1consul_server_2consul_server_3 服务

1
2
3
4
5
docker restart consul_server_1

docker restart consul_server_2

docker restart consul_server_3

5.启动UI界面查看,登录需要secreatID验证,即输入acl.hcl 配置文件中的master token


多台服务器部署

目前查找到能部署成功的方式是通过network的方式。

server1

服务器IP:192.168.26.73

1.进入到 config 目录下

1
cd server1/config

2.创建 config.json 配置文件

1
vim config.json

![image-20240226151703284](/imgs/2.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"datacenter": "dc1",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"log_file": "/consul/log/",
"log_level": "INFO",
"node_name": "consul_server_1",
"client_addr": "0.0.0.0",
"server": true,
"ui": true,
"enable_script_checks": true,
"addresses": {
"https": "0.0.0.0",
"dns": "0.0.0.0"
}
}

image-20240226161334661

log_file: 也可以是 “/consul/log/” //根据版本来的,consul容器内本身是没有log文件夹的,如果没有权限在容器内创建log文件夹,则使用 /consul/log

3.配置启动命令

server1 目录下 创建启动脚本run.sh

1
vim run.sh
1
2
3
#!/bin/bash

docker run -d --net=host --name=consul_server_1 -v $PWD/data:/consul/data -v $PWD/config:/consul/config -v $PWD/log:/consul/log -e CONSUL_BIND_INTERFACE='ens192' consul agent -bind=192.168.26.73 -config-dir=/consul/config/config.json

参数说明

  • -d:在后台运行容器。
  • --network=host:将容器连接到名为host的网络
  • --name=consul_server_1 :指定容器名称为consul_server_1。
  • -v $PWD/data:/consul/data:挂载宿主机上的数据存储目录到容器中的/consul/data 目录
  • -v $PWD/config:/consul/config:挂载宿主机上的配置文件目录到容器中的/consul/config 目录
  • -v $PWD/log:/consul/log:挂载宿主机上的日志输出目录到容器中的/consul/log 目录
  • -e CONSUL_BIND_INTERFACE='ens192':通过环境变量CONSUL_BIND_INTERFACE指定Consul绑定的网卡接口为ens192(这个根据实际的网卡名称,通过ifconfig 命令查看)
  • consul agent :启动consul agent
  • -bind=192.168.26.73:指定Consul节点在Docker容器内监听的IP地址(服务器IP)
  • -config-dir=/consul/config/config.json:指定配置文件路径(容器内),consul会自动读取配置文件中的参数

image-20240227174226118

4.启动服务

1
sh run.sh

启动后,因为配置了bootstrap_expect=3,但只启动了一个server,所以会报错:没有集群领导者

4

需要把另外2个服务也启动起来!

server2

服务器IP:192.168.26.74

1.进入到 config 目录下

1
cd server2/config

2.创建 config.json 配置文件

1
vim config.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"datacenter": "dc1",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"log_file": "/consul/log/",
"log_level": "INFO",
"node_name": "consul_server_2",
"client_addr": "0.0.0.0",
"server": true,
"ui": true,
"enable_script_checks": true,
"addresses": {
"https": "0.0.0.0",
"dns": "0.0.0.0"
}
}

3.配置启动命令

server2 目录下 创建启动脚本run.sh

1
vim run.sh
1
2
3
#!/bin/bash

docker run -d --network=host --name=consul_server_2 -v $PWD/data:/consul/data -v $PWD/config:/consul/config -v $PWD/log:/consul/log -e CONSUL_BIND_INTERFACE='ens192' consul agent -bind=192.168.26.74 -join=192.168.26.73

参数说明

  • -join=192.168.26.73:将节点加入到consul_server_1 IP上

image-20240227174405828

4.启动服务

1
sh run.sh
server3

服务器IP:192.168.26.75

1.进入到 config 目录下

1
cd server3/config

2.创建 config.json 配置文件

1
vim config.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"datacenter": "dc1",
"bootstrap_expect": 3,
"data_dir": "/consul/data",
"log_file": "/consul/log/",
"log_level": "INFO",
"node_name": "consul_server_3",
"client_addr": "0.0.0.0",
"server": true,
"ui": true,
"enable_script_checks": true,
"addresses": {
"https": "0.0.0.0",
"dns": "0.0.0.0"
}
}

3.配置启动命令

server3 目录下 创建启动脚本run.sh

1
vim run.sh
1
2
3
#!/bin/bash

docker run -d --network=host --name=consul_server_3 -v $PWD/data:/consul/data -v $PWD/config:/consul/config -v $PWD/log:/consul/log -e CONSUL_BIND_INTERFACE='ens192' consul agent -bind=192.168.26.75 -join=192.168.26.73 -config-dir=/consul/config/config.json

参数说明

  • -join=192.168.26.73:将节点加入到consul_server_1 IP上

image-20240227174802437

4.启动服务

1
sh run.sh

image-20240227174946704

节点自动加入集群

1.分别编辑sverer1sverer2sverer3 的配置文件,加入start_joinretry_join 字段

1
vim config/config.json

image-20240229141458532

server2server3 同样配置。

2.重新加载配置文件,验证配置是否正确

1
docker exec consul_server_1 consul reload

image-20240229143001728

我测试的consul_server_2leader,加入了配置,但是没有重启leader。我重启的是 consul_server_1,测试优雅退出 consul_server_1,然后再重启,发现自动加入到了节点;也测试 consul_server_3 不加配置,然后优雅退出 consul_server_3 再重启,发现 consul_server_3 也自动加入到了节点。(这是为什么呢,从测试的结果来看,只要一个节点加入配置即可)

加入ACL认证

方法一:配置acl.hcl ,通过consul acl bootstrap 生成token,然后把生成的token当做 master 的token。

本文档不采用该方法,有兴趣的可以自行去了解。参考文档 中【增加ACL token权限配置】目录。

方法二:使用linux的 uuidgen 命令生成一个64位UUID作为 master token,写入acl.hcl 配置文件中

1.生成UUID

1
uuidgen

output:

1
17b0d7f6-cd24-4989-ad84-9e1e5c938ce8

image-20240229144313793

2.分别在consul_server_1consul_server_2consul_server_3config文件夹中 新增acl.hcl 配置文件,并将生成的token 加入文件中

1
vim config/acl.hcl
1
2
3
4
5
6
7
8
9
primary_datacenter = "dc1"
acl {
enabled = true
default_policy = "deny"
enable_token_persistence = true
tokens {
master = "17b0d7f6-cd24-4989-ad84-9e1e5c938ce8"
}
}

参数说明:

  • enabled = true:代表开启ACL
  • default_policy=“deny”:默认为allow,如果需要自定义权限,需要将其设置为deny
  • enable_token_persistence =true: 开启token持久化,将token持久化到磁盘上

3.重启 consul_server_1consul_server_2consul_server_3 服务

1
2
3
4
5
docker restart consul_server_1

docker restart consul_server_2

docker restart consul_server_3

4.启动UI界面查看

image-20240229161256697

输入 acl.hcl 配置文件中的 master 的 token

image-20240229161313672

image-20240229161433696