1,Docker运行consul环境
1、Consul基础介绍
Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,比如 Airbnb 的 SmartStack 等相比,Consul 的方案更“一站式”,一致性协议采用 Raft 算法,用来保证服务的高可用. 使用 GOSSIP 协议管理成员和广播消息, 并且支持 ACL 访问控制,内置了服务注册与发现框架、分布一致性协议实现、健康检查,并允许 HTTP 和 DNS 协议调用 API 存储键值对、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等)。使用起来也较为简单。
Consul 用 Golang 实现,因此具有天然可移植性(支持 Linux、windows 和 Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。
要想利用Consul提供的服务实现服务的注册与发现,我们需要建立Consul Cluster。在Consul方案中,每个提供服务的节点上都要部署和运行Consul的agent,所有运行Consul Agent节点的集合构成Consul Cluster。Consul Agent有两种运行模式:Server和Client。这里的Server和Client只是Consul集群层面的区分,与搭建在Cluster之上的应用服务无关。以Server模式运行的Consul Agent节点用于维护Consul集群的状态,官方建议每个Consul Cluster至少有3个或以上的运行在Server Mode的Agent,Client节点不限。
Consul支持多数据中心,每个数据中心的Consul Cluster都会在运行于Server模式下的Agent节点中选出一个Leader节点,这个选举过程通过Consul实现的raft协议保证,多个Server节点上的Consul数据信息是强一致的。处于Client Mode的Consul Agent节点比较简单,无状态,仅仅负责将请求转发给Server Agent节点。
** Consul 功能:**
服务发现(Service Discovery):客户端通过 Consul 提供服务,其他客户端可以通过 Consul 利用 dns 或者 http 发现依赖服务
健康检查(Health Checking): Consul 提供任务的健康检查,可以用来操作或者监控集群的健康,也可以在服务发现时去除失效的服务
键值对存储(Key/Value Store): 存储层级键值对
多数据中心(Multi Datacenter): Consul 支持开箱即用的多数据中心
** Consul的优势**
使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft.
支持多数据中心,内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等. zookeeper 和 etcd 均不提供多数据中心功能的支持.
支持健康检查. etcd 不提供此功能.
支持 http 和 dns 协议接口. zookeeper 的集成较为复杂, etcd 只支持 http 协议,官方提供web管理界面, etcd 无此功能.
** Consul 的使用场景**
docker 实例的注册与配置共享
coreos 实例的注册与配置共享
vitess 集群
SaaS 应用的配置共享
与 confd 服务集成,动态生成 nginx 和 haproxy 配置文件
** Consul 的模式**
client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群。一个 Client 是一个转发所有 RPC 到 Server 的代理。这个 Client 是相对无状态的;Client 唯一执行的后台活动是加入 LAN gossip 池,这有一个最低的资源开销并且仅消耗少量的网络带宽。
server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯. 每个数据中心的 server 数量推荐为 3 个或是 5 个。参与 Raft 选举,维护集群状态,响应 RPC 查询,与其他数据中心交互 WAN gossip 和转发查询给 leader 或者远程数据中心。
群集架构图如下:
Consul和其他类似软件的对比:
2、Consul群集搭建
Consul 集群搭建时一般提供两种模式:
** 手动模式**: 启动第一个节点后,此时此节点处于 bootstrap 模式,其节点手动执行加入,使用: -join命令
** 自动模式**: 启动第一个节点后,在其他节点配置好尝试加入的目标节点,然后等待其自动加入(不需要人为命令加入),配置:retry_join
以自动模式为例:
目录结构:
1 | document |
server1.json配置文件:
1 | { |
server2.json配置文件:
1 | { |
server3.json配置文件:
1 | { |
client1.json配置文件:
1 | { |
运行docker容器:
1 | docker run --name=server1 -it -d -v $PWD/consul:/consul consul agent -config-file=/consul/server1.json |
查看容器运行日志(选择其中一个即可),可以看出选举server1作为Leader:
1 | docker logs server1 |
结果:
1 | 2018/06/14 08:12:06 [INFO] consul: New leader elected: server1 |
可以查看容器的ip:
1 | docker inspect -f '{{.NetworkSettings.IPAddress}}' server1 |
查看下集群的状态
注:server1为Leader;
1 | docker exec -t server1 consul members |
结果:
1 | [root@localhost document]# docker exec -t server1 consul members |
访问:http://172.17.0.5:8500,打开 Consul UI 界面,就可以看到我们配置的 Consul Client:
可以使用以下命令查询其它信息:
1 | curl -L http://172.17.0.5:8500/v1/catalog/datacenters |
3、节点异常处理
LEADER 挂了
leader挂了,consul会重新选取出新的leader,只要超过一半的SERVER还活着,集群是可以正常工作的。
1 | docker stop server1 |
运行以下命令查看现在的Leader:
1 | curl http://172.17.0.5:8500/v1/status/leader |
结果:
1 | [root@localhost document]# curl http://172.17.0.5:8500/v1/status/leader |
注:172.17.0.3为server2 IP。
2,Docker 运行 Fabio 环境
Fabio简介
Fabio 是 ebay 团队用 golang 开发的一个快速、现代、zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的微服务。
因为 consul 支持服务注册与健康检查所以 fabio 能够零配置提供负载。
根据项目的介绍fabio 能提供每秒15000次请求。
服务发现的特点
服务与服务之间的调用需要在配置文件中填写好主机和端口,不易于维护且分布式环境中不易于部署与扩容。
那么此时就需要考虑服务启动的时候自己把主机和端口以及一些其他信息注册到注册中心,这样其他服务可以从中找到它。
甚至更为简单的注册完毕后通过 DNS 的方式来『寻址』。比如 Zookeepr 可以很好的完成这个工作,但是其中还有一个弊端就是服务的健康检查服务注册到注册中心之后如何保证这个服务一定可用?此时就需要自己来写逻辑当服务不可用的时候自动从注册中心下线掉。 然后Consul 可以很轻易的解决这个问题。
工作原理
Consul 提供了一套健康检测机制简单的说针对 http 类型的服务(consul 也支持 其他类型例如tcp)在注册的时候可以顺便注册下健康检测的信息,提供一个健康检测的地址(url)以及一个频率超时时间这样的话 consul 会定期的来请求当状态码是200的时候设置次服务是健康的状态否则是故障状态。
既然注册到consul的服务能够自己维护健康状态此时 fabio 的工作就很简单了! 就是直接从consul 注册表里面取出健康的服务根据服务注册时候的 tags 配置自动创建自己的路由表,然后当一个 http 请求过来的时候自动去做负载均衡
简单流程图:
1 | ====== 服务注册 ========= ========= |
Docker 运行 Fabio
Fabio Docker 镜像地址:https://hub.docker.com/r/magiconair/fabio/
目录结构
1 | fabio |
首先,在/fabio/目录下创建一个fabio.properties文件(示例配置),然后vim fabio.properties增加下面配置:
1 | registry.consul.register.addr = 172.17.0.6:9998 |
在fabio文件夹下运行命令:
1 | docker run -d -p 9999:9999 -p 9998:9998 --name=fabio -v $PWD/fabio.properties:/etc/fabio/fabio.properties magiconair/fabio |
注:默认是bridge网络模式,也就是我们常用的桥接模式,Docker 会分配给容器一个独立的 IP 地址(端口也是独立的),并且容器和主机之间可以相互访问。或者添加参数:–net=host:host网络模式,容器的网络接口和主机一样,也就是共享一个 IP 地址。
3,Docker 运行 ASP.NET Core 2.0 服务
3.1 准备asp.net Core应用程序
3.2 添加HealthController用于Consul健康检查
1 | [ ] |
3.3 调用Consul API注册服务
组件地址:https://github.com/PlayFab/consuldotnet
(1) 首先安装 Consul包:
1 | install-package Conusl |
(2) 添加扩展方法,用于调用Consul API
1 | public static class AppBuilderExtensions |
(3)Starup类的Configure方法中,调用此扩展方法
1 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. |
ServiceEntity类定义:
1 | public class ServiceEntity |
appSettings.json配置文件:
1 | { |
3.4 运行ASP.NET Core程序
在Linux服务器下,建立程序文件夹,使用git clone命令下载代码,如:
1 | mkdir web |
使用docker-compose 运行程序:
1 | cd ConsulTest ## 进入目录 |
结果:
1 | Successfully built dfaf37c4246f |
查看docker 容器:
1 | docker ps -a |
结果:
其它命令:
查看容器IP:
1 | docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' consultest_consultest_1 |
3.5 验证
参考:
https://github.com/PlayFab/consuldotnet
https://www.consul.io/docs/agent/options.html