前言

服务发现在SOA(Service-Oriented Architecture)架构中是一个很重要的概念,是支撑大规模 SOA 的核心服务,在应用Docker容器集群的实践中也是非常重要的功能。对于Docker容器之间跨主机访问这个难题,服务发现是目前较为实用的解决方案。

服务发现的功能是管理集群中的进程或服务之间的通信,涉及到服务列表,在服务列表中注册服务,并且能够在服务列表中查找并连接服务。服务发现的基本思想是任何一个应用的实例能够以编程的方式获取当前环境的细节,这是为了让新的实例可以嵌入到现有的应用环境而不需要人工干预。

复杂系统的服务发现组件要提供更多的功能,例如,服务元数据存储、健康监控、多种查询和实时更新等。总的来说,服务发现提供了一种协调机制,方便服务的发布和查找。

常见的服务发现工具:

etcd: 这是CoreOS的创建者提供的工具,面向容器和宿主机提供服务发现和全局配置存储功能。它在每个宿主机上有基于http协议的API和命令行的客户端。

Zookeeper: 最早做服务发现的开源项目之一,起源于Hadoop,帮助在Hadoop集群中维护各种组件。它非常成熟、可靠,被许多大公司(YouTube、eBay、雅虎等)使用。其数据存储的格式类似于文件系统,如果运行在一个服务器集群中,Zookeeper实现了跨所有节点共享配置状态。

consul: 这个服务发现平台有很多高级的特性,使得它脱颖而出,例如:配置健康检查、ACL功能HAProxy配置等等。
Consul是强一致性的数据存储,与Zookeeper和etcd不一样,Consul内嵌实现了服务发现系统,所以这样就不需要构建自己的系统或使用第三方系统,另外,Consul还包括节点健康检查和运行在其上的服务。

总结,服务发现工具使得Docker容器可以适应它们当前所处环境并嵌入现有的组件。这是实现提供方便、容易扩展和部署的功能的一个重要的先决条件,该功能通过允许组件跟踪和应对他们所在环境变化来实现。


一、环境

实验环境关闭防火墙、禁用SElinux

主机名IP组件
docker01172.16.0.157consul、 consul-template、nginx
docker02172.16.0.158consul、 registrator
docker03172.16.0.145consul、 registrator

三大组件作用:
consul 作用是收集容器信息发送给本机的8500端口显示
registrator 自动发现docker container提供的服务,并在后端服务注册中心注册服务或取消服务的工具,后端注册中心支持conusl、etcd、skydns2、zookeeper等。
consul-template 将收集到的信息(把registrator收集的容器信息)写入template模板中,并写入Nginx的配置文件。

二、部署步骤

1.Docker01操作

部署consul服务
1)解压、启动
上传压缩包
[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=172.16.0.157 -client=0.0.0.0 -node=master &

参数解释:
-server:添加服务;
-bootstrap:一般在server单节点的时候使用,自选举为leader;
-ui:开启内部的web界面;
-bind:指定开启服务的IP(就是本机IP);
-client:指定服务的客户端(一般此处为任意);
-node:在集群内部通信使用的名称,默认是主机名。

2)验证:
查看群集leader及版本信息:consul info
在这里插入图片描述

查看consul集群内成员的信息:consul members
在这里插入图片描述
也可访问docker01的8500端口进行验证:
在这里插入图片描述
部署Nginx反向代理服务

1)安装前提软件(提前本地下载好)
yum localinstall *.rpm

2)创建程序用户
useradd -M -s /sbin/nologin nginx

3)编译安装

解压
tar xf ~/nginx-1.14.0.tar.gz -C /usr/src/

进入解压目录,使用命令安装
cd /usr/src/nginx-1.14.0/
./configure --user=nginx --group=nginx --with-http_stub_status_module --with-http_realip_module --with-pcre --with-http_ssl_module && make && make install

创建链接
ln -s /usr/local/nginx/sbin/* /usr/local/sbin/

单步测试:确保源码安装成功
curl localhost

部署consul-template

上传安装包
[root@docker01 ~]# unzip consul-template_0.19.5_linux_amd64.zip //解包
[root@docker01 ~]# mv consul-template /usr/local/bin/ //移动到命令搜索路径
[root@docker01 ~]# chmod +x /usr/local/bin/consul-template //赋予执行权限

进入Nginx安装目录
cd /usr/local/nginx/
编写模板供consul-template工具使用,并配置Nginx反向代理
[root@docker01 nginx]# mkdir consul
[root@docker01 nginx]# cd consul/
[root@docker01 consul]# vim nginx.ctmpl

代码如下:

upstream http_backend {
        {{range service "nginx"}}   //这里的“Nginx”是基于docker镜像进行搜索的,不是容器名称
        server {{ .Address }}:{{ .Port }};
        {{ end }}
}
server {
        listen 8000;                         //监听端口任意指定,不要冲突
        server_name localhost;
        location / {
                proxy_pass http://http_backend;
        }
}

在主配置文件配置调用生成的vhost.conf文件
[root@docker01 consul]# vim …/conf/nginx.conf

在配置文件末尾的花括号上方写入“include”配置
include /usr/local/nginx/consul/*.conf;
}

重载nginx服务
nginx -s reload

执行命令:将本机收集的信息,生成一个vhost.conf的文件,将命令放入后台才能保证实时发现同步并更新
nohup consul-template -consul-addr 172.16.0.157:8500 -template “/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx -s reload” &

2.docker02、docker03加入consul集群

docker02操作
1)以镜像方式启动consul:
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 172.16.0.157 -advertise 172.16.0.158 -client 0.0.0.0 -node=node01

2)部署registrator服务
docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart always gliderlabs/registrator consul://172.16.0.158:8500

docker03操作
1)以镜像方式启动consul
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 172.16.0.157 -advertise 172.16.0.145 -client 0.0.0.0 -node=node02

2)部署registrator服务

docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart always gliderlabs/registrator consul://172.16.0.145:8500

参数释义:
“join”是指定leader的IP地址(也就是docker01);“advertise”是指定自己本身的IP地址
注意:node名称在consul群集中,必须唯一

做完此操作后,在docker01查看到consul集群内成员的信息,同上


三、验证

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

docker02:运行容器
docker run -d -P --name web01 nginx
进入容器,创建测试页
docker exec -it web01 bash
echo “this is a web01 test.” > /usr/share/nginx/html/index.html

docker03:运行容器
docker run -d -P --name web03 nginx
进入容器,创建测试页
docker exec -it web03 bash
echo “this is a web03 test.” > /usr/share/nginx/html/index.html

访问网页:

在这里插入图片描述
查看docker01的Nginx配置文件:启动的容器ip及端口自动被添加
在这里插入图片描述
常见报错:
访问被拒绝,查看此配置文件发现未自动添加配置文件;报错提示一样,但造成错误原因不一!

解决:
1)少步骤;
忘记执行一条命令,将本机收集的信息,生成一个vhost.conf的文件,将命令放入后台才能保证实时发现同步并更新
nohup consul-template -consul-addr 172.16.0.157:8500 -template “/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx -s reload” &

2)少参数
docker run -d -P --name web02 nginx
忘记加-P;此参数是随机生成一个端口,供容器Nginx服务使用

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐