Docker + Consul + registrator 实现服务发现
环境:
关闭防火墙、禁用SElinux,且主机名不能冲突
docker01 | 192.168.1.128 |
---|---|
docker02 | 192.168.1.129 |
docker03 | 192.168.1.150 |
1、docker01上,启动consul服务
复制所需文件 consul_1.5.1_linux_amd64.zip 到虚拟机
[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
启动consul
[root@docker01 ~]# consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.1.128 -client=0.0.0.0 -node=master
这时,这条命令会占用终端,可以使用nohup命令让它保持后台运行
[root@docker01 ~]# nohup consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.1.100 -client=0.0.0.0 -node=master &
consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.1.128 -client=0.0.0.0 -node=master
PS:
-bootstrap:加入这个选项时,一般都在server单节点的时候用,自选举为leader
-ui:开启内部的web页面
-data-dir:key/volume数据存储位置
-bind:指定开启服务的IP
-client: 指定访问的客户端
-node:指定集群内通信使用的名称。默认是主机名
PS:开启的端口
8300 集群节点
8301 集群内部的访问
8302 夸数据中心的通信
8500 web ui 界面
8600 使用dns协议查看节点信息的端口
查看consul的信息
[root@docker01 ~]# consul info
agent:
check_monitors = 0
check_ttls = 0
checks = 0
services = 0
build:
prerelease =
revision = 40cec984
version = 1.5.1
consul:
acl = disabled
bootstrap = true
known_datacenters = 1
leader = true
leader_addr = 192.168.1.128:8300
server = true
raft:
applied_index = 21
commit_index = 21
fsm_pending = 0
last_contact = 0
last_log_index = 21
last_log_term = 2
last_snapshot_index = 0
last_snapshot_term = 0
latest_configuration = [{Suffrage:Voter ID:adb1713c-b091-1f62-bfe1-4babe9c303ac Address:192.168.1.128:8300}]
latest_configuration_index = 1
num_peers = 0
protocol_version = 3
protocol_version_max = 3
protocol_version_min = 0
snapshot_version_max = 1
snapshot_version_min = 0
state = Leader
term = 2
runtime:
arch = amd64
cpu_count = 1
goroutines = 81
max_procs = 1
os = linux
version = go1.12.1
serf_lan:
coordinate_resets = 0
encrypted = false
event_queue = 1
event_time = 2
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 1
members = 1
query_queue = 0
query_time = 1
serf_wan:
coordinate_resets = 0
encrypted = false
event_queue = 0
event_time = 1
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 1
members = 1
query_queue = 0
query_time = 1
查看consul集群内成员的信息
[root@docker01 ~]# consul members
Node Address Status Type Build Protocol DC Segment
master 192.168.1.128:8301 alive server 1.5.1 2 dc1 <all>
2、docker02、docker03,加入consul集群
这里采用容器的方式去运行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:latest -join 192.168.1.128 -advertise 192.168.1.129 -client 0.0.0.0 -node=node01
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:latest -join 192.168.1.128 -advertise 192.168.1.150 -client 0.0.0.0 -node=node02
浏览器访问consul服务,验证集群信息
3、docker02、docker03上部署registrator服务
registrator是一个能自动发现docker container提供的服务,并在后端服务注册中心注册服务或取消服务的工具,后端注册中心支持conusl、etcd、skydns2、zookeeper等
docker02
[root@docker02 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart always gliderlabs/registrator consul://192.168.1.129:8500
docker03
[root@docekr03 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart always gliderlabs/registrator consul://192.168.1.150:8500
4、docker01部署一个nginx服务
依赖环境
[root@docker01 ~]# yum -y install gcc openssl openssl-devel zlib zlib-devel pcre pcre-devel
[root@docker01 ~]# useradd -M -s /sbin/nologin nginx
[root@docker01 ~]# tar zxf nginx-1.12.0.tar.gz -C /usr/src/
[root@docker01 ~]# cd /usr/src/nginx-1.12.0/
[root@docker01 nginx-1.12.0]# ./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.12.0]# ln -s /usr/local/nginx/sbin/* /usr/local/bin/
[root@docker01 nginx-1.12.0]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@docker01 nginx-1.12.0]# nginx
PS:这里nginx作为反向代理,代理后端docker02、docker03上nginx的 容器服务,所以我们先去docker02、docker03上部署一些服务,为了方便等会看到负载的效果,所以,运行完成容器之后,先做一个主界面内容的区分
5、docker02、03 部署web01/02、web03/04
docker02: web01 web02
[root@docker02 ~]# docker run -itd --name web01 -p 80 --restart always nginx
[root@docker02 ~]# docker exec -it web01 bash
root@333ea2509f31:/# echo web0111111111 > /usr/share/nginx/html/index.html
root@333ea2509f31:/# exit
[root@docker02 ~]# docker run -itd --name web02 -p 80 --restart always nginx
[root@docker02 ~]# docker exec -it web02 bash
root@f9ccc4c21e13:/# echo web0222222222 > /usr/share/nginx/html/index.html
root@f9ccc4c21e13:/# exit
docker03: web03 web04
[root@docker03 ~]# docker run -itd --name web03 -p 80 --restart always nginx
[root@docekr03 ~]# docker exec -it web03 bash
root@36618e432ac8:/# echo web0333333333 > /usr/share/nginx/html/index.html
root@36618e432ac8:/# exit
[root@docker03 ~]# docker run -itd --name web04 -p 80 --restart always nginx
[root@docekr03 ~]# docker exec -it web04 bash
root@0343016b2f37:/# echo web0444444444 > /usr/share/nginx/html/index.html
root@0343016b2f37:/# exit
6、更改nginx服务的配置文件
[root@docker01 ~]# mkdir /usr/local/nginx/consul
[root@docker01 ~]# cd !$
cd /usr/local/nginx/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 ~]# vim /usr/local/nginx/conf/nginx.conf
……
# index index.html index.htm;
# }
#}
include /usr/local/nginx/consul/*.conf; # 文末添加此行
}
使nginx的主配置文件能够识别到新生产的配置文件
[root@docker01 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@docker01 ~]# nginx -s reload
安装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
使用consul-template 命令,根据模板生产新的配置文件,并重新加载nginx的配置文件
[root@docker01 ~]# consul-template -consul-addr 192.168.1.128:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/bin/nginx -s reload"
这条命令会占用终端,当然,可以使用nohup命令让它保持后台运行
[root@docker01 ~]# nohup consul-template -consul-addr 192.168.1.128:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/bin/nginx -s reload" &
7、验证
此时能够看到,新生产的vhost.conf配置文件已经生效,访问本机8000端口可以得到不同容器提供的服务
[root@docker01 ~]# cat /usr/local/nginx/consul/vhost.conf
upstream http_backend {
server 192.168.1.129:32768;
server 192.168.1.129:32769;
server 192.168.1.150:32768;
server 192.168.1.150:32769;
}
server {
listen 8000;
server_name localhost;
location / {
proxy_pass http://http_backend;
}
}
[root@docker01 ~]# curl localhost:8000
web0111111111
[root@docker01 ~]# curl localhost:8000
web0222222222
[root@docker01 ~]# curl localhost:8000
web0333333333
[root@docker01 ~]# curl localhost:8000
web0444444444
这时不管后端是新添加nginx的web容器,或是删除,新生产的配置文件都会实时的更新,这是在之前运行consul-template这条命令最后添加: /usr/local/sbin/nginx -s reload 它的作用
验证删除容器:
[root@docker02 ~]# docker rm -f web01
web01
[root@docker01 ~]# curl localhost:8000
web0222222222
[root@docker01 ~]# curl localhost:8000
web0333333333
[root@docker01 ~]# curl localhost:8000
web0444444444
验证添加容器:
[root@docker02 ~]# docker run -itd --name web05 -p 80 --restart always nginx
[root@docker02 ~]# docker exec -it web05 bash
root@348d4e2ca1d3:/# echo web0555555555 > /usr/share/nginx/html/index.html
root@348d4e2ca1d3:/# exit
[root@docker01 ~]# curl localhost:8000
web0333333333
[root@docker01 ~]# curl localhost:8000
web0444444444
[root@docker01 ~]# curl localhost:8000
web0222222222
[root@docker01 ~]# curl localhost:8000
web0555555555