入门手册、文档地址、mha_manager_consul、raft
背景
consul是什么?
consul是一个用于监控服务的一个监控工具,所有状态的服务都包含在一个控制面板内,具有发现,配置以及分割服务的功能,这些 功能可以单独使用,也可以把所有的功能集成成一个完整的服务网络,内置有proxy,也支持第三方proxy,如Envoy
consul功能
服务发现
健康检查
KV存储
服务通信安全
多数据中心
consul能解决什么问题?
consul与同类软件比较
如何开始consul的使用
consul基本体系结构
每个consul服务节点都要启动consul agent,agent只做服务的健康检查;
consul agent可以跟一个或者多个consul server进行通信,consul server存储和复制数据。他们自身会选出一个leader,只有一个server也能正常运行,但是为了避免单点故障而导致数据丢失,最好部署3到5个server节点,每个数据中心一套server集群。
入门
第一章 安装consul
首先我们在服务器上必须安装consul,使用二进制包安装即可,二进制包是所有平台通用的,当然也可以采用源码编译安装,源码编译安装参考文档
一、安装
1.找到并下载软件包,consul软件包是一个zip包,下载解压即可,程序名称就叫consul,包中的其他文件可以安全地删除而不影响consul的功能
2.设置环境变量,linux,windows
二、验证
安装好后,新启一个session检查consul是否可用,执行consul有如下输出即可证明正常安装,如果报error的话,说明环境变量设置有问题
************************************************************************
$ consul
usage: consul [--version] [--help]
Available commands are:
agent Runs a Consul agent
event Fire a new event
************************************************************************
第二章、运行consul agent
1、agent能以server或者client模式运行,每个数据中心至少运行一个server,推荐一个集群部署3到5个server节点,单节点如果出现单点故障会导致数据丢失;
2、其余所有的都运行在client模式下,client是一个轻量级的进程,具有服务注册,健康检查和发送查询到server的功能。
3、更多细节
一、启动agent
简单起见,现在以开发模式启动agent,这种模式能够简单快速的启动一个单节点的consul环境,由于这种模式不会稳定在确定的状态,所以我们不打算用在生产环境
-$ consul agent -dev
==> Starting Consul agent...
==> Starting Consul agent RPC...
==> Consul agent running!
Version: 'v0.7.0'
Node name: 'Armons-MacBook-Air'
Datacenter: 'dc1'
Server: true (bootstrap: false)
Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)
Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false
Atlas:
==> Log data will now stream in as it occurs:
2016/09/15 10:21:10 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:127.0.0.1:8300 Address:127.0.0.1:8300}]
2016/09/15 10:21:10 [INFO] raft: Node at 127.0.0.1:8300 [Follower] entering Follower state (Leader: "")
2016/09/15 10:21:10 [INFO] serf: EventMemberJoin: Armons-MacBook-Air 127.0.0.1
2016/09/15 10:21:10 [INFO] serf: EventMemberJoin: Armons-MacBook-Air.dc1 127.0.0.1
2016/09/15 10:21:10 [INFO] consul: Adding LAN server Armons-MacBook-Air (Addr: tcp/127.0.0.1:8300) (DC: dc1)
2016/09/15 10:21:10 [INFO] consul: Adding WAN server Armons-MacBook-Air.dc1 (Addr: tcp/127.0.0.1:8300) (DC: dc1)
2016/09/15 10:21:13 [DEBUG] http: Request GET /v1/agent/services (180.708µs) from=127.0.0.1:52369
2016/09/15 10:21:13 [DEBUG] http: Request GET /v1/agent/services (15.548µs) from=127.0.0.1:52369
2016/09/15 10:21:17 [WARN] raft: Heartbeat timeout from "" reached, starting election
2016/09/15 10:21:17 [INFO] raft: Node at 127.0.0.1:8300 [Candidate] entering Candidate state in term 2
2016/09/15 10:21:17 [DEBUG] raft: Votes needed: 1
2016/09/15 10:21:17 [DEBUG] raft: Vote granted from 127.0.0.1:8300 in term 2. Tally: 1
2016/09/15 10:21:17 [INFO] raft: Election won. Tally: 1
2016/09/15 10:21:17 [INFO] raft: Node at 127.0.0.1:8300 [Leader] entering Leader state
2016/09/15 10:21:17 [INFO] consul: cluster leadership acquired
2016/09/15 10:21:17 [DEBUG] consul: reset tombstone GC to index 3
2016/09/15 10:21:17 [INFO] consul: New leader elected: Armons-MacBook-Air
2016/09/15 10:21:17 [INFO] consul: member 'Armons-MacBook-Air' joined, marking health alive
2016/09/15 10:21:17 [INFO] agent: Synced service 'consul'
从上面的输出可以看出,consul agent已经启动并带有一些日志输出,agent运行在server模式,并且自己已被选为集群的leader,本地成员已被标识为健康成员
备注:consul默认使用主机名作为节点名,最好设置为带有node标志
如果在终端执行 consul members,可以看到整个consul集群的所有成员。当前环境只能看到一个(自己)
结果输出
=========================================================
节点名称,节点运行地址,健康状态,在集群中的角色,版本信息
额外的元信息可以通过添加-detailed选项来获取
consul members -detailed
Node Address Status Tags
master 127.0.0.1:8301 alive build=1.2.0:28141971,dc=dc1,id=ac61fca1-0235-c2b3-fa74-2f16ae6d95d3,port=8300,raft_vsn=3,role=consul,segment=
============================================================================================================================================================
members命令的结果输出是基于gossip协议,满足最终一致性(弱一致性),就是某个时刻从本地agent看到的并不完全匹配server的状态,
如果需要强一致性的话,可以采用HTTP API来发送请求到consul server
curl localhost:8500/v1/catalog/nodes
除了HTTP API,也可以用DNS查询接口来查询节点状态,但是得确保DNS能路由到consul agent的DNS服务器,其服务默认端口是8600,细节后叙。
dig @127.0.0.1 -p 8600 master.node.consul
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.4 <<>> @127.0.0.1 -p 8600 master.node.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49504
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;master.node.consul.INA
;; ANSWER SECTION:
master.node.consul.0INA127.0.0.1
master.node.consul.0INTXT"consul-network-segment="
;; Query time: 5 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Fri Jun 16 11:23:31 2017
;; MSG SIZE rcvd: 88
二、stop agent
可以用ctrl+c来优雅地停掉agent,agent停掉以后,就脱离了集群
节点脱离集群,consul会通知其他的集群成员。如果强制杀掉agent进程,集群的其他成员会检测到改节点已经挂掉了,当成员脱离的时候,他的服务以及服务的健康检查会从catalog里面删除掉,但是如果这个agent是被强制杀掉的话,catalog里面只会被打上cirtical的标记,并不会从catalog里面删除掉记录,这种情况的话consul会允许agent恢复,自动允许重连,而left不会出现这种情况
另外,如果停止的是一个server,为了避免中断而导致数据一致性的问题,优雅的中断就显得尤为重要,关于更多的如何安全的添加和删除server,请看这里。
第三章 service
一、服务注册
前面一章,我们已经启动了一个agent,查看集训成员,查询节点,这一章将要提到服务注册,服务查询
1.Defining a Service
可以通过service definition或者HTTP API 的方式来注册服务
最通用的就是service definition,所以这儿就采用这种方式来配置agent
首先创建配置目录,consul会在这个目录中生成所有的配置文件,所以在类unix系统上,按例我们通常会创建类似 /etc/consul.d的目录(.d前缀暗表该目录会包含一系列的配置文件)
$ sudo mkdir /etc/consul.d
接下来我们会创建一个定义服务的配置文件,假设我们有一个叫web的服务跑在80端口上。此外,我们会给他一个方便查询的这个服务的标志
$ echo '{"service": {"name": "web", "tags": ["rails"], "port": 80}}' \
| sudo tee /etc/consul.d/web.json
现在,指定配置文件,启动agent
consul agent -dev -config-dir=/etc/consul.d
************************************************log************************************************
==> Starting Consul agent...
==> Consul agent running!
Version: 'v1.2.0'
Node ID: '5a86185b-3a89-b626-cc20-a2da52de63ea'
Node name: 'master'
Datacenter: 'dc1' (Segment: '
Server: true (Bootstrap: false)
Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, DNS: 8600)
Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false
==> Log data will now stream in as it occurs:
2017/06/17 10:01:14 [DEBUG] agent: Using random ID "5a86185b-3a89-b626-cc20-a2da52de63ea" as node ID
2017/06/17 10:01:14 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:5a86185b-3a89-b626-cc20-a2da52de63ea Address:127.0.0.1:8300}]
2017/06/17 10:01:14 [INFO] serf: EventMemberJoin: master.dc1 127.0.0.1
。。。
2017/06/17 10:01:14 [INFO] agent: Synced service "web"
************************************************end************************************************
Synced service "web"表明agent已经将配置文件中指定的服务添加到列表中,已成功注册,如果想注册多个服务,目录中创建相应的配置文件即可
2.Querying Services
一旦启动agent,服务就是同步的,我们可以通过DNS或者HTTP API的方式查询服务
(1)DNS API
用DNS API,服务的DNS名称叫NAME.service.consul.
如当前注册的web服务,生成的子域名就叫web.service.consul
a.
dig @127.0.0.1 -p 8600 web.service.consul
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.4 <<>> @127.0.0.1 -p 8600 web.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1550
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;web.service.consul. IN A
;; ANSWER SECTION:
web.service.consul. 0 IN A 127.0.0.1
web.service.consul. 0 IN TXT "consul-network-segment="
;; Query time: 1 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Sat Jun 17 10:19:51 2017
;; MSG SIZE rcvd: 88
如上,会返回可用服务节点的ip地址,一条记录只有一个ip地址
b.use the DNS API to retrieve the entire address/port pair
$ dig @127.0.0.1 -p 8600 web.service.consul SRV
c.use the DNS API to filter services by tags
$ dig @127.0.0.1 -p 8600 rails.web.service.consul
(2)HTTP API
a.普通查询
curl http://localhost:8500/v1/catalog/service/web
b.过滤健康实例
curl 'http://localhost:8500/v1/health/service/web?passing'
(3)更新服务 -- 这部分存储疑问
修改配置文件,然后给agent发送sighup中断可以更新service definition,这种更新不会造成downtime以及服务查询的unavailability
可以采用HTTP API来动态的添加,删除,修改service
第四章 connect 服务间通信的自动认证与加密
1.HTTP API or DNS
2.connect
connect采用自动的TSL加密与认证
应用完全没必要修改用户连接,sidecar proxies能自动建立TLS连接,而且对inbound与outbound连接是完全无感知的,如果想要最佳的性能和安全,可以考虑natively integrate with Connect
备注:本入门向导不适用于生产环境,生产环境移步 Connect production guide
windows支持,略
socat安装
wget http://mirror.centos.org/centos/6/os/x86_64/Packages/compat-readline5-5.2-17.1.el6.x86_64.rpm
rpm -ivh compat-readline5-5.2-17.1.el6.x86_64.rpm
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/Packages/s/socat-1.7.2.3-1.el6.x86_64.rpm
rpm -ivh socat-1.7.2.3-1.el6.x86_64.rpm
部分内容省略
第五章 consul集群
单节点consul不能用于生产环境
当启动一个consul agent时,他是一个独立的节点,不能识别其他的任何节点,为了与别的集群成员互通,那么这个独立的agent必须加入一个已经存在的集群,加入集群后,agent能快速的发现并和别的集群成员传播数据,consul agent能加入任何agent,不只是server模式的agent
一、启动agent
为了模拟真实环境,我们通过 Vagrant启用了一个两节点的集群,Vagrantfile demo section of the Consul repo
1.集群中节点名称唯一,默认是主机名,手动override-node
command-line option
2.绑定ip地址,bind
address,这个地址是consul监控的地址,必须所有集群节点都可访问到。绑定地址不是绝对必要的,但是最好绑定一个,因为默认情况下consul会尝试监听所有的ipv4接口,并且不会报错,一般生产环境都会有多网卡,最好服务ip绑定好
第一个节点将会作为集群唯一的server节点
-bootstrap-expect
flag代表期望额外加入的server节点的数量,这在期望所有的server已经成功加入才开始同步数据时可以采用
-enable-script-checks
启用该选项是为了能够通过执行外部脚本来进行健康检查,后面的例子将会用到,在生产环境中,结合ACLs控制注册的仲裁脚本
最后是配置目录,config-dir
flag
综上所述,有
节点1 --server
vagrant ssh n1
consul agent -server -bootstrap-expect=1 \
-data-dir=/tmp/consul -node=agent-one -bind=172.20.20.10 \
-enable-script-checks=true -config-dir=/etc/consul.d
节点2 --client
vagrant ssh n2
consul agent -data-dir=/tmp/consul -node=agent-two \
-bind=172.20.20.11 -enable-script-checks=true -config-dir=/etc/consul.d
这时候,我们有两个agent在运行,一个server一个client,但是这两个agent仍然不能互相通信,他们自己本身就是一个单节点的集群,运行consul members即可验证
二、加入集群
新开一个终端,运行如下命令,将第一个agent加入到第二个agent
$ vagrant ssh n1
...
vagrant@n1:~$ consul join 172.20.20.11
Successfully joined cluster by contacting 1 nodes.
两个agent的日志都会记录这些信息,consul members验证一下结果
三、自动加入集群
无人工干预加入新节点到数据中心,aws ec2,google cloud,Azure支持
四、查询节点
五、脱离集群
第六章 健康检查
检查节点和服务是否健康的重要组件
一、健康检查定义
类似service,健康检查也可以通过定义check definition模块来实现,或者调用HTTP API
definition通用
0.9.0或者更新的版本必须启用enable_script_checks选项
在第二个节点的consul配置目录下创建两个配置文件
vagrant@n2:~$ echo '{"check": {"name": "ping",
"args": ["ping", "-c1", "google.com"], "interval": "30s"}}' \
>/etc/consul.d/ping.json
vagrant@n2:~$ echo '{"service": {"name": "web", "tags": ["rails"], "port": 80,
"check": {"args": ["curl", "localhost"], "interval": "10s"}}}' \
>/etc/consul.d/web.json
命令的具体含义
The first definition adds a host-level check named "ping". This check runs on a 30 second interval, invoking ping -c1 google.com. On a script-based health check, the check runs as the same user that started the Consul process. If the command exits with an exit code >= 2, then the check will be flagged as failing and the service will be considered unhealthy. This is the contract for any script-based health check.
The second command modifies the service named web, adding a check that sends a request every 10 seconds via curl to verify that the web server is accessible. As with the host-level health check, if the script exits with an exit code >= 2, the check will be flagged as failing and the service will be considered unhealthy.
现在我们可以重启第二个agent,也可以consul reload,或者发一个中断,下面是输出日志内容
==> Starting Consul agent...
...
[INFO] agent: Synced service 'web'
[INFO] agent: Synced check 'service:web'
[INFO] agent: Synced check 'ping'
[WARN] Check 'service:web' is now critical
二、健康状态检查
1.HTTP API
curl http://localhost:8500/v1/health/state/critical
2.DNS
dig @127.0.0.1 -p 8600 web.service.consul
第六章 KV存储
解决动态配置服务的问题
文档
第七章 web ui
第八章
1.Documentation - The documentation is an in-depth reference guide to all the features of Consul, including technical details about the internals of how Consul operates.
2.Guides - This section provides various getting started guides with Consul, including how to bootstrap a new datacenter.
3.Examples - The work-in-progress examples folder within the GitHub repository for Consul contains functional examples of various use cases of Consul to help you get started with exactly what you need
gossip protocol