本文介绍了一个服务发现和配置共享的软件,简单介绍了 Consul 的原理和使用, 一篇小文抛砖引玉,希望能吸引感兴趣的童鞋一起探讨研究。

Consul 是什么

Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla Public License 2.0 的协议进行开源. Consul 支持健康检查,并允许 HTTP 和 DNS 协议调用 API 存储键值对. 命令行超级好用的虚拟机管理软件 vgrant 也是 HashiCorp 公司开发的产品. 一致性协议采用 Raft 算法,用来保证服务的高可用. 使用 GOSSIP 协议管理成员和广播消息, 并且支持 ACL 访问控制.

Consul 的使用场景

  • docker 实例的注册与配置共享
  • coreos 实例的注册与配置共享
  • vitess 集群
  • SaaS 应用的配置共享
  • 与 confd 服务集成,动态生成 nginx 和 haproxy 配置文件

Consul 的优势

  • 使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft.
  • 支持多数据中心,内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等. zookeeper 和 etcd 均不提供多数据中心功能的支持.
  • 支持健康检查. etcd 不提供此功能.
  • 支持 http 和 dns 协议接口. zookeeper 的集成较为复杂, etcd 只支持 http 协议.
  • 官方提供web管理界面, etcd 无此功能.

综合比较, Consul 作为服务注册和配置管理的新星, 比较值得关注和研究.

Consul 的角色

  • client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群.
  • server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯. 每个数据中心的 server 数量推荐为 3 个或是 5 个.

架构

https://www.consul.io/docs/internals/architecture.html

安装 Consul

Linux 64bit:

https://www.consul.io/downloads.html
https://www.consul.io/docs/install/index.html
unzip consul_1.1.0_linux_amd64.zip
sudo cp consul /usr/local/bin/

初体验

启动

consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node node-1 -bind 10.10.10.10

查看成员

[root@xiexianbin_cn ~]# consul members
Node    Address           Status  Type    Build  Protocol  DC   Segment
node-1  10.10.10.10:8301  alive   server  1.1.0  2         dc1  <all>

Consul agent 日志

[root@xiexianbin_cn ~]# consul monitor
...

查看节点状态

[root@xiexianbin_cn ~]# consul operator raft list-peers
Node    ID                Address           State     Voter  RaftProtocol
test-1   10.10.10.10:8080  10.10.10.10:8080  follower  true   2
test-2   10.10.10.11:8080  10.10.10.11:8080  leader    true   2
test-3   10.10.10.12:8080  10.10.10.12:8080  follower  true   2

查看节点详情

[root@xiexianbin_cn ~]# curl 127.0.0.1:8500/v1/catalog/nodes | python -mjson.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   235  100   235    0     0   222k      0 --:--:-- --:--:-- --:--:--  229k
[
    {
        "Address": "10.10.10.10",
        "CreateIndex": 5,
        "Datacenter": "dc1",
        "ID": "c2acbfcf-2f10-8cbe-c77c-f168713cc850",
        "Meta": {
            "consul-network-segment": ""
        },
        "ModifyIndex": 6,
        "Node": "node-1",
        "TaggedAddresses": {
            "lan": "10.10.10.10",
            "wan": "10.10.10.10"
        }
    }
]
[root@xiexianbin_cn ~]# 

使用DNS协议查看节点信息

[root@xiexianbin_cn ~]# dig @127.0.0.1 -p 8600 node-1.node.consul

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> @127.0.0.1 -p 8600 node-1.node.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19495
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;node-1.node.consul.        IN  A

;; ANSWER SECTION:
node-1.node.consul. 0   IN  A   10.10.10.10

;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Thu Jun 14 13:31:24 CST 2018
;; MSG SIZE  rcvd: 63

[root@xiexianbin_cn ~]# 

注册服务示例

注册两个 Mysql 服务的实例, 数据中心在 dc1, 端口都是 3306. 具体为以下命令:

curl -X PUT -d '{"Datacenter": "dc1", "Node": "mysql-1", "Address": "mysql-1.node.consul","Service": {"Service": "mysql", "tags": ["master","v1"], "Port": 3306}}' http://127.0.0.1:8500/v1/catalog/register
curl -X PUT -d '{"Datacenter": "dc1", "Node": "mysql-2", "Address": "mysql-2.node.consul","Service": {"Service": "mysql", "tags": ["slave","v1"],"Port": 3306}}' http://127.0.0.1:8500/v1/catalog/register
[root@xiexianbin_cn ~]# curl http://127.0.0.1:8500/v1/catalog/service/mysql | python -mjson.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   628  100   628    0     0   560k      0 --:--:-- --:--:-- --:--:--  613k
[
    {
        "Address": "mysql-1.node.consul",
        "CreateIndex": 356,
        "Datacenter": "dc1",
        "ID": "",
        "ModifyIndex": 356,
        "Node": "mysql-1",
        "NodeMeta": null,
        "ServiceAddress": "",
        "ServiceEnableTagOverride": false,
        "ServiceID": "mysql",
        "ServiceMeta": {},
        "ServiceName": "mysql",
        "ServicePort": 3306,
        "ServiceTags": [
            "master",
            "v1"
        ],
        "TaggedAddresses": null
    },
    {
        "Address": "mysql-2.node.consul",
        "CreateIndex": 357,
        "Datacenter": "dc1",
        "ID": "",
        "ModifyIndex": 357,
        "Node": "mysql-2",
        "NodeMeta": null,
        "ServiceAddress": "",
        "ServiceEnableTagOverride": false,
        "ServiceID": "mysql",
        "ServiceMeta": {},
        "ServiceName": "mysql",
        "ServicePort": 3306,
        "ServiceTags": [
            "slave",
            "v1"
        ],
        "TaggedAddresses": null
    }
]
[root@xiexianbin_cn ~]# 
dig @127.0.0.1 -p 8600 mysql.service.consul SRV

; <<>> DiG 9.10.0-P2 <<>> @127.0.0.1 -p 8600 mysql.service.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12821
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 2
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;mysql.service.consul.    IN  SRV

;; ANSWER SECTION:
mysql.service.consul. 0 IN  SRV 1 1 3306 mysql-2.node.dc1.consul.
mysql.service.consul. 0 IN  SRV 1 1 3306 mysql-1.node.dc1.consul.

;; ADDITIONAL SECTION:
mysql-2.node.dc1.consul. 0 IN  CNAME mysql-2.node.consul.
mysql-1.node.dc1.consul. 0 IN  CNAME mysql-1.node.consul.

;; Query time: 7 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: Thu Jun 14 13:37:19 CST 2018
;; MSG SIZE  rcvd: 113

完毕