部署docker+consul+consul-Template+Registrator自动发现容器服务实现高可用集群负载均衡

一、consul

1、概述

Consul 是一个分布式,高可用,支持多数据中心的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla Public License 2.0 的协议进行开源。 在Consul的文档上,Consul 支持Service Discovery, Health Checking, Key/Value Store, Multi DataCenter。运用Consul,可以在系统中build复杂的应用和服务的发现等。Consul有多个组件,但总体而言,它是基础架构中的一款服务发现和配置的工具。(同类型的还有zookeeper和Etcd)

2、特点

  • 服务发现:Consul客户能够注册一个服务,比如api或mysql,其他客户可以在Consul上查询一个指定服务的提供者。Consul提供DNS和HTTP的服务发现接口。

  • 健康检查:Consul可以灵活的使用脚本等来检测注册在其上的服务是否可用,不健康的服务Consul也能够灵活处理,比如提供服务的主机内存使用超过90%,我们可以配置让Consul不要把这样的服务提供给服务调用者。

  • key/value存储:这个功能和etcd有些类似,可以通过HTTP API方便地使用。

  • 多数据中心支持:Consul支持开箱即用的多数据中心支持,这意味着用户不用建立额外的抽象层让业务扩展到各个区域。

3、优势

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

4、基本架构

提供服务给Consul的节点需要运行一个Consul agent,agent可以运行为server或client模式,服务调用或使用KV存储的节点运行agent不是必需的。agent负责服务和节点的健康检测。
agent与一个或多个Consul Server进行交互。Consul Server用于存放和复制数据。
在一个集群中,Consul Server一般为奇数个,常用为3、5、7,它们会使用consensus protocol来选出一个leader。
服务使用节点可以查询Consul agent,而不管这个agent运行在什么模式,因为运行在client模式下的agent虽然不保存数据,但是它会将请求转发到Consul Server。

二、Consul-template

  • compose-template是一个守护进程,用于实时查询consul集群信息,并更新文件系统上任意数量的指定模板,生成配置文件。更新完成以后,可以选择送行shell命令执行更新操作,重新加载Nginx
  • consul-template是基于consul自动替换配置文件的应用
  • consul-template可以查询consul中的服务目录、key、key-values等
  • 这种强大的抽象功能和查询语言模板使得consul-template特别适合动态的创建配置文件,也就是自动化增加服务

三、Registrator

Registrator,它一个是独立的服务注册器,无需依赖任何集群管理系统

  • 通过docker socket直接监听容器event,根据容器启动/停止等event来注册/注销服务
  • 每个容器的每个exposed端口对应不同的服务
  • 支持可插拔的registry backend,默认支持Consul, etcd and SkyDNS
  • 自身也是docker化的,可以容器方式启动
  • 用户可自定义配置,如服务TTL(time-to-live)、服务名称、服务tag等

四、docker+consul集群部署

1、环境准备

consul服务器:192.168.245.209
软件包:docker-compose,consul_0.9.2_linux_amd64.zip

docker容器服务器(提供web服务):192.168.245.210
安装Registrator,启动4个容器,2个nginx,2个apache

事先都要先安装好docker,此处省略安装docker的步骤

2、安装docker-compose

将docker-compose直接放入/usr/local/bin下,添加执行权限

[root@consul ~]# cd /usr/local/bin

[root@consul bin]# chmod +x docker-compose 

[root@consul bin]# docker-compose -v
docker-compose version 1.21.1, build 5a3f1a3

3、安装consul

创建一个目录存放consul软件包并解压,解压生成一个可执行文件consul,将它移动到/usr/bin可方便使用

[root@consul ~]# mkdir consul

[root@consul ~]# cd consul/
[root@consul consul]# unzip consul_0.9.2_linux_amd64.zip 
Archive:  consul_0.9.2_linux_amd64.zip
  inflating: consul 
                   
[root@consul consul]# ls
consul  consul_0.9.2_linux_amd64.zip

[root@consul consul]# mv consul /usr/bin

4、启动consul

[root@consul consul]# consul agent \  
-server \  
-bootstrap \  
-ui \  
-data-dir=/var/lib/consul-data \  
-bind=192.168.245.209 \   
-client=0.0.0.0 \    
-node=consul-server01 &> /var/log/consul.log &  
[1] 21443
参数解释:

consul agent   
agent指令是consul的核心,运行在consul集群的每个node上的daemon,agent可以run在server或者是client上,每个agent都可以提供DNS或者是HTTP的接口,负责health check和service发现等。用consul agent命令可以启动,具体可run "consul agent --help"查看参数

-server  
定义agent运行在server模式

-bootstrap  
bootstrap模式,该模式node可以指定自己作为leader,而不用进行选举

-ui   
启用内置的静态web UI服务器,就是支持web页面管理的意思

-data-dir=/var/lib/consul-data    
提供一个目录用来存放agent的状态,所有的agent允许都需要该目录,该目录必须是稳定的,系统重启后都继续存在

-bind=192.168.245.209   
该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的,默认是0.0.0.0

-client=0.0.0.0   
consul服务侦听地址,这个地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1所以不对外提供服务,如果你要对外提供服务改成0.0.0.0

-node=consul-server01    
节点在集群中的名称,在一个集群中必须是唯一的,默认是该节点的主机名

&> /var/log/consul.log &  
把所有信息都输出到日志并在后台运行,停止用ctrl+c
[root@consul consul]# jobs
[1]+  运行中               consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.245.209 -client=0.0.0.0 -node=consul-server01 &>/var/log/consul.log &

查看集群成员

[root@localhost consul]# consul members   
Node             Address               Status  Type    Build  Protocol  DC
consul-server01  192.168.245.209:8301  alive   server  0.9.2  2         dc1

5、查询服务

一旦agent启动并且服务同步了,我们可以通过HTTP的API来查询服务

[root@consul consul]# curl 127.0.0.1:8500/v1/status/peers  //查看集群server成员
["192.168.245.209:8300"]
[root@consul consul]# curl 127.0.0.1:8500/v1/status/leader  //查看集群leader
"192.168.245.209:8300"
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/services  //注册的所有服务
{"consul":[]}
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/nodes  //查看节点信息
[{"ID":"e720d654-5e27-95ec-aa2f-97cb4f25161c","Node":"consul-server01","Address":"192.168.245.209","Datacenter":"dc1","TaggedAddresses":{"lan":"192.168.245.209","wan":"192.168.245.209"},"Meta":{},"CreateIndex":5,"ModifyIndex":6}][root@consul consul]# 

6、安装Registrator

192.168.245.210(容器服务器端做以下操作)
安装启动registrator

[root@docker ~]# docker run -d \
--name=registrator \
--net=host \
-v /var/run/docker.sock:/tmp/docker.sock \
--restart=always \
gliderlabs/registrator:latest \
-ip=192.168.245.210 \
consul://192.168.245.209:8500
[root@docker ~]# docker ps -a
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS               NAMES
8875301bfc45        gliderlabs/registrator:latest   "/bin/registrator -i…"   2 minutes ago       Up 2 minutes                            registrator

启动2个nginx服务和2个apache服务,指定不同的映射端口,-h:指定容器内部的主机名

[root@localhost ~]# docker run -itd -p:83:80 --name test-01 -h test01 nginx
[root@localhost ~]# docker run -itd -p:84:80 --name test-02 -h test02 nginx
[root@localhost ~]# docker run -itd -p:88:80 --name test-03 -h test03 httpd
[root@localhost ~]# docker run -itd -p:89:80 --name test-04 -h test04 httpd
[root@docker ~]# docker ps -a
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS                NAMES
00304eb157c6        httpd                           "httpd-foreground"       5 seconds ago       Up 4 seconds        0.0.0.0:89->80/tcp   test-04
3ea5721d5671        httpd                           "httpd-foreground"       13 seconds ago      Up 12 seconds       0.0.0.0:88->80/tcp   test-03
c8ec5385df86        nginx                           "/docker-entrypoint.…"   44 seconds ago      Up 42 seconds       0.0.0.0:84->80/tcp   test-02
b9056d529275        nginx                           "/docker-entrypoint.…"   39 minutes ago      Up 39 minutes       0.0.0.0:83->80/tcp   test-01
8875301bfc45        gliderlabs/registrator:latest   "/bin/registrator -i…"   53 minutes ago      Up 53 minutes                            registrator
[root@docker ~]# 

7、验证consul集群

真机验证访问192.168.245.209:8500可以看到容器群集1个节点下的4个服务

在这里插入图片描述
在这里插入图片描述
回到consul服务端查看服务,多了apache和nginx的服务:

[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/services
{"consul":[],"httpd":[],"nginx":[]}

另外真机也可以访问到容器内部的apache和nginx服务

在这里插入图片描述
在这里插入图片描述

8、安装并启动nginx服务(作为反向代理服务器)

在consul服务器上进行如下操作:

[root@consul consul]# yum -y install gcc pcre-devel zlib-devel 

[root@consul consul]# tar zvxf nginx-1.12.0.tar.gz -C /opt

[root@consul consul]# cd /opt/nginx-1.12.0/
[root@consul nginx-1.12.0]# ./configure --prefix=/usr/local/nginx   //配置安装目录

[root@consul nginx-1.12.0]# make && make install

修改nginx配置文件

[root@consul nginx-1.12.0]# vim /usr/local/nginx/conf/nginx.conf

http {
	include       mime.types;
	include vhost/*.conf;   //包含vhost目录下的.conf配置文件,这个文件会通过Consul-template模板自动生成
	default_type  application/octet-stream;

[root@consul nginx-1.12.0]# mkdir /usr/local/nginx/conf/vhost   //创建vhost目录
[root@consul nginx-1.12.0]# mkdir /var/log/nginx         //创建日志存放目录
[root@consul nginx-1.12.0]# /usr/local/nginx/sbin/nginx    //启动nginx

9、安装consul-template

[root@consul nginx-1.12.0]# cd ~/consul/

[root@consul consul]# ls
consul_0.9.2_linux_amd64.zip  consul-template_0.19.3_linux_amd64.zip  nginx-1.12.0.tar.gz  nginx.ctmpl

[root@consul consul]# unzip consul-template_0.19.3_linux_amd64.zip 
Archive:  consul-template_0.19.3_linux_amd64.zip
  inflating: consul-template   
  
[root@consul consul]# mv consul-template /usr/local/bin  //拷贝到系统环境变量下可以直接使用

编辑consul-template模板文件

[root@consul consul]# vim nginx.ctmpl
upstream http_backend {   //声明后端服务器池
  {{range service "nginx"}}
   server {{.Address}}:{{.Port}};   //读取节点的地址和端口
   {{end}}
}
server {
  listen 83;   //指定监听consul的端口
  server_name localhost 192.168.245.209;   //监听本地代理服务器地址
  access_log /var/log/nginx/nginx-access.log; //日志目录,没有需要自己创建
  index index.html index.php;
  location / {   //配置反向代理
    proxy_set_header HOST $host;   //$host就是nginx代理服务器,也就是客户端请求的host
    proxy_set_header X-Real-IP $remote_addr;   //将$remote_addr的值放进变量X-Real-IP中,可以看见用户真实的ip,也就是客户端的真实ip
    proxy_set_header Client-IP $remote_addr; ///将$remote_addr的值放进变量Client-IP中,代表请求的客户端ip
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://http_backend;   //跳转的服务器池
   }
}

10、启动模板,进入监控状态

[root@consul consul]# consul-template -consul-addr 192.168.245.209:8500 -template "/root/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/nginxrr.conf:/usr/local/nginx/sbin/nginx -s reload" --log-level=info
2020/09/23 16:55:52.438669 [INFO] consul-template v0.19.3 (ebf2d3d)
2020/09/23 16:55:52.438687 [INFO] (runner) creating new runner (dry: false, once: false)
2020/09/23 16:55:52.439246 [INFO] (runner) creating watcher
2020/09/23 16:55:52.439498 [INFO] (runner) starting
2020/09/23 16:55:52.439518 [INFO] (runner) initiating run
2020/09/23 16:55:52.444750 [INFO] (runner) initiating run
2020/09/23 16:55:52.445957 [INFO] (runner) rendered "/root/consul/nginx.ctmpl" => "/usr/local/nginx/conf/vhost/nginxrr.conf"
2020/09/23 16:55:52.445975 [INFO] (runner) executing command "/usr/local/nginx/sbin/nginx -s reload" from "/root/consul/nginx.ctmpl" => "/usr/local/nginx/conf/vhost/nginxrr.conf"
2020/09/23 16:55:52.446011 [INFO] (child) spawning: /usr/local/nginx/sbin/nginx -s reload
参数解读:
-consul-addr:指定consul集群监听地址
-template 后面是模板参数 第一个是模板地址,冒号后的第二个参数是输出位置,第三个表示输出后重载nginx配置文件
-log-level 日志级别 通常是info warn之类

执行成功后vhost下就会产生相应的conf文件了,查看发现已经获取到了后端web服务器的地址了

[root@localhost ~]# cd /usr/local/nginx/conf/vhost/
nginxrr.conf
[root@localhost vhost]# vim nginxrr.conf 

upstream http_backend {

   server 192.168.245.210:83;

   server 192.168.245.210:84;

}
server {
  listen 83;
  server_name localhost 192.168.245.209;
  access_log /var/log/nginx/nginx-access.log;
  index index.html index.php;
  location / {
    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Client-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://http_backend;
   }
}

查看已经启动了nginx(83端口)了

[root@localhost vhost]# netstat -anpt | grep 83
tcp        0      0 192.168.245.209:8300    0.0.0.0:*               LISTEN      76973/consul        
tcp        0      0 192.168.245.209:8301    0.0.0.0:*               LISTEN      76973/consul        
tcp        0      0 192.168.245.209:8302    0.0.0.0:*               LISTEN      76973/consul        
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      83668/nginx: master 
tcp        0      0 0.0.0.0:83              0.0.0.0:*               LISTEN      83668/nginx: master 

进入容器将ngxin的默认主页内容换掉便于测试

[root@docker ~]# docker exec -it b9 bash

root@test01:/# cd /usr/share/nginx/html/
root@test01:/usr/share/nginx/html# ls
50x.html  index.html
root@test01:/usr/share/nginx/html# echo this is 83 port nginx > index.html 
root@test01:/usr/share/nginx/html# 
root@test01:/usr/share/nginx/html# exit
exit

[root@docker ~]# docker exec -it c8 bash
root@test02:/# cd /usr/share/nginx/html/
root@test02:/usr/share/nginx/html# echo this is 84 port nginx > index.html
root@test02:/usr/share/nginx/html# 
root@test02:/usr/share/nginx/html# exit
exit

11、验证访问网页

真机访问验证:http://192.168.245.209:83/

第一次显示:this is 83 port nginx
在这里插入图片描述
第二次显示:this is 84 port nginx

在这里插入图片描述
容器端查看访问容器日志:轮询显示日志

[root@localhost ~]# docker logs -f test-01
[root@localhost ~]# docker logs -f test-02

在这里插入图片描述
在这里插入图片描述

12、验证自动发现服务

在容器服务器上新启动一个nginx容器,端口是85

[root@docker ~]# docker run -itd -p:85:80 --name test-05 -h test05 nginx

重新刷新consul管理界面

在这里插入图片描述
consul-template会自动发现节点服务器写进配置文件里

在这里插入图片描述
真机访问验证:http://192.168.245.209:83/

刷新第三次页面的时候会出现新加这台nginx的主页

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值