文章目录
一、定义
consul在docker中,一个能够自动发现并且更新监控信息的一个功能。
consul也可以说是一个注册中心,可以将监控的应用服务的基本信息,都注册到consul这里,然后consul将这些节点的信息进行制作一个可以被前端所能识别的更新的模板,然后将这个模板同步到主页的更新列表中,一旦后面的应用服务节点增加信息的服务,则会及时的将信息更新到consul中,consul再去通知主页进行更新。
1、consul的优势
-
consul是使用Raft算法来保证一致性,比发咋的Paxos算法更加的直接,相比较而言,zookeeper采用的是Paxos,而Etcd采用的是Raft。
-
支持多数据中心,内外网的服务采用不同的端口进行监听。多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟,分片等情况。zookeeper和Etcd均不支持多数据中心功能的支持
-
可以支持健康检查,Etcd不支持该功能
-
支持HTTP、DNS、和GPRS协议接口。zookeeper的集成较为复杂,Etcd支持吃HTTP协议
-
官方提供WEB的管理界面,而Etcd无此功能
-
综合比较,Consul作为服务注册和配置管理的新星,比较值得关注和研究
Etcd:只一个分布式的数据库,比MySQL等这些数据库相比,有一个有点:能够发现数据的更新的信息
K8s的核心数据库就是Etcd,因为Etcd能够自动发现。因为容器的特性是短周期。意味着容器挂掉之后,重启,IP地址就会发生变化,常规数据库不能自动更新这些地址,所以容器IP地址发生改变之后并不能自动获取信息,并将信息更新到新的容器上。
2、Consul的特性
Consul的特性是,分布式的、高可用的、横向扩展的,其特性为下面四种:
服务发现:可方便的实现服务注册,通过DNS或者HTTP应用程序可以很容易的找到他所依赖的服务
key/value(键值对)存储:使用key/value的形式进行数据存储
多数据中心:Consul支持开箱即用的多数据中心。这意味着用户不需要担心建立额外的抽象层,让业务扩展到多个区域。
健康检查:可以对指定服务进行健康检查。例如:Response Status是否为200,避免将流量转发到不健康的服务上
3、构建核心
template 模板:负责更新配置模块
registrator (自动发现+注册到consul-server端)后端每构建出一个容器,会向registrator进行注册,控制consul完成更新操作,consul会触发consul template模板进行热更新( reload)
核心机制: consul ,自动发现、自动更新,为容器提供服务(添加、删除、生命周期)
下面我画了一个简易的consul监控的步骤,举例就用nginx了。
其表示的是,nginx代理的有一些容器。假如这个nginx代理的一个容器因为一些原因二挂掉,需要重新添加新的容器。
正常情况下,不手动更新的话,nginx是不能自动识别到新添加的容器的,需要添加新的容器之后,再手动更新到nginx.conf中
consul则是可以取代这个步骤,consul能够借助registration来进行监控识别registration所监控的模块,当这个模块中有添加或者减少等变更容器的操作信息产生的时候,registration会直接注册,并且汇报给consul agent。
consul agent会将其传输给consul server。由consul保存到consul template。consul template是负责更新配置文件,将配置文件更新之后,将更新好的配置文件传输给监控中的nginx中的nginx.conf中。
nginx通过include加载和识别,consul控制nginx重载即可。
上面这是大致的保存过程。
二、部署
服务器Consul:
IP:192.168.75.51
插件:Docker-ce、Consul、Consul-template
服务器docker:
IP:192.168.75.53
插件:Docker-ce、registration
1、consul服务器配置
tree
.
└── consul_0.9.2_linux_amd64.zip
找到安装包,并且将其解压,直接放在当前目录,或者指定目录都可以,我为了方便后面的时候使用consul,直接解压在缓存文件目录中了
unzip consul_0.9.2_linux_amd64.zip -d /usr/bin/
解压完成之后,开启consul进行监控节点
[root@localhost bin]# consul agent \ #使用的是agent模式
> -server \ #使用的是server模式
> -bootstrap \ #前端框架
> -ui \ #可被访问的界面
> -data-dir=/uar/lib/consul-data \ #数据目录
> -bind=192.168.75.51 \ #consul服务器地址
> -client=0.0.0.0 \ #监听地址,监听所有含有registration服务的服务器地址
> -node=consul-server01 &> /var/log/consul.log & #节点名称写入日志,并且后台运行
[1] 2423
jobs
[1]+ 运行中 consul agent -server -bootstrap -ui -data-dir=/uar/lib/consul-data -bind=192.168.75.51 -client=0.0.0.0 -node=consul-server01 &>/var/log/consul.log &
consul members #查看集群信息
Node Address Status Type Build Protocol DC
consul-server01 192.168.75.51:8301 alive server 0.9.2 2 dc1
再查看consul的leader信息,找到端口号之后再确认被监听端口端口信息,以及被监听端口开启状态
consul info | grep leader
leader = true
leader_addr = 192.168.75.51:8300
netstat -natp | grep 8300
tcp 0 0 192.168.75.51:8300 0.0.0.0:* LISTEN 2423/consul
tcp 0 0 192.168.75.51:8300 192.168.75.51:41005 ESTABLISHED 2423/consul
tcp 0 0 192.168.75.51:41005 192.168.75.51:8300 ESTABLISHED 2423/consul
#可以看到,正在使用这个端口信息的就是consul,
确认之后,可以到浏览器上进到consul的界面进行管理
http://consul的IP地址:8500
#8500默认是登录consul的端口号
#lsof -i:8500
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
consul 2423 root 18u IPv6 31107 0t0 TCP *:fmtp (LISTEN)
刚刚创建,并且没有加入一个监测点,暂时还没有什么记录产生
直接在服务节点上也可以直接以命令的方式,查看一部分节点信息:
curl 127.0.0.1:8500/v1/status/peers #查看集群server成员
["192.168.75.51:8300"]
curl 127.0.0.1:8500/v1/status/leader #集群Raf leader
"192.168.75.51:8300"
curl 127.0.0.1:8500/v1/catalog/services #注册的所有服务
{"consul":[]} #当前还没有注册过服务
curl 127.0.0.1:8500/v1/catalog/服务名字,例如nginx #可以查看被监控服务的服务信息,因为还没有被监控节点,所以为空
curl 127.0.0.1:8500/v1/catalog/nodes #查看弄得节点详细信息
[{"ID":"f41cbead-9a4a-451f-416c-a2d043b3e48d","Node":"consul-server01","Address":"192.168.75.51","Datacenter":"dc1","TaggedAddresses":{"lan":"192.168.75.51","wan":"192.168.75.51"},"Meta":{},"CreateIndex":5,"ModifyIndex":6}]
上面consul正常安装完成了,下面开启服务发现等功能
2、容器服务自动注册到consul集群
1、在docker服务器上安装Gliderlabs/Registration Gliderlabs/Registrator
可以检查容器运行状态自动注册,还可以注册docker容器的服务到服务配置中心(8300收集到8500展示)
docker run -d \
> --name registrator \ #容器名字
> --net host \ #网络使用host
> -v /var/run/docker.sock:/tmp/docker.sock \ #挂载
> --restart always \ #重启策略,总是重启,不管是故障还是人为,只要非开启状态就重启
> gliderlabs/registrator:latest \ #使用的镜像名字以及标签
> -ip 192.168.75.100 \ #容器ID地址
> consul://192.168.75.51:8500 #配置中心的位置
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7347196d08ec gliderlabs/registrator:latest "/bin/registrator -i…" 9 seconds ago Up 8 seconds registrator
测试是否能自动发现添加的容器
docker run -itd -p:81:80 --name test1 -h test01 nginx
docker run -itd -p:82:80 --name test2 -h test02 nginx
docker run -itd -p 83:80 --name test3 -h test03 httpd
docker run -itd -p 84:80 --name test4 -h test04 httpd
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03ee344d6e8a httpd "httpd-foreground" 6 seconds ago Up 4 seconds 0.0.0.0:84->80/tcp, :::84->80/tcp test4
17989e06cb49 httpd "httpd-foreground" 20 seconds ago Up 18 seconds 0.0.0.0:83->80/tcp, :::83->80/tcp test3
d6bf0005992b nginx "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 0.0.0.0:82->80/tcp, :::82->80/tcp test2
0e56568bed57 nginx "/docker-entrypoint.…" 5 minutes ago Up 4 minutes 0.0.0.0:81->80/tcp, :::81->80/tcp test1
添加完成之后,继续到consul的主界面查看
3、consul-server节点配置nginx
yum -y install pcre-devel zlib-devel gcc gcc-c++ make
tar zxvf nginx-1.12.0.tar.gz
cd nginx-1.12.0/
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module
make && make install
安装完成之后,找到配置文件,找到http模块
cd /usr/local/nginx/conf/ && vim nginx.conf
17 http {
18 include mime.types;
19 default_type application/octet-stream;
#找到之后,在include下面再插入一行,使其加载虚拟主机里的所有conf文件
17 http {
18 include mime.types;
19 include vhost/*.conf; #加载虚拟机里面所有以conf结尾的文件
20 default_type application/octet-stream;
#再创建一个vhost目录,供其识别
[root@localhost conf]# mkdir vhost
#查看
pwd && ls | grep vhost
/usr/local/nginx/conf
vhost
启动nginx
[root@localhost conf]# ../sbin/nginx #或者先存放在缓存命令目录中,再执行也可以
#挂载:ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/
[root@localhost conf]# ss -natp | grep nginx
LISTEN 0 128 *:80 *:* users:(("nginx",pid=6728,fd=6),("nginx",pid=6727,fd=6))
4、配置模板信息
vim /opt/consul/nginx.ctmpl #写入下面信息
upstream http_backend { #协议的后端
{{range service "nginx"}} 服务的范围只收集nginx信息
server {{.Address}}:{{.Port}}; #此处引用的变量会指向后端的地址和端口(动态变化)
{{end}}
}
#收集信息,并将收集到的信息展现为IP和端口信息
server {
listen 84;
server_name localhost 192.168.75.51; #反向代理的服务器地址,前端服务器地址
access_log /var/log/nginx/lhk.com-access.log;
index index.html index.php;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr; #后端真实IP
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #转发地址
proxy_pass http://http_backend;
}
}
5、启动consul-template
consul-template是一个守护进程,用于实时查询consul集群信息,并且更新文件系统上任意数量的指定模板,生成配置文件。更新完成后,可以选择运行shell命令进行执行更新操作,冲新加载nginx。consul-template可以查询consul中的服务目录、key、key-values等。
这种强大的抽象功能和查询语言模板可以使consul-template特别适合动态的创建配置文件
因为其解压后也直接是一个执行程序,所以直接解压在缓存命令文件中
unzip consul-template_0.19.3_linux_amd64.zip -d /usr/bin/
consul-template \
> -consul-addr 192.168.75.51:8500 \
> -template "/opt/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/lhk.conf:/usr/local/nginx/sbin/nginx -s reload" \
> --log-level=info
完成之后,可以到配置文件中看所有nginx相关的IP和端口信息
cat /usr/local/nginx/conf/vhost/lhk.conf
upstream http_backend {
server 192.168.75.100:81;
server 192.168.75.100:82;
}
server {
listen 84;
server_name localhost 192.168.75.51;
access_log /var/log/nginx/lhk.com-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的容器,现在已经被自动更新到这个配文件中了,显示格式就是之前设置好的IP地址加上端口
6、测试
在docker服务器上再继续创建一个nginx容器,创建步骤就省略了跟上面一样。只需要再创建一个nginx容器就行。
直接查看结果
先到管理页面处查看:
可以看到现在已经显示的多了一个
再到consul服务节点去查看:
cat /usr/local/nginx/conf/vhost/lhk.conf
upstream http_backend {
server 192.168.75.100:81;
server 192.168.75.100:82;
server 192.168.75.100:85;
}
consul服务节点这边的这个配置文件中,也实时被同步到了nginx容器的现在的状况
添加尝试了,再试试删除容器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GPDrqvkr-1644662454755)(D:\图片\image-20220212183602434.png)]
模拟test2坏掉了
docker rm -f test2
到控制页面再看,现在82端口已经消失了
[root@localhost consul]# cat /usr/local/nginx/conf/vhost/lhk.conf
upstream http_backend {
server 192.168.75.100:81;
server 192.168.75.100:85;
}
#被更新的配置文件也是一样的消失了82端口这个容器