consul的agent有两种运行模式:client和server
server节点:负责运行一致性协议(raft协议)以及存储集群状态
client节点:可以是认为是无状态的,它依赖于server节点
consul集群在提供服务之前,必须有一个server节点被选作为leader。因此,通常需要先运行server节点(这并不是严格要求的,client节点也可以在server节点前运行,但是在server节点运行起来之前,很多请求会失败)。bootstrapping过程指的是连接这些初始化server节点并构建成一个集群的过程。
推荐的bootstrapping方法是用-bootstrap-expect配置选项。这个选项指定期望的server节点的数量,并当server节点可用的时候,自动进行bootstrapping。为了避免不一致以及脑裂现象(集群中多个节点认作自己为leader),所有的server节点要么通过-bootstrap-expect指定相同的值,要么就不指定值。只有指定特定值的server节点才会尝试建立集群。通常我们推荐每个datacenter使用3或5个server节点。因为单节点在故障的时候会丢失数据,所以不建议单server节点部署。
假如我们使用3台server节点的集群,我们可以指定-bootstrap-expect 3来分别启动Node A, Node B和Node C三个节点。当server节点们都启动之后,可以看到类似如下的信息:
[WARN] raft: EnableSingleNode disabled, and no known peers. Aborting election.
这表明节点期望有2个peers,但是现在并没有发现已知的peers,所以放弃选举。这样节点不会选自己为leader,是为了避免脑裂的现象。
为了完成leader选举,需要将server节点建立关联,组成集群。通常使用consul join命令来实现。如:
$ consul join <Node A Address> <Node B Address> <Node C Address>
Successfully joined cluster by contacting 3 nodes.
上述操作,在任意一个节点执行即可。当join操作执行成功,节点上会输出类似如下的日志信息:
[INFO] consul: adding server foo (Addr: 127.0.0.2:8300) (DC: dc1)
[INFO] consul: adding server bar (Addr: 127.0.0.1:8300) (DC: dc1)
[INFO] consul: Attempting bootstrap with nodes: [127.0.0.3:8300 127.0.0.2:8300 127.0.0.1:8300]
...
[INFO] consul: cluster leadership acquired
集群组建成功之后,可以通过consul members命令查看集群成员信息。另外,可以通过consul info命令查看集群信息(如,此时可以看到raft.num_peers值为2;还可以看到last_log_index信息,当同步完成的时候,各个server节点的last_log_index值是一样的)。
当server节点运行完成,剩余的client节点就可以开始加入了。client节点的加入可以通过join任何一个已存的节点来完成。所有的节点都是通过gossip协议来实现发现功能的。所以,一旦有节点接入到任意的集群成员,新节点都会自动找到server节点,并向server节点注册自己。