Consul:是用于服务发现和配置的工具。Consul是分布式的,高度可用的,并且具有极高的可伸缩性,它是一个一个分布式的、高可用的系统,而且开发使用都很简单、方便、它主要提供了一个功能齐全的控制平台,主要特点:服务发现、健康检查、键值存储、安全服务通信、多数据中心;
Registrator:负责收集docker host上容器的信息,并发送给consul;
Consul-tpmplate:根据编辑好的模板生成新的nginx配置文件,并负责重新加载nginx配置文件;
系统版本 | 主机名称 | IP地址 | 所需组件 |
---|---|---|---|
docker01 | 192.168.10.52 | Consul Consul-template Nginx | |
Centos7. 5 | docker02 | 192.168.10.53 | rigistrator Consul |
docker03 | 192.168.10.54 | rigistrator Consul |
上面示意图的大概流程如下:
1、docker01主机上以二进制包的方式部署consul服务并后台运行,其身份为leader;
2、docker02、docker03以容器的方式运行consul服务,并加入到docker01的consul群集中;
3、在主机docker02、docker03上后台运行registrator容器,使其自动发现docker容器提供的服务;
4、在docker01上部署Nginx,提供反向代理服务,docker02、docker03主机上基于Nginx镜像,各运行两个web容器,提供不同的网页文件,以便测试效果;
5、在docker01上安装consul-template命令,将收集到的信息(registrator收集到容器的信息)写入template模板中,并且最终写入Nginx的配置文件中。
6、至此,实现客户端通过访问Nginx反向代理服务器(docker01),获得docker02、docker03服务器上运行的Nginx容器提供的网页文件。
注:registrator是一个自动发现docker
container提供的服务,并且在后端服务注册中心(数据中心)注册服务。主要用来收集容器运行服务的信息,并且发送给consul。数据中心除了consul外,还有etcd、zookeeper等。
docker01主机采用二进制的方式进行安装!方法如下:
[root@docker01 ~]# wget https://releases.hashicorp.com/consul/1.6.2/consul_1.5.1_linux_amd64.zip
#可以执行上面的命令下载,如果有这个包直接上传
[root@docker01 ~]# rz #上传压缩包
[root@docker01 ~]# unzip consul_1.5.1_linux_amd64.zip #解包,解压后会得到一个命令
[root@docker01 ~]# mv consul /usr/local/bin/ #移动到命令存放路径
[root@docker01 ~]# chmod +x /usr/local/bin/consul #赋予其执行权限
[root@docker01 ~]# nohup consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.10.52 -client=0.0.0.0 -node=master &
[1] 3426
[root@docker01 ~]# nohup: ignoring input and appending output to ‘nohup.out’ #忽略输入并把输出追加到"nohup.out"
#执行命令后,会提示该信息,并占用终端,按回车键即可,
#运行上述命令后,会在当前目录下生成一个名为“nohup.out”的文件,其存放的是consul服务的运行日志
#执行上述命令后,consul就放到后台运行了,并返回其PID号,可以通过“jobs -l”命令进行查看
上述命令的相关参数解释如下:
-server:添加一个服务;
-bootstrap:一般在server单节点的时候使用,自选举为leader;
-ui:开启内部的web界面;
-bind:指定开启服务的IP(就是本机IP咯);
-client:指定服务的客户端(一般此处为任意);
-node:在集群内部通信使用的名称,默认是主机名。
开启的端口作用如下:
8300:集群节点;
8301:集群内部访问的端口;
8302:跨数据中心之间的通信;
8500:http_ui;
8600:DNS。
附加查询两条查询命令:
[root@docker01 ~]# consul info #可以看到这个群集的leader及版本信息
[root@docker01 ~]# consul members #查看集群内部信息
客户端可以访问docker01的8500端口进行验证,会看到以下页面:
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.1052 -advertise 192.168.1053 -client 0.0.0.0 -node=node01
#上述命令中,“-join”是指定leader的IP地址(也就是docker01);“-advertise”是指定自己本身的IP地址
[root@docker02 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ed8c232ee57 progrium/consul "/bin/start -join 19…" 4 seconds ago Up 3 seconds 53/tcp, 8300/tcp, 53/udp, 8302/tcp, 0.0.0.0:8301->8301/tcp, 0.0.0.0:8500->8500/tcp, 0.0.0.0:8301->8301/udp, 8400/tcp, 8302/udp, 0.0.0.0:8600->8600/tcp, 0.0.0.0:8600->8600/udp consul
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.10.52 -advertise 192.168.10.54 -client 0.0.0.0 -node=node02
#与docker02主机执行的命令类似,但是改成了自己的IP,及node名称改了
#注意:node名称在consul群集中,必须唯一。
[root@docker03 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3dee7d7f3b3 progrium/consul "/bin/start -join 19…" About a minute ago Up About a minute 53/tcp, 8300/tcp, 53/udp, 8302/tcp, 0.0.0.0:8301->8301/tcp, 0.0.0.0:8500->8500/tcp, 0.0.0.0:8301->8301/udp, 8400/tcp, 8302/udp, 0.0.0.0:8600->8600/tcp, 0.0.0.0:8600->8600/udp consul
注:主机docker01的consul服务也可以采用容器的方式部署,这里只是为了展示其多种部署方式而已。
至此,在docker01主机上,执行“consul members”命令,即可查看到docker02及docker03的信息,如下:
[root@docker01 ~]# consul members
Node Address Status Type Build Protocol DC Segment
master 192.168.10.52:8301 alive server 1.5.1 2 dc1
node01 192.168.10.53:8301 alive client 0.5.2 2 dc1
node02 192.168.10.54:8301 alive client 0.5.2 2 dc1
客户端访问192.168.10.52的8500端口,通过以下操作,也可看到docker02或03主机上所有与docker容器相关的端口:
四、在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.10.53:8500
#上述命令的作用是将收集的容器信息发送给本机的8500端口来显示
主机docker03配置如下
[root@docker03 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator consul://192.168.10.54:8500
#同docker02,将收集的容器信息发送给本机的8500端口来显示
[root@docker01 ~]#yum -y install gcc openssl openssl-devel zlib zlibdevel pcre pcre-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
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.10.52:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx -s reload" &
[2] 7168
[root@docker01 consul]# nohup: 忽略输入并把输出追加到"nohup.out"
[root@docker01 consul]#
//同样也是将这条命令放入后台执行,否则会占用前台的终端
//这条命令的作用就i是将本机收集到的信息,生成一个vhost.conf的文件,将命令放入后台才能保证实时发现同步并更新
配置至此,docker02或者docker03上一旦有任何Nginx相关的容器以后台“-d”的运行方式运行,都会被添加到反向代理中来,进行调度,一旦容器发生意外关闭,则可以自动从反向代理配置文件中剔除。
docker02上运行两台nginx容器,为其准备不同的网页文件的目的就是方便客户端访问时区分访问的是哪台容器。
[root@docker02 ~]# docker run -itd --name web01 -P nginx
[root@docker02 ~]# docker exec -it web01 /bin/bash
root@fa1b328515a9:/# echo "web01" > /usr/share/nginx/html/index.html
[root@docker02 ~]# docker run -itd --name web02 -P nginx
[root@docker02 ~]# docker exec -it web02 /bin/bash
root@e136933af40d:/# echo "web02" > /usr/share/nginx/html/index.html
[root@docker02 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e136933af40d nginx "/docker-entrypoint.…" 8 minutes ago Up 8 minutes 0.0.0.0:32769->80/tcp web02
fa1b328515a9 nginx "/docker-entrypoint.…" 20 minutes ago Up 20 minutes 0.0.0.0:32768->80/tcp web01
docker03上运行两台nginx容器,为其准备不同的网页文件的目的就是方便客户端访问时区分访问的是哪台容器。
[root@docker03 ~]# docker run -itd --name web03 -P nginx
[root@docker03 ~]# docker exec -it web03 /bin/bash
root@9782a3b6dae0:/# echo "web03" > /usr/share/nginx/html/index.html
[root@docker03 ~]# docker run -itd --name web04 -P nginx
[root@docker03 ~]# docker exec -it web04 /bin/bash
root@c3ed403d1933:/# echo "web04" > /usr/share/nginx/html/index.html
[root@docker03 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3ed403d1933 nginx "/docker-entrypoint.…" 8 minutes ago Up 8 minutes 0.0.0.0:32769->80/tcp web04
9782a3b6dae0 nginx "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 0.0.0.0:32768->80/tcp web03
在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.10.53:32768;
server 192.168.10.53:32769;
server 192.168.10.54:32768;
server 192.168.10.54:32769;
}
server {
listen 8000;
server_name localhost;
location / {
proxy_pass http://http_backend;
}
}
//由于consul-template是在后台运行的,所以,只要检测到容器的变化,就会动态修改上述文件
//并且重启Nginx服务,使更改生效