Mike Zhang

DNS DevOps CISSP CISA Security+ 摄影 程序员 北京

Consul简介

12 Aug 2018 » devops

Consul是一套分布式高可用的系统,主要提供服务发现和配置的功能,通过使用Consul可以很容易的管理服务实例的注册和提供接口给其他服务使用。

1. 主要功能

Consul的主要功能包含以下几个方面:

  1. 服务发现 通过Consul 来完成服务的统一管理和配置,借助于DNS或者HTTP, 其他服务可以查询Consul来获得依赖的服务的信息。
  2. 健康检查 Consul可以提供针对服务的健康检查,包括服务进程的可达以及服务本身节点的资源状态检查。通过检查来管理集群的整体情况,并对于请求的流量进行优化调度。
  3. 键值存储 Consul 通过简单的http API接口提供键值存储功能,应用可以借助于这个功能实现动态配置保存和一些特征值存储及集群的选举等等
  4. 多数据中心 支持跨数据中心的使用,可扩展性能好

2. 基本概念

在使用Consul的时候会遇到一些服务定义的概念,这里整理如下便于理解。

– Agent(代理) – 在Consul集群中每个节点都会运行一个代理,这个代理服务运行检查和同步服务状态,并且代理可以指定运行在客户端状态或者服务端状态。因此集群中的节点,要要么是Consul服务器或者是一个Consul客户端。

  • Client(客户端) – 客户端作为一个代理主要用于传递RPC请求到服务器端,并参与gossip协议的信息交换

  • Server(服务器) – 服务器也是一个运行在服务器模式下的代理节点,包含大量的请求处理操作,比如响应客户端的RPC请求,交换网络中的gossip信息,维护集群状态,参与Raft选举等等。

  • DataCenter(数据中心) – 数据中心内部网络环境应该满足低延迟,高带宽及网络的私有,网络不应该跨越Internet进行传输数据。

  • Consensus(一致性) – 多节点中一致性主要用于满足数据的一致性保证,通过一些措施比如选举操作来产生一个leader节点,并且对于操作的顺序要保证在不同的节点上要一致。

  • Gossip – Consul构建与Serf之上提供完全的Gossip协议支持,Gossip协议支持成员定义,失败检查以及事件广播等

  • LAN Gossip – 同一个本地网络中或者数据中心中的一个局域网Gossip池

  • WAN Gossip – 广域网Gossip池,这个级别的节点都属于服务器节点,位于不同的数据中心保持之间的通信

3. 系统架构

以下为简单的跨数据中心的Consul应用架构图,每个数据中均包含有多个服务器和多个客户端,每个中心为保证高可用,推荐部署3-5个服务器节点,实现一个可用性和效率的平衡(服务节点多,一致性处理效率会降低), 一个数据中心中的Servers选举出一个Leader. 客户端节点不受影响,可以很容易的实现上千个客户端部署。其他的服务如果需要发现依赖服务的信息,可以查询服务器或者客户端(forward到服务器中)。当服务发现需要跨越数据中心的时候,由本地的Consul服务器发请求到远程的数据中心中并获取到结果。

一个数据中心中所有节点都会加入到内部的gossip协议池,相比于心跳协议,实施节点失效检查并非通过服务器实现,而是分布式的模式下实现。客户端无需配置服务器地址,即可实现互联。同时,通过gossip协议来实现消息的通知。

服务器节点也会参与一部分WAN广域网的gossip池之间的通信,这种通信一般要延迟比较大,并且数据中心可以通过这种方式来发现彼此,支持跨数据中心的请求传递。

不同数据中心的Consul之间一般不会复制数据,彼此可以直接进行资源的rpc调用获取结果,但是也可以通过一些措施或者工具来实现数据在数据中心之间的复制。

4. Consul与其他类似服务比较

对比ZooKeeper, Doozerd以及etcd

这些系统经常出现在分布式系统中用于,管理不同的节点之间的状态和一致性操作。Consul本身支持多数据中心,以及丰富的gossip协议支持,当作为键值存储的时候,这些系统都会表现出读取数据的强一致性以及当网络分片发生的时候通过牺牲可用性来保障一致性。

对于服务发现,Consul支持的会更好些,通过内部的框架即可实现通过DNS或者HTTP接口的服务发现功能,极大的减少开发工作。其他的比如zookeeper则仅仅提供kv存储要求开发者自行实现服务发现功能。

服务发现框架一般需要健康检查和失效检查的配合才能正常工作。zookeeper提供kv来存储和删除一个断开连接的节点,尽管比简单的心跳检查实现的更成熟一些但是仍旧存在可扩展性问题,同样增加了客户端复杂性。所有的客户端都必须保持到服务器的连接来实现存活。

Consul使用一个不同架构来实现健康检查,通过每个节点上部署的客户端代理,加入到gossip池中,不仅仅可以进行简单的存活检查,也可以实现比如内存和磁盘的检查等等。通过一个http接口来减少复杂度。

Consul本身支持服务发现,健康检查和k.v存储以及跨数据中心的支持,这些功能对于上述的三套其他系统都无法完全满足,其他系统需要借助于工具或者库去开发实现,因此Consul使用上更简单容易一些。

对比Chef和Puppet配置管理工具

很多人用Chef或者Puppet来管理服务发现,通过查询一个主要的配置管理数据库来获取信息。这种方式存在的问题比较多,比如配置内容为静态,更新操作可能不会太及时。对于不健康的服务器无法进行管理等等。Consul本身提供的服务发现可以很容易的进行动态的变更服务信息。借助于健康检查,实现路由的灵活调度。多数据中心的支持也使得配置更加方便简单

对比SkyDNS 服务发现工具

SkyDNS主要提供服务发现的功能,多个节点可以通过使用http API接口的方式来注册服务,查询则可以通过HTTP或者DNS协议来完成。 Consul实现基本相似,但是提供更多功能,比如丰富的健康检查,而不是SkyDNS使用的心跳和TTL检查。多数据中心的原生支持,也是的Consul更加灵活一些。

5. 基本用法

可以参考github上的docker实例来看一下consul的使用场景,docker-compose.yml文件如下:

version: "2"
services:
  app1:
    build: ./python_app/
    ports:
      - "8080:8080"
  app2:
    build: ./python_app/
    ports:
      - "8081:8080"
  consul1:
    image: "progrium/consul:latest"
    container_name: "consul1"
    hostname: "consul1"
    ports:
      - "8400:8400"
      - "8500:8500"
      - "8600:53"
    command: "-server -bootstrap-expect 3 -ui-dir /ui"
  consul2:
    image: "progrium/consul:latest"
    container_name: "consul2"
    hostname: "consul2"
    expose:
      - "8400"
      - "8500"
      - "8600"
    command: "-server -join consul1"
    depends_on:
      - consul1
  consul3:
    image: "progrium/consul:latest"
    container_name: "consul3"
    hostname: "consul3"
    expose:
      - "8400"
      - "8500"
      - "8600"
    command: "-server -join consul1"
    depends_on:
      - consul1

启动后我们可以直接通过本地的http://localhost:8600/ui查看服务的运行状况

另外DNS查询服务如下:

» dig -p 8600 @localhost PythonApp.service.consul +tcp         zhangmingkai@zhangmingkaideMacBook-Pro

; <<>> DiG 9.9.7-P3 <<>> -p 8600 @localhost PythonApp.service.consul +tcp
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30477
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;PythonApp.service.consul.      IN      A

;; ANSWER SECTION:
PythonApp.service.consul. 0     IN      CNAME   app1.

;; Query time: 2002 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Sun Feb 25 21:13:04 CST 2018
;; MSG SIZE  rcvd: 84