环境
centos:7.3
docker:1.12.6
kernel:3.10.0-514.6.1.el7.x86_64
consul:0.8.1
server1:10.1.13.221
server2:10.1.13.222
consul的功能
·服务发现
·健康检查
·支持多数据中心
·key/value存储
consul的使用场景
·docker实例的注册与配置共享
·coreos实例的注册与配置共享
consul的优势
·使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft
·支持多数据中心,内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等. zookeeper 和 etcd 均不提供多数据中心功能的支持
·支持健康检查. etcd 不提供此功能
·官方提供web管理界面, etcd 无此功能
·支持 http 和 dns 协议接口. zookeeper 的集成较为复杂, etcd 只支持 http 协议
consul发现机制
当一个Consul代理启动后,它并不知道其它节点的存在,它是一个孤立的 单节点集群,如果想感知到其它节点的存在,它必须加入到一个现存的集群,要加入到一个现存的集群,它只用加入集群中任意一个现存的成员,当加入一个现存的成员后,会通过成员间的通讯很快发现集群中的其它成员,一个Consul代理可以加入任意一个代理,而不仅仅是服务节点
参数
-advertise:通知展现地址用来改变我们给集群中的其他节点展现的地址,一般情况下-bind地址就是展现地址
-bootstrap:用来控制一个server是否在bootstrap模式,在一个datacenter中只能有一个server处于bootstrap模式,当一个server处于bootstrap模式时,可以自己选举为raft leader。
-bootstrap-expect:在一个datacenter中期望提供的server节点数目,当该值提供的时候,consul一直等到达到指定sever数目的时候才会引导整个集群,该标记不能和bootstrap公用
-bind:该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的,默认是0.0.0.0
-client:consul绑定在哪个client地址上,这个地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1
-config-file:明确的指定要加载哪个配置文件
-config-dir:配置文件目录,里面所有以.json结尾的文件都会被加载
-data-dir:提供一个目录用来存放agent的状态,所有的agent允许都需要该目录,该目录必须是稳定的,系统重启后都继续存在
-dc:该标记控制agent允许的datacenter的名称,默认是dc1
-encrypt:指定secret key,使consul在通讯时进行加密,key可以通过consul keygen生成,同一个集群中的节点必须使用相同的key
-join:加入一个已经启动的agent的ip地址,可以多次指定多个agent的地址。如果consul不能加入任何指定的地址中,则agent会启动失败,默认agent启动时不会加入任何节点。
-retry-join:和join类似,但是允许你在第一次失败后进行尝试。
-retry-interval:两次join之间的时间间隔,默认是30s
-retry-max:尝试重复join的次数,默认是0,也就是无限次尝试
-log-level:consul agent启动后显示的日志信息级别。默认是info,可选:trace、debug、info、warn、err。
-node:节点在集群中的名称,在一个集群中必须是唯一的,默认是该节点的主机名
-protocol:consul使用的协议版本
-rejoin:使consul忽略先前的离开,在再次启动后仍旧尝试加入集群中。
-server:定义agent运行在server模式,每个集群至少有一个server,建议每个集群的server不要超过5个
-syslog:开启系统日志功能,只在linux/osx上生效
-pid-file:提供一个路径来存放pid文件,可以使用该文件进行SIGINT/SIGHUP(关闭/更新)agent
下载地址:
https://releases.hashicorp.com/consul/0.8.1/consul_0.8.1_linux_amd64.zip
安装:
#unzip consul_0.8.1_linux_amd64.zip
#mv consul /usr/local/bin
简单使用
[root@localhost ~]# nohup consul agent -server -bootstrap -data-dir /opt/consul -node=s221 -bind=10.1.13.221 &
[root@localhost ~]# consul info
agent:
check_monitors = 0
check_ttls = 0
checks = 0
services = 1
build:
prerelease =
revision = 'e9ca44d
version = 0.8.1
consul:
bootstrap = true
known_datacenters = 1
leader = true
leader_addr = 10.1.13.221:8300
server = true
raft:
applied_index = 191
commit_index = 191
fsm_pending = 0
last_contact = 0
last_log_index = 191
last_log_term = 4
last_snapshot_index = 0
last_snapshot_term = 0
latest_configuration = [{Suffrage:Voter ID:10.1.13.221:8300 Address:10.1.13.221:8300}]
latest_configuration_index = 1
num_peers = 0
protocol_version = 2
protocol_version_max = 3
protocol_version_min = 0
snapshot_version_max = 1
snapshot_version_min = 0
state = Leader
term = 4
runtime:
arch = amd64
cpu_count = 2
goroutines = 63
max_procs = 2
os = linux
version = go1.8.1
serf_lan:
encrypted = false
event_queue = 1
event_time = 3
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 1
members = 1
query_queue = 0
query_time = 1
serf_wan:
encrypted = false
event_queue = 0
event_time = 1
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 1
members = 1
query_queue = 0
query_time = 1
server2:10.1.13.222[client端]
[root@localhost ~]# nohup consul agent -data-dir /opt/consul -node=c222 -bind=10.1.13.222 &
这时查看状态,是没有加入到server端的
[root@localhost ~]# consul members
Node Address Status Type Build Protocol DC
c222 10.1.13.222:8301 alive client 0.8.1 2 dc1
需要在server1:10.1.13.221服务端执行,join后边加客户端的ip
[root@localhost ~]# consul join 10.1.13.222
或者在client启动的时候加入
[root@localhost ~]# nohup consul agent -data-dir /opt/consul -node=c222 -join=10.1.13.221 -bind=10.1.13.222 &
再查看状态,服务端和客户端都一样
[root@localhost ~]# consul members
Node Address Status Type Build Protocol DC
c222 10.1.13.222:8301 alive client 0.8.1 2 dc1
s221 10.1.13.221:8301 alive server 0.8.1 2 dc1
DNS查看
[root@localhost ~]# dig @127.0.0.1 -p 8600 c222.node.consul
...
c222.node.consul. 0 IN A 10.1.13.222
...
服务注册
服务注册有两种方式
·服务定义:是服务注册最常用的方法
·HTTP API:通过HTTP API方式注册
服务定义注册
服务定义
[root@localhost ~]# mkdir /etc/consul.d
[root@localhost ~]# echo '{"service": {"name": "web", "tags": ["rails"], "port": 80}}' >/etc/consul.d/web.json
[root@localhost ~]# nohup consul agent -server -bootstrap-expect 1 -data-dir /opt/consul -config-dir /etc/consul.d -node=s221 -bind=10.1.13.221 &
查看定义的服务
方式1
[root@localhost ~]# dig @127.0.0.1 -p8600 web.service.consul
...
web.service.consul. 0 IN A 10.1.13.221
...
方式2
[root@lcoalhost ~]# curl -s http://localhost:8500/v1/catalog/service/web | python -m json.tool
[
{
"Address": "10.1.13.221",
"CreateIndex": 325,
"ID": "cea73f23-8839-eef8-c932-2ab960e7e019",
"ModifyIndex": 325,
"Node": "s221",
"NodeMeta": {},
"ServiceAddress": "",
"ServiceEnableTagOverride": false,
"ServiceID": "web",
"ServiceName": "web",
"ServicePort": 80,
"ServiceTags": [
"rails"
],
"TaggedAddresses": {
"lan": "10.1.13.221",
"wan": "10.1.13.221"
}
}
]
HTTP API方式注册
服务定义
[root@lcoalhost ~]# curl -X PUT http://127.0.0.1:8500/v1/agent/service/register -i -H "Content-Type:application/json" -H "Accept:application/json" -d '{"ID":"db","Name" :"db","Tags":["duxuefeng"],"Address":"10.1.13.221","Port":3306}'
查看定义的服务
[root@localhost ~]# curl -s http://localhost:8500/v1/catalog/service/db | python -m json.tool
[
{
"Address": "10.1.13.221",
"CreateIndex": 377,
"ID": "cea73f23-8839-eef8-c932-2ab960e7e019",
"ModifyIndex": 377,
"Node": "s221",
"NodeMeta": {},
"ServiceAddress": "10.1.13.221",
"ServiceEnableTagOverride": false,
"ServiceID": "db",
"ServiceName": "db",
"ServicePort": 3306,
"ServiceTags": [
"duxuefeng"
],
"TaggedAddresses": {
"lan": "10.1.13.221",
"wan": "10.1.13.221"
}
}
]
服务添加主机
如果在server1上注册一个服务
server1:10.1.13.221[server端]
[root@lcoaolhost ~]# curl -X PUT http://127.0.0.1:8500/v1/agent/service/register -i -H "Content-Type:application/json" -H "Accept:application/json" -d '{"ID":"nginx","Name" :"nginx","Tags":["duxuefeng"],"Address":"10.1.13.221","Port":80}'
需要在其他主机上(server2)添加自己到服务中,前提是这台主机已经加入到cluster中
server2:10.1.13.222[client端]
[root@localhost ~]# consul members
Node Address Status Type Build Protocol DC
c222 10.1.13.222:8301 alive client 0.8.1 2 dc1
s221 10.1.13.221:8301 alive server 0.8.1 2 dc1
[root@localhost ~]# curl -X PUT http://127.0.0.1:8500/v1/agent/service/register -i -H "Content-Type:application/json" -H "Accept:application/json" -d '{"ID":"nginx","Name" :"nginx","Tags":["duxuefeng"],"Address":"10.1.13.222","Port":80}'
查看
[root@localhost ~]# curl -s http://localhost:8500/v1/catalog/service/db | python -m json.tool
[
{
"Address": "10.1.13.222",
"CreateIndex": 506,
"ID": "8b53f13a-f95b-b23a-db14-a4bc62e83bea",
"ModifyIndex": 506,
"Node": "c222",
"NodeMeta": {},
"ServiceAddress": "10.1.13.222",
"ServiceEnableTagOverride": false,
"ServiceID": "nginx",
"ServiceName": "nginx",
"ServicePort": 80,
"ServiceTags": [
"duxuefeng"
],
"TaggedAddresses": {
"lan": "10.1.13.222",
"wan": "10.1.13.222"
}
},
{
"Address": "10.1.13.221",
"CreateIndex": 377,
"ID": "cea73f23-8839-eef8-c932-2ab960e7e019",
"ModifyIndex": 503,
"Node": "s221",
"NodeMeta": {},
"ServiceAddress": "10.1.13.221",
"ServiceEnableTagOverride": false,
"ServiceID": "nginx",
"ServiceName": "nginx",
"ServicePort": 80,
"ServiceTags": [
"duxuefeng"
],
"TaggedAddresses": {
"lan": "10.1.13.221",
"wan": "10.1.13.221"
}
}
]
删除节点
在要删除的节点上退出consul cluster
server2:10.1.13.222[client端]
[root@localhost ~]# consul leave
[root@localhost ~]# curl -s http://localhost:8500/v1/catalog/service/db | python -m json.tool
[
{
"Address": "10.1.13.221",
"CreateIndex": 377,
"ID": "cea73f23-8839-eef8-c932-2ab960e7e019",
"ModifyIndex": 503,
"Node": "s221",
"NodeMeta": {},
"ServiceAddress": "10.1.13.221",
"ServiceEnableTagOverride": false,
"ServiceID": "db",
"ServiceName": "db",
"ServicePort": 3306,
"ServiceTags": [
"duxuefeng"
],
"TaggedAddresses": {
"lan": "10.1.13.221",
"wan": "10.1.13.221"
}
}
]
consul节点健康检查
在需要做健康检查的节点上,应放在所有节点上
[root@localhost ~]# echo '{"check": {"name": "ping", "script": "ping -c1 www.baidu.com >/dev/null", "interval": "30s"}}' >/etc/consul.d/ping.json
[root@localhost ~]# nohup consul agent -data-dir /opt/consul -node=c222 -join=10.1.13.221 -bind=10.1.13.222 -config-dir /etc/consul.d &
[root@localhost ~]# curl -s http://localhost:8500/v1/health/state/any | python -m json.tool
[
{
"CheckID": "ping",
"CreateIndex": 621,
"ModifyIndex": 625,
"Name": "ping",
"Node": "c222",
"Notes": "",
"Output": "",
"ServiceID": "",
"ServiceName": "",
"Status": "passing"
},
{
"CheckID": "serfHealth",
"CreateIndex": 622,
"ModifyIndex": 622,
"Name": "Serf Health Status",
"Node": "c222",
"Notes": "",
"Output": "Agent alive and reachable",
"ServiceID": "",
"ServiceName": "",
"Status": "passing"
},
{
"CheckID": "ping",
"CreateIndex": 600,
"ModifyIndex": 603,
"Name": "ping",
"Node": "s221",
"Notes": "",
"Output": "",
"ServiceID": "",
"ServiceName": "",
"Status": "passing"
},
{
"CheckID": "serfHealth",
"CreateIndex": 175,
"ModifyIndex": 175,
"Name": "Serf Health Status",
"Node": "s221",
"Notes": "",
"Output": "Agent alive and reachable",
"ServiceID": "",
"ServiceName": "",
"Status": "passing"
}
]
测试
把本机的解析关掉
[root@localhost ~]# vi /etc/resolv.conf
# Generated by NetworkManager
search 223.5.5.5
#nameserver 8.8.8.8
#nameserver 10.1.1.1
[root@localhost ~]# curl -s http://localhost:8500/v1/health/state/any | python -m json.tool
[
{
"CheckID": "ping",
"CreateIndex": 621,
"ModifyIndex": 652,
"Name": "ping",
"Node": "c222",
"Notes": "",
"Output": "ping: www.baidu.com: \u672a\u77e5\u7684\u540d\u79f0\u6216\u670d\u52a1\n",
"ServiceID": "",
"ServiceName": "",
"Status": "critical"
},
{
"CheckID": "serfHealth",
"CreateIndex": 622,
"ModifyIndex": 622,
"Name": "Serf Health Status",
"Node": "c222",
"Notes": "",
"Output": "Agent alive and reachable",
"ServiceID": "",
"ServiceName": "",
"Status": "passing"
},
{
"CheckID": "ping",
"CreateIndex": 600,
"ModifyIndex": 603,
"Name": "ping",
"Node": "s221",
"Notes": "",
"Output": "",
"ServiceID": "",
"ServiceName": "",
"Status": "passing"
},
{
"CheckID": "serfHealth",
"CreateIndex": 175,
"ModifyIndex": 175,
"Name": "Serf Health Status",
"Node": "s221",
"Notes": "",
"Output": "Agent alive and reachable",
"ServiceID": "",
"ServiceName": "",
"Status": "passing"
}
]
服务检查
echo '{"service": {"name": "web", "tags": ["rails"], "port": 80, "check": {"script": "curl localhost:80 >/dev/null 2>&1", "interval": "10s"}}}' >/etc/consul.d/web.json
[root@localhost ~]# nohup consul agent -data-dir /opt/consul -node=c222 -join=10.1.13.221 -bind=10.1.13.222 -config-dir /etc/consul.d &
K/V data
定义值
[root@localhost ~]# curl -X PUT -d 'test' http://127.0.0.1:8500/v1/kv/web/key1
[root@localhost ~]# curl -X PUT -d 'test' http://127.0.0.1:8500/v1/kv/web/key2?flags=42
[root@localhost ~]# curl -X PUT -d 'test' http://127.0.0.1:8500/v1/kv/web/web/sub/key3
查看
[root@localhost ~]# curl -s http://127.0.0.1:8500/v1/kv/?recurse|python -m json.tool
[
{
"CreateIndex": 734,
"Flags": 0,
"Key": "web/key1",
"LockIndex": 0,
"ModifyIndex": 745,
"Value": "dGVzdA=="
},
{
"CreateIndex": 749,
"Flags": 42,
"Key": "web/key2",
"LockIndex": 0,
"ModifyIndex": 749,
"Value": "dGVzdA=="
},
{
"CreateIndex": 751,
"Flags": 0,
"Key": "web/web/sub/key3",
"LockIndex": 0,
"ModifyIndex": 751,
"Value": "dGVzdA=="
}
]
删除key
[root@localhost ~]# curl -s http://127.0.0.1:8500/v1/kv/web/key1|python -m json.tool
修改key
curl -X PUT -d 'newval' http://127.0.0.1:8500/v1/kv/web/key1?cas=734
curl -s http://127.0.0.1:8500/v1/kv/web/key1|python -m json.tool
web UI
[root@localhost ~]# wget https://releases.hashicorp.com/consul/0.8.1/consul_0.8.1_web_ui.zip
[root@localhost ~]# unzip consul_0.8.1_web_ui.zip
[root@localhost ~]# mv static consul-ui
[root@localhost ~]# mv consul-ui /opt
[root@localhost ~]# nohup consul agent -server -bootstrap-expect 1 -data-dir /opt/consul -config-dir /etc/consul.d -node=s221 -bind=10.1.13.221 -ui-dir /opt/consul/consul-ui &
启动后访问http://ip:8500/ui