Consul 是一个分布式,高可用,支持多数据中心的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla Public License 2.0 的协议进行开源。 在Consul的文档上,Consul 支持Service Discovery, Health Checking, Key/Value Store, Multi DataCenter。运用Consul,可以在系统中build复杂的应用和服务的发现等。
Consul 的优势
- 使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft.
- 支持多数据中心,内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等. zookeeper 和 etcd 均不提供多数据中心功能的支持.
- 支持健康检查. etcd 不提供此功能.
- 支持 http 和 dns 协议接口. zookeeper 的集成较为复杂, etcd 只支持 http 协议.
- 官方提供web管理界面, etcd 无此功能.
consul 架构
从图中可以看出,consul是支持多数据中心的,并且多数据中心是一个非常common的用户场景。公司的项目中采用consul这是比较重要的一个考虑,之前的项目一直用的是zookeeper,实现多数据中心会有比较多的问题。
- Agent - 运行在consul集群的每个node上的daemon,agent可以run在server或者是client上,每个agent都可以提供DNS或者是HTTP的接口,负责health check和service发现等。用consul agent命令可以启动,具体可run "consul agent --help"查看参数。
- Client - client把所有的RPCs转发到server端,是相对无状态的。唯一在后台运行的时client端执行了LAN gossip pool,只消耗极少的资源和网络带宽。
- Server - server 负责维护cluster state, RPC quiries, 和其他数据中心交换WAN gossip,转发queries给leader或者其他数据中心。
- Datacenter -这里文档里面指的时网络环境是私有,低延迟,高带宽的,排除和公网的通信。其实我认为和vmware的概念有些类似,vmware的一台server下面的虚拟机也可以定义为一个datacenter,不同的server可以构成不同的datacenter,这里面还包含逻辑功能的划分。对于我们测试人员来说,单个人的测试环境可以作为一个datacenter。
- Serf:consul是基于Serf上实现的,Serf是一个服务发现,编配(应用集群管理等)工具,它去中心化,高可用并且能故障恢复(容忍), Serf使用Gossip协议,采用Go语言编写。Serf提供成员关系,纠错检查,广播的功能。gossip包含的任意node-to-node间的通信,主要是基于UDP。
- LAN Gossip - 指 LAN gossip pool 包含哪些都在同一局域网或者是datacenter的node。which contains nodes that are all located on the same local area network or datacenter.
- WAN Gossip - 指 WAN gossip pool 包含哪些都在同一局域网或者是datacenter的node。
- RPC - Remote Procedure Call. 客户端和服务器端的请求/应答机制。
在这篇文档中,我会介绍Consul的一些基本用法,以及把Consul用在production的环境中。
Consul 测试环境
一开始要研究consul的时候,用vagrant搭建了4个虚拟机,有个问题没有解决。我的vagrant的虚拟机是在mac上创建的,eth0就是mac的网络,eth1才是我们创建的private network。但是consul默认就绑定eth0的,这样4台机子没办法通过eth0来通信,consul有相关的参数可以来修改bind的IP和端口,这个会再以后的文章中介绍。所以我这里还是用了现有的4台centos的vmware的虚拟机做的测试。
Node Type server1 server server2 server server2 server agent1 agent
Consul 在CentOS上的安装
安装非常简单,
安装完成后,就可以run Consul命令啦。
cd /usr/local/bin wget https://dl.bintray.com/mitchellh/consul/0.5.0_linux_amd64.zip unzip *.zip rm *.zip
consul命令行运行的方式非常简单,可以看到以下的参数,也可以参考consul的用户文档。
$ consul usage: consul [--version] [--help] <command> [<args>] Available commands are: agent Runs a Consul agent force-leave Forces a member of the cluster to enter the "left" state info Provides debugging information for operators join Tell Consul agent to join cluster keygen Generates a new encryption key leave Gracefully leaves the Consul cluster and shuts down members Lists the members of a Consul cluster monitor Stream logs from a Consul agent reload Triggers the agent to reload configuration files version Prints the Consul version
开启Bootstrap Server
一开始学习consul, 我们需要让consul 运行起来。consul server推荐至少在3~5个之间,推荐的方法是一开始启动其中一台server,并且配置到bootstrap的模式,该模式node可以指定自己作为leader,而不用进行选举。然后再依次启动其他server,配置为非bootstrap的模式。最后把第一个serverbootstrap模式停止,重新以非bootstrap模式启动,这样server之间就可以自动选举leader。
在上面的表中,我们需要指定server 1 做为bootstrap server,可以run下面的命令,以下是启动的过程。可以看到bootstrap模式下配置自己为leader。
[[email protected] ~]$ consul agent -server -bootstrap -data-dir /tmp/consul ==> WARNING: Bootstrap mode enabled! Do not enable unless necessary ==> WARNING: It is highly recommended to set GOMAXPROCS higher than 1 ==> Starting Consul agent... ==> Starting Consul agent RPC... ==> Consul agent running! Node name: ‘localhost.localdomain‘ Datacenter: ‘dc1‘ Server: true (bootstrap: true) Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400) Cluster Addr: 10.74.15.87 (LAN: 8301, WAN: 8302) Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false Atlas: <disabled> ==> Log data will now stream in as it occurs: 2015/05/11 02:58:06 [INFO] raft: Node at 10.74.15.87:8300 [Follower] entering Follower state 2015/05/11 02:58:06 [INFO] serf: EventMemberJoin: localhost.localdomain 10.74.15.87 2015/05/11 02:58:06 [INFO] serf: EventMemberJoin: localhost.localdomain.dc1 10.74.15.87 2015/05/11 02:58:06 [INFO] consul: adding server localhost.localdomain (Addr: 10.74.15.87:8300) (DC: dc1) 2015/05/11 02:58:06 [INFO] consul: adding server localhost.localdomain.dc1 (Addr: 10.74.15.87:8300) (DC: dc1) 2015/05/11 02:58:06 [ERR] agent: failed to sync remote state: No cluster leader 2015/05/11 02:58:08 [WARN] raft: Heartbeat timeout reached, starting election 2015/05/11 02:58:08 [INFO] raft: Node at 10.74.15.87:8300 [Candidate] entering Candidate state 2015/05/11 02:58:08 [INFO] raft: Election won. Tally: 1 2015/05/11 02:58:08 [INFO] raft: Node at 10.74.15.87:8300 [Leader] entering Leader state 2015/05/11 02:58:08 [INFO] consul: cluster leadership acquired 2015/05/11 02:58:08 [INFO] consul: New leader elected: localhost.localdomain 2015/05/11 02:58:08 [INFO] raft: Disabling EnableSingleNode (bootstrap) 2015/05/11 02:58:08 [INFO] consul: member ‘localhost.localdomain‘ joined, marking health alive 2015/05/11 02:58:08 [INFO] agent: Synced service ‘consul‘
启动其他servers,在 server2
and server3
, 我们用以下命令启动consul,不需要带bootstrap 选项。
[[email protected] ~]$ consul agent -server -data-dir /tmp/consul ==> WARNING: It is highly recommended to set GOMAXPROCS higher than 1 ==> Starting Consul agent... ==> Starting Consul agent RPC... ==> Consul agent running! Node name: ‘localhost.localdomain‘ Datacenter: ‘dc1‘ Server: true (bootstrap: false) Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400) Cluster Addr: 10.74.15.87 (LAN: 8301, WAN: 8302) Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false Atlas: <disabled> ==> Log data will now stream in as it occurs: 2015/05/11 03:01:54 [INFO] serf: EventMemberJoin: localhost.localdomain 10.74.15.87 2015/05/11 03:01:54 [INFO] serf: EventMemberJoin: localhost.localdomain.dc1 10.74.15.87 2015/05/11 03:01:54 [INFO] raft: Node at 10.74.15.87:8300 [Follower] entering Follower state 2015/05/11 03:01:54 [INFO] consul: adding server localhost.localdomain (Addr: 10.74.15.87:8300) (DC: dc1) 2015/05/11 03:01:54 [INFO] consul: adding server localhost.localdomain.dc1 (Addr: 10.74.15.87:8300) (DC: dc1) 2015/05/11 03:01:54 [ERR] agent: failed to sync remote state: No cluster leader 2015/05/11 03:01:55 [WARN] raft: EnableSingleNode disabled, and no known peers. Aborting election.
可以从log中看到,无法找到cluster leader和无法配置自己为leader,server2还没有和server1通信。这时,需要run下面的命令加入到server1的集群。
consul join 192.0.2.2 192.0.2.3 consul members //查看现有的cluster下面的node
当3台机子都加入到集群,我们需要配置这3台机子为同等的server,并且让它们自己选择leader,这时可以停止第一台的consul,然后再用以下命令启动:
consul agent -server -data-dir /tmp/consul consul join 192.0.2.2 192.0.2.3
现在,3太机子会互相复制信息,或者可以处理
某台机子挂掉后的情况。当有其他server需要加入时,重复上面的操作就可以。
Referencehttp://blog.coding.net/blog/intro-consul?type=hothttp://liubin.org/2014/02/22/first-serf-experience/