consul的基本概念
组成 consul 集群的每个成员上都要运行一个 agent,可以通过 consul agent 命令来启动。agent 可以运行在 server 状态或者 client 状态。自然的,运行在 server 状态的节点被称为 server 节点;运行在 client 状态的节点被称为 client 节点。
client 节点
负责转发所有的 RPC 到 server 节点。本身无状态,且轻量级,因此,可以部署大量的 client 节点。
server 节点
负责组成 cluster 的复杂工作(选举、状态维护、转发请求到 lead),以及 consul 提供的服务(响应 RCP 请求)。考虑到容错和收敛,一般部署 3 ~ 5 个比较合适。
datacenter
多机房使用的数据共享
Client是consul客户端。consul客户端不保存数据,客户端将接收到的请求转发给响应的Server端。Server之间通过局域网或广域网通信实现数据一致性。每个Server或Client都是一个consul agent。Consul集群间使用了GOSSIP协议通信和raft一致性算法。上面这张图涉及到了很多术语:
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的请求/响应机制。
在每个数据中心,client和server是混合的。一般建议有3-5台server。这是基于有故障情况下的可用性和性能之间的权衡结果,因为越多的机器加入达成共识越慢。然而,并不限制client的数量,它们可以很容易的扩展到数千或者数万台。
每个数据中心的server都是Raft节点集合的一部分。这意味着它们一起工作并选出一个leader,一个有额外工作的server。leader负责处理所有的查询和事务。作为一致性协议的一部分,事务也必须被复制到所有其他的节点。因为这一要求,当一个非leader得server收到一个RPC请求时,它将请求转发给集群leader。
server节点也作为WAN gossip Pool的一部分。这个Pool不同于LAN Pool,因为它是为了优化互联网更高的延迟,并且它只包含其他Consul server节点。这个Pool的目的是为了允许数据中心能够以low-touch的方式发现彼此。这使得一个新的数据中心可以很容易的加入现存的WAN gossip。因为server都运行在这个pool中,它也支持跨数据中心请求。当一个server收到来自另一个数据中心的请求时,它随即转发给正确数据中心一个server。该server再转发给本地leader。
单dc的CONSUL环境
主机名称 | IP | 角色 | 数据中心 |
---|---|---|---|
node0 | 192.168.192.120 | Server | DataCenter1 |
node1 | 192.168.192.121 | Server | DataCenter1 |
node2 | 192.168.192.122 | Server | DataCenter1 |
node3 | 192.168.192.123 | Client | DataCenter1 |
Consul有两种方式搭建方式:一是bootstrap模式,二是非bootstrap模式。
bootstrap模式
1. 在启动agent
在第一台节点上启动agent,以server模式运行,指定server角色的节点数目,指定节点名(在datacenter内节点名唯一),同时提供监听地址。
[ceph@node0 cousul]$ consul agent -server-bootstrap-expect=3 -data-dir=/tmp/consul -node=node0 -bind=192.168.192.120-dc=dc1
依次在另外两台机器部署agent作为server
节点node1
[ceph@node1 consul]$ consul agent-server -bootstrap-expect=3 -data-dir=/tmp/consul -node=node1-bind=192.168.192.121 -dc=dc1
节点node2
[ceph@node2 consul]$ consul agent-server -bootstrap-expect=3 -data-dir=/tmp/consul -node=node2-bind=192.168.192.122 -dc=dc1
目前,三个节点均不知道其他Server节点的存在,以node0为例
[ceph@node0 consul]$ consul members
Node Address Status Type Build Protocol DC
node0 192.168.192.120:8301 alive server 0.6.4 2 dc1
查看consul集群信息
[ceph@node0 consul]$ consul info
当前节点为follow节点
触发选举leader
因为consul一般需要3~5个Server,因此,在节点node0上添加node1和node2。
[ceph@node0 consul]$ consul join192.168.192.121
Successfully joined cluster bycontacting 1 nodes.
[ceph@node0 consul]$ consul join192.168.192.122
Successfully joined cluster bycontacting 1 nodes.
观察三个节点consul日志:
Node0:
2016/07/05 21:10:55 [INFO] agent: (LAN) joining: [192.168.192.122]
2016/07/05 21:10:55 [INFO] serf: EventMemberJoin: node2 192.168.192.122
2016/07/05 21:10:55 [INFO] agent: (LAN) joined: 1 Err: <nil>
2016/07/05 21:10:55 [INFO] consul: adding LAN server node2 (Addr:192.168.192.122:8300) (DC: dc1)
2016/07/05 21:10:55 [INFO] consul: Attempting bootstrap with nodes:[192.168.192.120:8300 192.168.192.121:8300 192.168.192.122:8300]
2016/07/05 21:10:55 [INFO] consul: New leader elected: node2
2016/07/05 21:10:56 [INFO] agent: Synced service 'consul'
Node1
2016/07/05 21:10:55 [INFO] serf:EventMemberJoin: node2 192.168.192.122
2016/07/05 21:10:55 [INFO] consul: adding LAN server node2 (Addr:192.168.192.122:8300) (DC: dc1)
2016/07/05 21:10:55 [INFO] consul: Attempting bootstrap with nodes:[192.168.192.121:8300 192.168.192.120:8300 192.168.192.122:8300]
2016/07/05 21:10:56 [INFO] consul: New leader elected: node2
2016/07/05 21:10:57 [INFO] agent:Synced service 'consul'
Node2
2016/07/05 21:10:55 [INFO] serf: EventMemberJoin: node0 192.168.192.120
2016/07/05 21:10:55 [INFO] serf: EventMemberJoin: node1 192.168.192.121
2016/07/05 21:10:55 [INFO] consul: adding LAN server node0 (Addr:192.168.192.120:8300) (DC: dc1)
2016/07/05 21:10:55 [INFO]consul: Attempting bootstrap with nodes: [192.168.192.122:8300192.168.192.120:8300 192.168.192.121:8300]
2016/07/05 21:10:55 [INFO] consul: adding LAN server node1 (Addr:192.168.192.121:8300) (DC: dc1)
2016/07/05 21:10:55 [WARN] raft: Heartbeat timeout reached, startingelection
2016/07/05 21:10:55 [INFO] raft: Node at 192.168.192.122:8300[Candidate] entering Candidate state
2016/07/05 21:10:55 [INFO] raft: Election won. Tally: 2
2016/07/05 21:10:55 [INFO] raft: Node at 192.168.192.122:8300 [Leader]entering Leader state
2016/07/05 21:10:55 [INFO] consul: cluster leadership acquired
2016/07/05 21:10:55 [INFO] consul: New leader elected: node2
2016/07/05 21:10:55 [INFO] raft: pipelining replication to peer192.168.192.121:8300
2016/07/05 21:10:55 [INFO] raft: pipelining replication to peer192.168.192.120:8300
2016/07/05 21:10:55 [INFO] consul: member 'node2' joined, marking healthalive
2016/07/05 21:10:55 [INFO] consul: member 'node0' joined, marking healthalive
2016/07/05 21:10:55 [INFO] consul: member 'node1' joined, marking healthalive
2016/07/05 21:10:58 [INFO] agent: Synced service 'consul'
由日志可知,举出了leadernode2
[ceph@node0 consul]$ consul members
Node Address Status Type Build Protocol DC
node0 192.168.192.120:8301 alive server 0.6.4 2 dc1
node1 192.168.192.121:8301 alive server 0.6.4 2 dc1
node2 192.168.192.122:8301 alive server 0.6.4 2 dc1
查看info信息
[ceph@node0 consul]$ consul info
agent:
check_monitors= 0
check_ttls= 0
checks= 0
services= 1
build:
prerelease=
revision= 26a0ef8c
version= 0.6.4
consul:
bootstrap = false
known_datacenters= 1
leader = false
server = true
节点node2上查看consul信息
[ceph@node2 consul]$ consul info
agent:
check_monitors= 0
check_ttls= 0
checks= 0
services= 1
build:
prerelease=
revision= 26a0ef8c
version= 0.6.4
consul:
bootstrap= false
known_datacenters= 1
leader = true
server = true
在node3上以client启动agent
[ceph@node3 consul]$ consul agent -data-dir=/tmp/consul -node=node3 -bind=192.168.192.123 -dc=dc1
在节点node0上添加node3
[ceph@node0 consul]$ consul join192.168.192.123
Successfully joined cluster bycontacting 1 nodes.
[ceph@node0 consul]$ consul members
Node Address Status Type Build Protocol DC
node0 192.168.192.120:8301 alive server 0.6.4 2 dc1
node1 192.168.192.121:8301 alive server 0.6.4 2 dc1
node2 192.168.192.122:8301 alive server 0.6.4 2 dc1
node3 192.168.192.123:8301 alive client 0.6.4 2 dc1
节点node3的日志如下:
2016/07/05 21:21:57 [INFO] serf: EventMemberJoin: node0 192.168.192.120
2016/07/05 21:21:57 [INFO] serf: EventMemberJoin: node2 192.168.192.122
2016/07/05 21:21:57 [INFO] serf: EventMemberJoin: node1 192.168.192.121
2016/07/05 21:21:57 [INFO] consul: adding server node0 (Addr:192.168.192.120:8300) (DC: dc1)
2016/07/05 21:21:57 [INFO] consul: adding server node2 (Addr:192.168.192.122:8300) (DC: dc1)
2016/07/05 21:21:57 [INFO] consul: adding server node1 (Addr:192.168.192.121:8300) (DC: dc1)
2016/07/05 21:21:57 [INFO] consul: New leader elected: node2
2016/07/05 21:21:57 [INFO] agent: Synced node info
依次关闭node3 node2
Node0和node1的日志如下:
Node0
2016/07/05 21:24:00 [INFO] serf: EventMemberLeave: node2 192.168.192.122
2016/07/05 21:24:00 [INFO] consul: removing LAN server node2 (Addr:192.168.192.122:8300) (DC: dc1)
2016/07/05 21:24:00 [WARN] raft: Heartbeat timeout reached, startingelection
2016/07/05 21:24:00 [INFO] raft: Node at 192.168.192.120:8300[Candidate] entering Candidate state
2016/07/05 21:24:01 [INFO] raft: Duplicate RequestVote for same term: 2
2016/07/05 21:24:02 [WARN] raft: Election timeout reached, restartingelection
2016/07/05 21:24:02 [INFO] raft: Node at 192.168.192.120:8300[Candidate] entering Candidate state
2016/07/05 21:24:02 [INFO] raft: Election won. Tally: 2
2016/07/05 21:24:02 [INFO] raft: Node at 192.168.192.120:8300 [Leader]entering Leader state
2016/07/05 21:24:02 [INFO] consul: cluster leadership acquired
2016/07/05 21:24:02 [INFO] consul: New leader elected: node0
2016/07/05 21:24:02 [INFO] raft: pipelining replication to peer192.168.192.121:8300
2016/07/05 21:24:02 [INFO] consul: member 'node2' left, deregistering
2016/07/05 21:24:03 [INFO] agent.rpc: Accepted client: 127.0.0.1:35701
Node1
2016/07/05 21:24:00 [INFO] consul: removing LAN server node2 (Addr:192.168.192.122:8300) (DC: dc1)
2016/07/05 21:24:00 [WARN] raft: Rejecting vote request from192.168.192.120:8300 since we have a leader: 192.168.192.122:8300
2016/07/05 21:24:01 [WARN] raft: Heartbeat timeout reached, startingelection
2016/07/05 21:24:01 [INFO] raft: Node at 192.168.192.121:8300[Candidate] entering Candidate state
2016/07/05 21:24:02 [INFO] raft: Node at 192.168.192.121:8300 [Follower]entering Follower state
2016/07/05 21:24:02 [INFO]consul: New leader elected: node0
###consul多数据中心搭建
自建IDC后面简称com、阿里云机房ali、腾讯云机房tx
com机房:内网10.10.10.0/24,边界节点,10.10.10.100/101.xxx.80.xxx
ali机房:内网10.10.10.0/24,边界节点,10.10.10.100/xxx.43.xxx.50
tx机房:内网10.10.10.0/24,边界节点,10.10.10.100/xxx.159.xxx.35
1、server、client节点部署
所有节点的consul服务均由supervisord守护管理。
idc机房配置3个server模式的节点,其它的均是client模式的节点,server和client配置各举例一个
server模式:(边界server节点的配置稍有不同,后面详细介绍):
[program:consul_server]
command=/usr/local/consul/bin/consul agent -server -bootstrap-expect 3 -data-dir /usr/local/consul/data/ -config-dir /usr/local/consul/config/ -node=own-server02 -bind=10.10.10.105 -dc=xxx-own
process_name=%(process_num)s
numprocs=1
directory=/usr/local/consul/bin/
autostart=true
autorestart=true
startsecs=1
redirect_stderr=true
stdout_logfile=/opt/log/consul/consul_server.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=5
client模式:
[program:consul_client]
command=/usr/local/consul/bin/consul agent -data-dir /usr/local/consul/data/ -node=own-client04 -bind=10.10.10.214 -config-dir=/usr/local/consul/config/ -dc=xxx-own
process_name=%(process_num)s
numprocs=1
directory=/usr/local/consul/bin/
autostart=true
autorestart=true
startsecs=1
redirect_stderr=true
stdout_logfile=/opt/log/consul/consul_client.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=5
ali、tx机房的server、client节点配置类似,有区别的参数就是-dc、-bind、-node即所属的数据中心、用于集群通信的监听ip、节点名称。
每次添加一个新的节点后,consul join加入到本地集群已有的任意一个节点即可加入这个集群(这个动作可以做到批量装机里面)。
集群之间的通信设置
每个集群选取一个处于server模式的节点作为边界节点,配置与集群内的其它server模式的节点稍有差异:
[program:consul_server]
command=/usr/local/consul/bin/consul agent -server -bootstrap-expect 3 -advertise-wan=101.xxx.80.xxx -data-dir /usr/local/consul/data/ -config-dir /usr/local/consul/config/ -node=own-server03 -dc=xxxx-own
process_name=%(process_num)s
numprocs=1
directory=/usr/local/consul/bin/
autostart=true
autorestart=true
startsecs=1
redirect_stderr=true
stdout_logfile=/opt/log/consul/consul_server.log
stdout_logfile_maxbytes=50MB
相比于其它server模式节点,需要指定-advertise-wan参数。如果不指定该参数,consul join -wan加入一个集群的时候,默认使用的是内外ip(节点环境是有内外网两个以上ip),造成集群之间通信失败(如果集群之间的内网没有互通)。
每个边界节点将-advertise-wan设置成公网ip,用于集群之间的通信。
如果边界节点开启了防火墙,需要将对方的ip地址加入白名单,或者将TCP/UDP的8302端口加入彼此的白名单。
最后任意一个边界节点均可以查看到各个边界节点状态信息:
[root@xxxxxx ~]# consul members -wan
Node Address Status Type Build Protocol DC
own-server02.xxxx-own 101.xxx.80.xxx:8302 alive server 0.x.x 2 xxxx-own
ali-server03.xxxx-ali xxx.43.xxx.50:8302 alive server 0.x.x 2 xxxx-ali
tx-server02.xxxx-tx xxx.159.xxx.35:8302 alive server 0.x.x 2 xxxx-tx
[root@xxxxx ~]#
集群UI管理界面设置
将官方提供的ui界面文件部署在任意一个边界节点上,可以访问到任何一个集群的节点状态。客户端(http、dns、rpc)默认监听地址是127.0.0.1,访问ui的端口是http的8500端口,如果不设置客户端监听ip,需要一个代理(nginx)将本地的8500端口转发到外网,也可以直接指定client的监听ip:
[program:consul_server]
command=/usr/local/consul/bin/consul agent -server -bootstrap-expect 3 -advertise-wan=101.xxx.80.xxx -data-dir /usr/local/consul/data/ -config-dir /usr/local/consul/config/ -node=own-server03 -ui-dir /usr/local/consul/web/ -bind=10.10.10.100 -client=0.0.0.0 -dc=xxxx-own
process_name=%(process_num)s
numprocs=1
directory=/usr/local/consul/bin/
autostart=true
autorestart=true
startsecs=1
redirect_stderr=true
stdout_logfile=/opt/log/consul/consul_server.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=5
参数-client用来指定client监听ip,处于安全考虑可以监听在内网10.10.10.100,但是consul命令默认访问的是127.0.0.1端口,故监听0.0.0.0。配置成功后可以看到各个集群之间的状态:
consul的ACL配置
https://blog.youkuaiyun.com/llianlianpay/article/details/79028916
consul和zookeeper服务变更通知的区别:
zookeeper:客户端和服务端通过建立tcp长连接进行服务变更通知,一旦服务端有服务变化,通过socket发送消息给客户端。优点是简单,服务端主动推送消息到客户端,缺点是长连接往往不稳定,链路断开,客户端经常收不到服务端推送的消息。
consul:是基于http协议,客户端通过http api主动查询服务,如果有变更则返回服务信息,我们都知道http是一个request,一个response,而consul怎样保证服务端一有变更马上response到客户端呢,这里consul解决方案是:1轮循;2阻塞查询,通过轮循调用服务端,并且不及时返回服务信息,而是等待一定时间在返回,在规定时间内如果有服务变更则马上返回变更信息,这样就客户端就可以及时的知道服务变更。
参考:http://www.xiaomastack.com/2016/05/20/consul02/
https://blog.youkuaiyun.com/younger_china/article/details/52243718