使用docker-compose搭建Consul集群
Consul的功能作用
Consul是一个分布式、高可用的系统,是一个为了解决在生产环境中服务注册,服务发现,服务配置的一个工具,它有多个组件,提供如下几个关键功能:
- 服务发现: Consul的某些客户端可以提供一个服务,例如api或者mysql,其它客户端可以使用Consul去发现这个服务的提供者。使用DNS或者HTTP,应用可以很容易的找到他们所依赖的服务
- 健康检查: Consul客户端可以提供一些健康检查,这些健康检查可以关联到一个指定的服务(服务是否返回200 OK),也可以关联到本地节点(内存使用率是否在90%以下)。这些信息可以被一个操作员用来监控集群的健康状态,被服务发现组件路由时用来远离不健康的主机
- 键值存储: 应用可以使用Consul提供的分层键值存储用于一些目的,包括动态配置、特征标记、协作、leader选举等等。通过一个简单的HTTP API可以很容易的使用这个组件
- 多数据中心: Consul对多数据中心有非常好的支持,这意味着Consul用户不必担心由于创建更多抽象层而产生的多个区域
工作原理
- Consul Cluster由部署和运行了Consul Agent的节点组成。 在Cluster中有两种角色:Server和 Client。
- Server和Client的角色和Consul Cluster上运行的应用服务无关, 是基于Consul层面的一种角色划分.
- Consul Server: 用于维护Consul Cluster的状态信息, 实现数据一致性, 响应RPC请求。官方建议是: 至少要运行3个或者3个以上的Consul Server。 多个server之中需要选举一个leader, 这个选举过程Consul基于Raft协议实现. 多个Server节点上的Consul数据信息保持强一致性。 在局域网内与本地客户端通讯,通过广域网与其他数据中心通讯。Consul Client: 只维护自身的状态, 并将HTTP和DNS接口请求转发给服务端。
- Consul 支持多数据中心, 多个数据中心要求每个数据中心都要安装一组Consul cluster,多个数据中心间基于gossip protocol协议来通讯, 使用Raft算法实现一致性
consul中包括3中不同的角色:client、server、server-leader
Client(客户端):转发所有的请求给server无状态,不持久化数据参与LAN Gossip的健康检查
server(服务器):持久化数据转发请求给server-Leader参数Server-Leader选举通过WAN Gossip(流算法协议,Gassndra和比特币的底层算法一样,符合弱一致性),与其他的数据中心交换数据
Server-leader:响应RPC的请求将服务列表数据同步给server
Agent:agent是一个守护线程跟随consul应用启动而启动负责检查、维护节点同步
consul agent介绍:
consul通过agent来运行的,agent分为server 和client两种类型,这两种类型基本上没有什么区别,server agent是将服务的消息存储,一般来说为了防止单点故障推荐使用3到5个来构建集群架构。
而client agent主要用于注销服务、健康检查及转发server agent的查询等,相当于一个代理,因此它必须要在集群的每台主机上运行。
使用ACL访问控制Consul
ACL是Consul用来控制访问API与data的。 首先,我们创建一个uuid,也可以使用consul自带的生成key的功能
[root@localhost opt]# docker exec consul1 consul keygen
XAi/F5LQ+IbrAW8Mkyon+K+PCkSu+aoFf2YUeixMYA0=
使用这个token,我们创建一个acl.json和acl_client.json文件,分别给与server节点和client节点使用
acl.json
{
"acl_datacenter": "dc1",
"acl_master_token": "XAi/F5LQ+IbrAW8Mkyon+K+PCkSu+aoFf2YUeixMYA0=",
"acl_default_policy": "deny"
}
acl_client.json
{
"acl_datacenter": "dc1",
"acl_token": "XAi/F5LQ+IbrAW8Mkyon+K+PCkSu+aoFf2YUeixMYA0="
}
分发 acl.json、acl_client.json 文件到 ./consul/{consul1/config ,consul2/config,consul3/config}
目录下
注意上面的分发路径需要跟docker-compose.yaml挂载的配置文件路径一致,如下
version: '3.5'
services:
consul1:
image: consul:latest
container_name: consul1
restart: always
command: agent -server -client=0.0.0.0 -bootstrap-expect=3 -node=consul1 -config-dir=/consul/config
volumes:
- ./consul/consul1/data:/consul/data
- ./consul/consul1/config:/consul/config
consul2:
image: consul:latest
container_name: consul2
restart: always
command: agent -server -client=0.0.0.0 -retry-join=consul1 -node=consul2 -config-dir=/consul/config
volumes:
- ./consul/consul2/data:/consul/data
- ./consul/consul2/config:/consul/config
consul3:
image: consul:latest
container_name: consul3
restart: always
command: agent -server -client=0.0.0.0 -retry-join=consul1 -node=consul3 -config-dir=/consul/config
volumes:
- ./consul/consul3/data:/consul/data
- ./consul/consul3/config:/consul/config
consul4:
image: consul:latest
container_name: consul4
restart: always
ports:
- 8500:8500
command: agent -client=0.0.0.0 -retry-join=consul1 -ui -node=client1 -config-dir=/consul/config
volumes:
- ./consul/consul4/data:/consul/data
- ./consul/consul4/config:/consul/config
启动服务:docker-compose -f consul_cluster.yaml up -d
启动了4个consul,其中consul1 是主节点,consul2、consul3 是子节点。consul4是提供ui服务的。
server模式启动的命令行参数说明:
- -server:表示当前使用的server模式;如果没有指定,则表示是client模式。
- -node:指定当前节点在集群中的名称。
- -config-dir:指定配置文件路径,定义服务的;路径下面的所有.json结尾的文件都被访问;缺省值为:/consul/config。
- -data-dir: consul存储数据的目录;缺省值为:/consul/data。
- -datacenter:数据中心名称,缺省值为dc1。
- -ui:使用consul自带的web UI界面 。
- -join:加入到已有的集群中。
- -enable-script-checks: 检查服务是否处于活动状态,类似开启心跳。
- -bind: 绑定服务器的ip地址。
- -client: 客户端可访问ip,缺省值为:“127.0.0.1”,即仅允许环回连接。
- -bootstrap-expect:在一个datacenter中期望的server节点数目,consul启动时会一直等待直到达到这个数目的server才会引导整个集群。这个参数的值在同一个datacenter的所有server节点上必须保持一致。
另外一个参数-bootstrap,用来控制一个server是否运行在bootstrap模式:当一个server处于bootstrap模式时,它可以选举自己为leader;注意在一个datacenter中只能有一个server处于bootstrap模式。所以这个参数一般只能用在只有一个server的开发环境中,在有多个server的cluster产品环境中,不能使用这个参数,否则如果多个server都标记自己为leader那么会导致数据不一致。另外该标记不能和-bootstrap-expect同时指定。
consul 端口的了解
端口 | 说明 |
TCP/8300 | 8300端口用于服务器节点。客户端通过该端口RPC协议调用服务端节点 |
TCP/UDP/8301 | 8301端口用于单个数据中心所有节点之间的互相通信, 即对LAN池信息的同步。她使得整个数据中心能够自动发现服务器地址,分布式检测节点故障,事件广播(如领导选举事件) |
TCP/UDP/8302 | 8302端口用于单个或多个数据中心之间的服务器节点的信息同步,即对WAN池信息的同步。它针对互联网的高延迟进行了优化,能够实现跨数据中心请求 |
8500 | 8500端口基于HTTP协议,用于API接口或者WEB UI访问 |
8600 | 8600端口作为DNS服务器,它使得我们可以通过节点名查询节点信息 |
这个时候无论是服务注册还是rpc调用都需要有token才能调用,打开ui界面:
http://IP:8500 使用我们刚才的token进入,可以在acl里面创建相应权限的角色,这个在官方网站有详细的说明,然后给这个角色创建一个token,我们的服务注册的时候就可以在配置中加入这个acl_token,然后调用接口或注册服务。
这里说明一下,我这是演示用法,因为是一个虚拟机部署了全部的服务并且一次性全部,所以用的全是同一个token,在实际的生产过程中,流程应该是先启动一台server,然后进入ui界面给每一台server生成一个token并配置相应的权限,然后再启动加入集群,服务实例也是一样,应该给每个服务创建token并配置权限,这样才比较安全
暂时告于段落……如果接下来项目中还有用到的再补充
参考链接:https://zhuanlan.zhihu.com/p/433947538