Docker中创建Consul集群

2020/01/21 14:49
阅读数 31

一、Consul简介

Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。它具有很多优点。包括:基于 raft 协议,比较简洁; 支持健康检查, 同时支持 HTTP 和 DNS 协议 支持跨数据中心的 WAN(广域网) 集群 提供图形界面 跨平台,支持 Linux、Mac、Windows。

consul是使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。服务部署简单,只有一个可运行的二进制的包。每个节点都需要运行agent,他有两种运行模式server和client。每个数据中心官方建议需要3或5个server节点以保证数据安全,同时保证server-leader的选举能够正确的进行。

@client

CLIENT表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到SERVER,本身是不持久化这些信息。

@server

SERVER表示consul的server模式,表明这个consul是个server,这种模式下,功能和CLIENT都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。

@server-leader

中间那个SERVER下面有LEADER的字眼,表明这个SERVER是它们的老大,它和其它SERVER不一样的一点是,它需要负责同步注册的信息给其它的SERVER,同时也要负责各个节点的健康监测。

@raft(分布式一致性协议)

server节点之间的数据一致性保证,一致性协议使用的是raft,而zookeeper用的paxos,etcd采用的也是raft。

@服务发现协议

consul采用http和dns协议,etcd只支持http

@服务注册

consul支持两种方式实现服务注册,一种是通过consul的服务注册http API,由服务自己调用API实现注册,另一种方式是通过json个是的配置文件实现注册,将需要注册的服务以json格式的配置文件给出。consul官方建议使用第二种方式。

@服务发现

consul支持两种方式实现服务发现,一种是通过http API来查询有哪些服务,另外一种是通过consul agent 自带的DNS(8600端口),域名是以NAME.service.consul的形式给出,NAME即在定义的服务配置文件中,服务的名称。DNS方式可以通过check的方式检查服务。

@服务间的通信协议

Consul使用gossip协议管理成员关系、广播消息到整个集群,他有两个gossip pool(LAN pool和WAN pool),LAN pool是同一个数据中心内部通信的,WAN pool是多个数据中心通信的,LAN pool有多个,WAN pool只有一个。

二、基本概念

在描述架构之前,这里提供了一些术语来帮助声明正在探讨的东西:

  • Agent——agent是一直运行在Consul集群中每个成员上的守护进程。通过运行 consul agent 来启动。agent可以运行在client或者server模式。指定节点作为client或者server是非常简单的,除非有其他agent实例。所有的agent都能运行DNS或者HTTP接口,并负责运行时检查和保持服务同步。
  • Client——一个Client是一个转发所有RPC到server的代理。这个client是相对无状态的。client唯一执行的后台活动是加入LAN gossip池。这有一个最低的资源开销并且仅消耗少量的网络带宽。
  • Server——一个server是一个有一组扩展功能的代理,这些功能包括参与Raft选举,维护集群状态,响应RPC查询,与其他数据中心交互WAN gossip和转发查询给leader或者远程数据中心。
  • DataCenter——虽然数据中心的定义是显而易见的,但是有一些细微的细节必须考虑。例如,在EC2中,多个可用区域被认为组成一个数据中心?我们定义数据中心为一个私有的,低延迟和高带宽的一个网络环境。这不包括访问公共网络,但是对于我们而言,同一个EC2中的多个可用区域可以被认为是一个数据中心的一部分。
  • Consensus——在我们的文档中,我们使用Consensus来表明就leader选举和事务的顺序达成一致。由于这些事务都被应用到有限状态机上,Consensus暗示复制状态机的一致性。
  • Gossip——Consul建立在Serf的基础之上,它提供了一个用于多播目的的完整的gossip协议。Serf提供成员关系,故障检测和事件广播。更多的信息在gossip文档中描述。这足以知道gossip使用基于UDP的随机的点到点通信。
  • LAN Gossip——它包含所有位于同一个局域网或者数据中心的所有节点。
  • WAN Gossip——它只包含Server。这些server主要分布在不同的数据中心并且通常通过因特网或者广域网通信。
  • RPC——远程过程调用。这是一个允许client请求server的请求/响应机制。

Consul Architecture 架构图

 

 

拆解开这个体系,从每一个组件开始了解。首先,可以看到有两个数据中心,分别标记为“one”和“two”。Consul是支持多数据中心一流,并且是常用业务场景。

每个数据中心都是由Server和client组成。建议有3~5 Server——基于故障处理和性能的平衡之策。如果增加越多的机器,则Consensus会越来越慢。对client没有限制,可以很容易地扩展到成千上万或数万。

同一个数据中心的所有节点都要加入Gossip协议。这意味着gossip pool包含给定数据中心的所有节点。有以下目的:首先,没有必要为client配置服务器地址参数;发现是自动完成的。第二,节点故障检测的工作不是放置在服务器上,而是分布式的。这使故障检测比心跳机制更可扩展性。第三,可用来作为消息层通知重要的事件,如leader选举。

每个数据中心的服务器都是属于一个Raft peer。这意味着,他们一起工作,选出一个的Leader,Leader server是有额外的职责。负责处理所有的查询和事务。事务也必须通过Consensus协议复制到所有的伙伴。由于这一要求,当非Leader Server接收到一个RPC请求,会转发到集群的leader。

Server节点也是作为WAN gossip pool的一部分。这个pool是与LAN gossip pool是不同的,它为具有更高延迟的网络响应做了优化,并且可能包括其他consul集群的server节点。设计WANpool的目的是让数据中心能够以low-touch的方式发现彼此。将一个新的数据中心加入现有的WAN Gossip是很容易的。因为池中的所有Server都是可控制的,这也使跨数据中心的要求。当一个Serfer接收到不同的数据中心的要求时,它把这个请求转发给相应数据中心的任一Server。然后,接收到请求的Server可能会转发给Leader。

多个数据中心之间是低耦合,但由于故障检测、连接缓存复用、跨数据中心要求快速和可靠的响应。

三、Docker中创建Consul集群

1 使用docker下载consul镜像,默认下载最consul最新版本,目前版本号为1.4.0,如果需要其他版本请登录https://hub.docker.com/进行搜索
2 下载完毕后分别创建/home/docker/consul、consul-server1-data、consul-server2-data、consul-server3-data、consul-client-data、consul-server1-conf、consul-server2-conf、consul-server3-conf、consul-client-conf这九个文件夹

[root@docker-02 ~]# cd /home/
[root@docker-02 home]#  mkdir docker
[root@docker-02 home]# cd docker
[root@docker-02 docker]# mkdir consul
[root@docker-02 docker]#  cd consul
[root@docker-02 consul]# mkdir consul-server1-data consul-server2-data consul-server3-data  consul-client-data consul-server1-conf consul-server2-conf consul-server3-conf consul-client-conf
3 创建Consul配置文件
3.1 在docker中每个Consul成员都是docker中的一个容器,docker会给每个容器分配容器的IP地址,容器IP地址只能用于容器之间内部通讯不能被宿主机直接访问,每个Consul容器IP同时也是Consul成员的Agentd守护进程的IP地址,创建Consul集群需要其他Consul容器加入同一个Consul容器的Agentd守护进程的IP地址,将该Consul容器作为Consul容器的leader,当该Consul容器挂掉时,Consul集群会从所有Agentd守护进程的IP地址中再选举出一个leader,但当宿主及重启,docker中所有容器的IP地址都会发生变化,Consul集群中的每个成员的IP地址也发生变化,原本是Consul容器的IP地址可能变成了Mysql容器的IP地址,这样每个Consul成员无法自动加入原来Consul容器的Agentd守护进程的IP地址,Consul集群就会报错,解决方案是在所有Consul节点服务的配置文件中,配置参数"retry_join",将docker中所有容器的IP都作为加入同一个Consul容器的Agentd守护进程的IP地址,任何一个Consul成员的Agent守护进程只需要知道集群中任意一个节点即可,加入到集群之后,集群节点之间会根据GOSSIP协议互相发现彼此的关系
要先统计docker中所有容器已经被使用的IP地址,将没有被使用的空闲的IP地址作为Consul容器Agentd守护进程的IP地址
3.1.1 查询docker中所有容器IP地址
3.1.2 统计出已经使用的IP地址后,将空闲的172.17.0.6、172.17.0.9、172.17.0.4、172.17.0.3这四个准备使用的IP地址,作为Consul容器的IP地址,并将所有docker容器中所有已经使用的IP地址和准备使用的IP地址写入每个Consul节点服务的配置文件的配置参数"retry_join"中, "retry_join": ["172.17.0.2","172.17.0.3","172.17.0.4","172.17.0.5","172.17.0.6","172.17.0.7","172.17.0.8","172.17.0.9"]
3.2 创建consul-server1节点服务配置文件
3.2.1 进入consul-server1-conf文件夹创建consul-server1.json文件
[root@docker-02 consul]# cd consul-server1-conf/
[root@docker-02 consul-server1-conf]# touch consul-server1.json

3.2.2 vi编辑consul-server1.json配置文件,复制下列代码

[root@docker-02 consul-server1-conf]# cat consul-server1.json 
{
    "datacenter": "DC1",
    "data_dir": "/consul/data",
    "log_level": "INFO",
    "node_name": "consul-server1",
    "server": true,
    "bootstrap_expect": 1,
    "retry_join": ["172.17.0.2","172.17.0.3","172.17.0.4","172.17.0.5","172.17.0.6","172.17.0.7","172.17.0.8","172.17.0.9"],
    "retry_interval": "3s",
    "enable_debug": false,
    "rejoin_after_leave": true,
    "enable_syslog": false
}

3.3 创建consul-server2节点服务配置文件
3.3.1 进入consul-server2-conf文件夹创建consul-server2.json文件

[root@docker-02 consul-server1-conf]# cd .. 
[root@docker-02 consul]# cd consul-server2-conf/

3.3.2 vi编辑consul-server2.json配置文件,复制下列代码

[root@docker-02 consul-server2-conf]# cat consul-server2.json 
{
    "datacenter": "DC1",
    "data_dir": "/consul/data",
    "log_level": "INFO",
    "node_name": "consul-server2",
    "server": true,
    "bootstrap_expect": 2,
    "retry_join": ["172.17.0.2","172.17.0.3","172.17.0.4","172.17.0.5","172.17.0.6","172.17.0.7","172.17.0.8","172.17.0.9"],
    "retry_interval": "3s",
    "enable_debug": false,
    "rejoin_after_leave": true,
    "enable_syslog": false
}

3.4 创建consul-server3节点服务配置文件
3.4.1 进入consul-server3-conf文件夹创建consul-server3.json文件

[root@docker-02 consul-server2-conf]# cd ../consul-server3-conf/
[root@docker-02 consul-server3-conf]# vi consul-server3.json

3.4.2 vi编辑consul-server3.json配置文件,复制下列代码

[root@docker-02 consul-server3-conf]# cat consul-server3.json 
{
    "datacenter": "DC1",
    "data_dir": "/consul/data",
    "log_level": "INFO",
    "node_name": "consul-server3",
    "server": true,
    "bootstrap_expect": 2,
    "retry_join": ["172.17.0.2","172.17.0.3","172.17.0.4","172.17.0.5","172.17.0.6","172.17.0.7","172.17.0.8","172.17.0.9"],
    "retry_interval": "3s",
    "enable_debug": false,
    "rejoin_after_leave": true,
    "enable_syslog": false
}

3.4 创建consul-client节点服务配置文件
3.4.1 进入consul-client-conf文件夹创建consul-client.json文件

[root@docker-02 consul-server3-conf]# cd ../consul-client-conf/
[root@docker-02 consul-client-conf]#  touch consul-client.json

3.4.2 vi编辑consul-client.json配置文件,复制下列代码

[root@docker-02 consul-client-conf]# vi consul-client.json 

{
  "datacenter": "DC1",
  "data_dir": "/consul/data",
  "log_level": "INFO",
  "node_name": "consul-client",
  "server": false,
  "ui": true,
  "bootstrap_expect": 0,
  "bind_addr": "192.168.43.234",
  "client_addr": "192.168.43.234",
  "retry_join": ["172.17.0.2","172.17.0.3","172.17.0.4","172.17.0.5","172.17.0.6","172.17.0.7","172.17.0.8","172.17.0.9"],
  "retry_interval": "3s",
  "enable_debug": false,
  "rejoin_after_leave": true,
  "enable_syslog": false
}
3.5 配置参数说明
datacenter: 数据中心名称
data_di:ConsulServer模式节点的数据目录
log_level: "INFO":日志级别
node_name:当前节点名称
server:是否为 Server 模式,true 为 Server 模式,false 为 Client 模式
ui:是否开启 UI 访问
bootstrap_expect:启动时期望的就绪节点,1 代表启动为 bootstrap 模式,等待其他节点加入
bind_addr:绑定的 IP,ConsulServer模式无需指定,ConsulClient模式必须绑定宿主机IP地址,否则报错[Consul]Error starting agent: Failed to get advertise address: Multiple private IPs found.
client_addr:作为 Client 接受请求的绑定 IP地址,该IP地址必须为宿主机IP地址,否则访问宿主机无法访问到Client模式的Consul节点,端口使用了 HTTP: 8500, DNS: 8600
retry_join:尝试加入的其他节点
retry_interval:每次尝试间隔
raft_protocol:Raft 协议版本
enable_debug:是否开启 Debug 模式
rejoin_after_leave:允许重新加入集群
enable_syslog:是否开启 syslog
4 启动三个server模式的consul节点consul-server1、consul-server2、consul-server3,启动一个client模式的consul节点consul-client
[root@docker-02 consul-client-conf]# docker run -d --name consul-server1 --restart=always -v /home/docker/consul/consul-server1-data:/consul/data -v /home/docker/consul/consul-server1-conf:/consul/config consul agent -data-dir /consul/data -config-dir /consul/config
Unable to find image 'consul:latest' locally
latest: Pulling from library/consul
e7c96db7181b: Pull complete 
06ba64850324: Pull complete 
e2cfcbd06e76: Pull complete 
211aae54ca69: Pull complete 
1f22c1b42a0a: Pull complete 
028c01a3f1b3: Pull complete 
Digest: sha256:a167e7222c84687c3e7f392f13b23d9f391cac80b6b839052e58617dab714805
Status: Downloaded newer image for consul:latest
a0d30329efbf677e0924ec0a4f6ab79ac0e12187a8fcc91acbff363efd0f840c
[root@docker-02 consul-client-conf]# docker run -d --name consul-server2 --restart=always -v /home/docker/consul/consul-server2-data:/consul/data -v /home/docker/consul/consul-server2-conf:/consul/config consul agent -data-dir /consul/data -config-dir /consul/config
8b95ae0306473272a6e25329067c991c0a3f455121b74f2f189d46363f03b6b5
[root@docker-02 consul-client-conf]# docker run -d --name consul-server3 --restart=always -v /home/docker/consul/consul-server3-data:/consul/data -v /home/docker/consul/consul-server3-conf:/consul/config consul agent -data-dir /consul/data -config-dir /consul/config
4eb530c9c155b4e361e4a002ccf521dc51baf72ef46a5be15b963e1efec3d420
[root@docker-02 consul-client-conf]# docker run -d --net=host --name consul-client --restart=always -p 8400:8400 -p 8500:8500 -p 8600:53/udp -v /home/docker/consul/consul-client-data:/consul/data -v /home/docker/consul/consul-client-conf:/consul/config consul agent  -data-dir /consul/data -config-dir /consul/config
WARNING: Published ports are discarded when using host network mode
6b0180f50dec54f0a83902c8335ddb18d0719b806dd9c42a04bd641885232186

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部