基于docker consul服务发现集群搭建
一、Consul简介
- Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。它具有很多优点。包括:基于raft 协议,比较简洁; 支持健康检查, 同时支持 HTTP 和 DNS 协议 支持跨数据中心的 WAN(广域网) 集群 提供图形界面 跨平台,支持 Linux、Mac、Windows。
- consul是使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。服务部署单,只有一个可运行的二进制的包。每个节点都需要运行agent,他有两种运行模式server和client。每个数据中心官方建议需要3或5个server节点以保证数据安全,同时保证server-leader的选举能够正确的进行。
二、基本概念
-
在描述架构之前,这里提供了一些术语来帮助声明正在探讨的东西:
-
Agent——agent是一直运行在Consul集群中每个成员上的守护进程。通过运行 consul agent来启动。agent可以运行在client或者server模式。指定节点作为client或者server是非常简单的,除非有其他agent实例。所有的agent都能运行DNS或者HTTP接口,并负责运行时检查和保持服务同步。
-
Client——一个Client是一个转发所有RPC到server的代理。这个client是相对无状态的。client唯一执行的后台活动是加入LAN
-
gossip池。这有一个最低的资源开销并且仅消耗少量的网络带宽。
-
Server——一个server是一个有一组扩展功能的代理,这些功能包括参与Raft选举,维护集群状态,响应RPC查询,与其他数据中心交互WA gossip和转发查询给leader或者远程数据中心。
-
DataCenter——虽然数据中心的定义是显而易见的,但是有一些细微的细节必须考虑。例如,在EC2中,多个可用区域被认为组成一个数据中心?我们定义数据中心为一个私有的,低延迟和高带宽的一个网络环境。这不包括访问公共网络,但是对于我们而言,同一个EC2中的多个可用区域可以被认为是一个数据中心的一部分。
-
Consensus——在我们的文档中,我们使用Consensus来表明就leader选举和事务的顺序达成一致。由于这些事务都被应用到有限状态机上,Consensus暗示复制状态机的一致性。
-
Gossip——Consul建立在Serf的基础之上,它提供了一个用于多播目的的完整的gossip协议。Serf提供成员关系,故障检测和事件广播。更多的信息在gossip文档中描述。这足以知道gossip使用基于UDP的随机的点到点通信。
-
LAN Gossip——它包含所有位于同一个局域网或者数据中心的所有节点。
-
WAN Gossip——它只包含Server。这些server主要分布在不同的数据中心并且通常通过因特网或者广域网通信。
-
RPC——远程过程调用。这是一个允许client请求server的请求/响应机制。
三、 consul 部署
- 服务器:192.168.75.200 Docker-ce 、 Compose 3 、 Consul、 Consul-template (部署一个Nginx作为负载均衡)
- 服务器:192.168.75.144 Docker-ce、registrator
consul 服务器
需要提前安装部署好docker环境和docker-compose
将docker-compose拖至opt目录
mv docker-compose /usr/bin
chmod +x /usr/bin/docker-compose
mkdir /root/consul
cp consul_0.9.2_linux_amd64.zip /root/consul
cd ~
cd consul/
unzip consul_0.9.2_linux_amd64.zip
mv consul /usr/bin
root@localhost consul]# consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.75.200 -client=0.0.0.0 -node=consul-server01 &>/var/log/consul.log &
[root@localhost consul]# jobs
[1]+ 运行中 consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.75.200 -client=0.0.0.0 -node=consul-server01 &
[root@localhost consul]# consul members
Node Address Status Type Build Protocol DC
consul-server01 192.168.75.200:8301 alive server 0.9.2 2 dc1
consul info | grep leader
leader=true
leader_addr=192.168.75.200:8300
//通过httpd api 获取集群信息
curl 127.0.0.1:8500/v1/status/peers //查看集群server成员
curl 127.0.0.1:8500/v1/status/leader //集群Raf leader
curl 127.0.0.1:8500/v1/catalog/services //注册的所有服务器
curl 127.0.0.1:8500/v1/catalog/nginx //查看Nginx服务信息
curl 127.0.0.1:8500/v1/catalog/nodes //集群节点详细信息
[{"ID":"2b0977e4-3e06-3988-36cf-c93e1c756c7a","Node":"consul-server01","Address":"192.168.75.200","Datacenter":"dc1","TaggedAddresses":{"lan":"192.168.75.200","wan":"192.168.75.200"},"Meta":{},"CreateIndex":5,"ModifyIndex":6}][root@localhost ~]#
// 后端服务器配置,192.168.75.144
--------------容器服务自动加入Nginx集群--------------------------
1.安装Gliderlabs/Registrator Gliderlabs/Registrator
可检查容器运行状态自动注册,还可注销docker容器的服务到服务配置中心。
目前支持Consul、Etcd 和SkyDNS2.
在192.168.75.144节点,执行以下操作:
[root@localhost ~]# docker run -d \
--name=registrator \
--net=host \
-v /var/run/docker.sock:/tmp/docker.sock \
--restart=always \
gliderlabs/registrator:latest \
-ip=192.168.75.144 \
consul://192.168.75.200:8500
2.测试服务发现功能是否正常
docker run -itd -p 83:80 --name test-01 -h test01 nginx
docker run -itd -p 84:80 --name test-02 -h test02 nginx
docker run -itd -p 85:80 --name test-03 -h test03 httpd
docker run -itd -p 88:80 --name test-04 -h test04 httpd
3.验证http和Nginx服务是否注册到consul
浏览器输入http://192.168.75.200:8500,“单击 NODES”,然后单击“consul-server01”,就会出现5个nodes节点。
//在consul服务器上查看服务
[root@localhost consul]# curl 127.0.0.1:8500/v1/catalog/services
{"consul":[],"httpd":[],"nginx":[]}[root@localhost consul]#
4.安装consul-template
consul-Template 是一个守护进程,用于实时查询Consul集群信息,
并更新文件系统上任意数量的指定模板,生产配置文件,更新完成以后。
可以选择运行shell命令执行更新操作,重新加载Nginx。Consul-Template
可以查询Consul中的服务目录,key 、 key-values 等。
这种强大的抽象功能和查询语言模板可以使Consul-Template 特别适合动态的创建配置文件
例如:创建Apache/Nginx Proxy Balancers、Haproxy Backends
5. 准备template Nginx模板文件
//在consul上操作
vim /root/consul/nginx.ctmpl
upstream http-backend { ##负载均衡反向代理
{{range service "nginx"}}
server {{.Address}}:{{.Port}};
{{end}}
}
server {
listen 83;
server_name localhost 192.168.75.200;
access_log /var/log/nginx/kgc.cn-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; ##负载均衡反向代理
}
}
6.在consul服务器上编译安装Nginx作为负载均衡
yum install gcc pcre-devel zlib-devel -y
tar zxvf nginx-1.12.0.tar.gz
cd nginx-1.12.0/
./configure --prefix=/usr/local/nginx
make && make install
vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
include vhost/*.conf; ##添加虚拟主机目录
default_type application/octet-stream;
//创建虚拟主机目录
mkdir /usr/local/nginx/conf/vhost
//创建日志文件目录
mkdir /var/log/nginx
//启动Nginx
/usr/local/nginx/sbin/nginx
8.在consul服务器配置并启动template
上传consul-template_0.19.3_linux_amd64.zip包到/root目录下
cp consul-template_0.19.3_linux_amd64.zip /root
unzip consul-template_0.19.3_linux_amd64.zip
mv consul-template /usr/bin/
//启动容器IP地址,写入到vhost的Nginx.ctmpl,nginx作为负载均衡,访问后端容器test-01、test-02、test-03、test-04
consul-template -consul-addr 192.168.75.200:8500 \
-template "/root/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/kgc.conf:/usr/local/nginx/sbin/nginx -s reload" \
--log-level=info
//另外打开一个终端查看生成配置文件
[root@localhost opt]# cat /usr/local/nginx/conf/vhost/kgc.conf
upstream http_backend {
server 192.168.75.144:83;
server 192.168.75.144:84;
}
批量停止docker
docker ps -a | awk '{print $1}' | xargs docker start
四、 验证集群
-----------------------------------------------------------------------------------------
最后验证集群
浏览器访问 192.168.75.200:83 现在后端Nginx容器节点轮询,------注意:如果不能轮询将后端容器重启容器 docker ps -a | awk '{print $1}' | xargs docker stop docker ps -a | awk '{print $1}' | xargs docker start
就验证consul服务器的Nginx负载均衡成功
docker logs -f test-01 //查看容器的日志 ,test-01 是容器名称
//查看后端容器Nginx test-01
[root@localhost ~]# docker logs -f test-01
192.168.75.200 - - [24/Sep/2020:01:50:31 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:80
192.168.75.200 - - [24/Sep/2020:01:50:31 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:80
192.168.75.200 - - [24/Sep/2020:01:50:31 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:80
192.168.75.200 - - [24/Sep/2020:01:50:32 +0000] "GET / HTTP/1.0" 304 0 "
//查看后端容器Nginx test-02
[root@localhost ~]# docker logs -f test-02
192.168.75.200 - - [24/Sep/2020:01:50:30 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:80.0) Gecko/20100101 Firefox
192.168.75.200 - - [24/Sep/2020:01:50:31 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:80.0) Gecko/20100101 Firefox
192.168.75.200 - - [24/Sep/2020:01:50:31 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:80.0) Gecko/20100101 Firefox
192.168.75.200 - - [24/Sep/2020:01:50:32 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:80.0) Gecko/20100101 Firefox
-----------------------------------------------------------------------------------------
六、 consul服务器设置将Nginx改为httpd
- 配置后端容器test-03、test-04
- consul服务器设置将Nginx改为httpd
vim /root/consul/nginx.ctmpl
upstream http_backend {
{{range service "httpd"}}
server {{.Address}}:{{.Port}};
{{end}}
}
server {
listen 83;
server_name localhost 192.168.75.200;
access_log /var/log/nginx/kgc.cn-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;
}
}
vhost 重新生成新的后端容器IP地址
consul-template -consul-addr 192.168.75.200:8500 \
-template "/root/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/kgc.conf:/usr/local/nginx/sbin/nginx -s reload" \
--log-level=info
[root@localhost ~]# cat /usr/local/nginx/conf/vhost/kgc.conf
upstream http_backend {
server 192.168.75.144:85;
server 192.168.75.144:88;
}
server {
listen 83;
server_name localhost 192.168.75.200;
access_log /var/log/nginx/kgc.cn-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;
}
}
//验证 consul服务器的Nginx能够轮询后端容器httpd test-03、test-04
浏览器192.168.75.200:30 ,然后查看后端容器test-03、test-04的日志
[root@localhost ~]# docker logs -f test-03
192.168.75.200 - - [24/Sep/2020:02:17:02 +0000] "GET / HTTP/1.0" 200 45
192.168.75.200 - - [24/Sep/2020:02:17:03 +0000] "GET / HTTP/1.0" 304 -
192.168.75.200 - - [24/Sep/2020:02:17:04 +0000] "GET / HTTP/1.0" 304 -
192.168.75.200 - - [24/Sep/2020:02:17:04 +0000] "GET / HTTP/1.0" 304 -
[root@localhost ~]# docker logs -f test-04
192.168.75.200 - - [24/Sep/2020:02:17:02 +0000] "GET / HTTP/1.0" 304 -
192.168.75.200 - - [24/Sep/2020:02:17:03 +0000] "GET / HTTP/1.0" 304 -
192.168.75.200 - - [24/Sep/2020:02:17:04 +0000] "GET / HTTP/1.0" 304 -