近年微服务架构在互联网应用领域中愈来愈火,引入微服务主要解决了单体应用多个模块的紧耦合、无法扩展和运维困难等问题。微服务架构就是按照功能粒度将业务模块进行垂直拆分,对单体应用本身进行服务化和组件化,每个组件单独部署为小应用(从DB到UI)。微服务与微服务之间通过Service API进行交互,同时为了支持水平扩展、性能提升和服务可用性,单个服务允许同时部署一个或者多个服务实例。在运行时,每个实例通常是一个云虚拟机或者Docker容器。本篇文章就可以完美的解决这一问题!

关于docker这里就不多介绍了,毕竟已经火遍大街小巷了,主要了解一下Consul、Registrator、Consul-tpmplate。

consul:是一个服务网格解决方案,它是一个一个分布式的、高可用的系统,而且开发使用都很简单、方便、它主要提供了一个功能齐全的控制平台,主要特点:服务发现、健康检查、键值存储、安全服务通信、多数据中心;

Registrator:负责收集docker host上容器的信息,并发送给consul;

Consul-tpmplate:根据编辑好的模板生成新的nginx配置文件,并负责重新加载nginx配置文件;

博文大纲:
一、环境准备
二、docker01部署consul服务
三、docker02及docker03主机上以容器的方式运行consul服务
四、docker02及docker03主机上以容器的方式运行registrator服务
五、docker01部署Nginx服务,提供反向代理
六、在docker01安装consul-template命令工具,并编写模板
七、验证服务的实时发现功能

一、环境准备

Docker+Consul+Registrator实现服务自动注册与发现_第1张图片

组件之间的工作流程图:
Docker+Consul+Registrator实现服务自动注册与发现

二、docker01部署consul服务

docker01主机采用二进制的方式进行安装!方法如下:

[root@docker01 ~]# wget https://releases.hashicorp.com/consul/1.6.2/consul_1.6.2_linux_amd64.zip
[root@docker01 ~]# unzip consul_1.6.2_linux_amd64.zip 
[root@docker01 ~]# mv consul /usr/local/bin/
[root@docker01 ~]# chmod +x /usr/local/bin/consul 
//下载这个软件包获取consul这个命令
[root@docker01 ~]# nohup consul agent -server -bootstrap -ui -data-dir=/var/lib/consule-data -bind=192.168.1.1  -client=0.0.0.0 -node=master &
[1] 2618
[root@docker01 ~]# nohup: 忽略输入并把输出追加到"nohup.out"

[root@docker01 ~]# 
//执行完命令后,需按两次回车键,根据提示信息可以看出将命令输出的信息保存到了一个名为nohup.out的文件(当前目录下)中。
//执行上述命令后,consul服务就放到后台运行了,并返回其PID号,可以通过“jobs -l”命令进行查看

上述命令的相关参数解释:

* -server:添加一个服务;
* -bootstrap:加入这个选项时,一般都在server单节点的时候使用,自选举为leader(领导);
* -ui:开启内部的web页面;
* -data-dir:(key/volume)数据存放目录;
* -bind:指定开启服务的IP;       
* -client:指定可以访问的客户端(指定加入的从节点);
* -node:指定集群内通信使用的名称(如果不指定,默认以主机名命名);

consul开启的相应端口:

* 8300:集群节点;
* 8301:集群内部访问的端口;
* 8302:跨数据中心之间的通信;
* 8500:提供web ui界面;
* 8600:使用DNS协议查看节点信息;
//因为放到后台了,所以这些端口信息都看不到,如果不放到后台的话会占用前台终端,使前台终端无法正常工作!

附加两条查询命令:

[root@docker01 ~]# consul info          //查看consul的详细信息
……………………
    leader_addr = 192.168.1.1:8300        //主要就是查看consul集群主节点是谁
…………………………
[root@docker01 ~]# consul members           //查看consul群集中的成员信息

三、docker02及docker03主机上以容器的方式运行consul服务

docker02的配置如下:

[root@docker02 ~]# docker run -d --name consul -p 8301:8301 -p 8301:8301/udp -p 8500:8500 -p 8600:8600 -p 8600:8600/udp --restart always progrium/consul -join 192.168.1.1 -advertise 192.168.1.2 -client 0.0.0.0 -node=node01
//-join:指定加入的群集主节点
//-advertise:声明本机的Ip地址
//-node:群集中的名称

docker03的配置如下:

[root@docker03 ~]# docker run -d --name consul -p 8301:8301 -p 8301:8301/udp -p 8500:8500 -p 8600:8600 -p 8600:8600/udp --restart always progrium/consul -join 192.168.1.1 -advertise 192.168.1.3 -client 0.0.0.0 -node=node02

注意:虽然docker01上的consul服务是二进制包安装的,docker02和docker03采用容器的方式部署,只是为了尽可能的展示部署方式而已!

在docker01进行查看:

[root@docker01 ~]# consul members          //查看consul群集信息
Node    Address           Status  Type    Build  Protocol  DC   Segment
master  192.168.1.1:8301  alive   server  1.6.2  2         dc1  
node01  192.168.1.2:8301  alive   client  0.5.2  2         dc1  
node02  192.168.1.3:8301  alive   client  0.5.2  2         dc1  

浏览器访问测试:
Docker+Consul+Registrator实现服务自动注册与发现_第2张图片

四、docker02及docker03主机上以容器的方式运行registrator服务

docker02的配置如下:

[root@docker02 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart always gliderlabs/registrator consul://192.168.1.2:8500
//将收集的容器信息发送给本机的8500端口来显示

浏览器测试访问:
Docker+Consul+Registrator实现服务自动注册与发现_第3张图片
Docker+Consul+Registrator实现服务自动注册与发现_第4张图片
docker03的配置如下:

[root@docker03 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart always gliderlabs/registrator consul://192.168.1.3:8500
//将收集的容器信息发送给本机的8500端口来显示

浏览器测试访问:
Docker+Consul+Registrator实现服务自动注册与发现_第5张图片
Docker+Consul+Registrator实现服务自动注册与发现_第6张图片

五、docker01部署Nginx服务,提供反向代理

[root@docker01 ~]# yum -y install pcre pcre-devel openssl openssl-devel zlib zlib-devel
[root@docker01 ~]# wget http://nginx.org/download/nginx-1.17.7.tar.gz
[root@docker01 ~]# useradd -M -s /sbin/nologin nginx
[root@docker01 ~]# tar zxf nginx-1.17.7.tar.gz -C /usr/src
[root@docker01 ~]# cd /usr/src/nginx-1.17.7/
[root@docker01 nginx-1.17.7]# ./configure --user=nginx --group=nginx --with-http_stub_status_module --with-http_realip_module --with-pcre --with-http_ssl_module && make && make install
[root@docker01 nginx-1.17.7]# cd
[root@docker01 ~]# ln -s /usr/local/nginx/sbin/nginx  /usr/local/sbin/
[root@docker01 ~]# nginx

六、在docker01安装consul-template命令工具,并编写模板

consul-template的作用就是将收集到的信息(把registrator收集到容器的信息)写入template模板中,并且最终写入Nginx的配置文件中。

[root@docker01 ~]# wget https://releases.hashicorp.com/consul-template/0.23.0/consul-template_0.23.0_linux_amd64.zip
[root@docker01 ~]# unzip consul-template_0.23.0_linux_amd64.zip 
[root@docker01 ~]# mv consul-template /usr/local/bin
[root@docker01 ~]# chmod +x /usr/local/bin/consul-template 
//获取consul-template 命令
[root@docker01 ~]# cd /usr/local/nginx/
[root@docker01 nginx]# mkdir consul && cd consul
[root@docker01 consul]# vim nginx.ctmpl
upstream http_backend {
        {{range service "nginx"}}
        server {{ .Address }}:{{ .Port }};
        {{ end }}
}
server {
        listen 8000;
        server_name localhost;
        location / {
                proxy_pass http://http_backend;
        }
}
[root@docker01 consul]# vim ../conf/nginx.conf
        include /usr/local/nginx/consul/*.conf;   //调用生成的vhost.conf文件
}         //必须在末尾的大括号中添加
[root@docker01 consul]# nohup consul-template -consul-addr 192.168.1.1:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx -s reload" &
[2] 64430
[root@docker01 consul]# nohup: 忽略输入并把输出追加到"nohup.out"

[root@docker01 consul]# 
//同样也是将这条命令放入后台执行,否则会占用前台的终端
//这条命令的作用就i是将本机收集到的信息,生成一个vhost.conf的文件,将命令放入后台才能保证实时发现同步并更新

七、验证服务的实时发现功能

配置至此,docker02或者docker03上一旦有任何Nginx相关的容器以后台“-d”的运行方式运行,都会被添加到反向代理中来,进行调度,一旦容器发生意外关闭,则可以自动从反向代理配置文件中剔除。

现在可以在docker02、和docker03上分别运行两台Nginx容器,其容器名称依次为web01、web02.......,其网页文件依次为:web01、web02……为其准备不同的网页文件的目的就是方便客户端访问时区分访问的是哪台容器。

由于其配置过程类似,我这里就写出一个运行Nginx容器的过程,其他照做即可!

[root@docker02 ~]# docker run -itd --name web01 -P nginx
[root@docker02 ~]#  docker exec -it web01 /bin/bash
root@b49445d94603:/# echo "web01" > /usr/share/nginx/html/index.html

在docker02及docker03运行四个Nginx容器后(必须以后台运行的方式,也就是说在运行时必须有“-d”选项),那么,此时访问docker01的8000端口,就会循环访问到这四个容器提供的网页文件,如下:

[root@docker01 consul]# curl 127.0.0.1:8000
web01
[root@docker01 consul]# curl 127.0.0.1:8000
web02
[root@docker01 consul]# curl 127.0.0.1:8000
web03
[root@docker01 consul]# curl 127.0.0.1:8000
web04
[root@docker01 consul]# cat /usr/local/nginx/consul/vhost.conf 
upstream http_backend {

        server 192.168.1.2:32768;

        server 192.168.1.2:32769;

        server 192.168.1.3:32768;

        server 192.168.1.3:32769;

}
server {
        listen 8000;
        server_name localhost;
        location / {
                proxy_pass http://http_backend;
        }
}
//由于consul-template是在后台运行的,所以,只要检测到容器的变化,就会动态修改上述文件
//并且重启Nginx服务,使更改生效

现在就已经配置完成了,docker02和docker03上创建和删除容器,vhost.conf文件都会动态的进行修改,自行测试!

——————————本文到此结束,感谢阅读——————————