使用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算法实现一致性

docker 需要启动时启动一个命令 docker启动consul_数据中心

 

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界面:

docker 需要启动时启动一个命令 docker启动consul_json_02

 

 

http://IP:8500 使用我们刚才的token进入,可以在acl里面创建相应权限的角色,这个在官方网站有详细的说明,然后给这个角色创建一个token,我们的服务注册的时候就可以在配置中加入这个acl_token,然后调用接口或注册服务。

这里说明一下,我这是演示用法,因为是一个虚拟机部署了全部的服务并且一次性全部,所以用的全是同一个token,在实际的生产过程中,流程应该是先启动一台server,然后进入ui界面给每一台server生成一个token并配置相应的权限,然后再启动加入集群,服务实例也是一样,应该给每个服务创建token并配置权限,这样才比较安全

 

暂时告于段落……如果接下来项目中还有用到的再补充

参考链接:https://zhuanlan.zhihu.com/p/433947538