Docker實現服務發現

MAYSYQ發表於2020-01-20

Docker實現服務發現

Docker + Consul + registrator實現服務發現

Consul:分散式、高可用的,服務發現和配置的工具,資料中心

Registrator:負責收集dockerhost上,容器服務的資訊,並且傳送給consul

Consul-template:根據編輯好的模板生成新的nginx配置檔案,並且負責載入nginx配置檔案

實驗環境

docker01

192.168.1.70

docker02

192.168.1.60

docker03

192.168.1.50

關閉防火牆和selinux,並修改主機名

[root@localhost ~]# systemctl  stop  firewalld
[root@localhost ~]# setenforce  0
[root@localhost ~]# hostnamectl  set-hostname   docker01
[root@localhost ~]# su -

1)docker01上,啟動consul服務

[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,並啟動,身份為leader

[root@docker01 ~]# consul  agent  -server  -bootstrap  \
>  -ui  -data-dir=/var/lib/consul-data  \
>  -bind=192.168.1.70  \
>  -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.70   -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協議檢視節點資訊的埠

//檢視conusl的資訊

[root@docker01 ~]# consul info
leader_addr = 192.168.1.70:8300  //這個對我們比較有用,其他的都是一些它的演算法

//檢視叢集內成員的資訊

[root@docker01 ~]# consul  members
Node    Address            Status  Type    Build  Protocol  DC   Segment
master  192.168.1.70:8301  alive   server  1.5.1  2         dc1  <all>

2)docker02、docker03,加入consul叢集

這裡我們採用容器的方式去執行consul服務

//docker02

[root@docker02 ~]# docker  load  <  myprogrium-consul.tar
[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.70  -advertise  192.168.1.60  -client  0.0.0.0  -node=node01

//docker03

[root@docker03 ~]# docker load  <  myprogrium-consul.tar
[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.70  -advertise  192.168.1.50  -client  0.0.0.0  -node=node02

//在docker01上就能看到加入的資訊

2019/12/26 09:50:25 [INFO] serf: EventMemberJoin: node01 192.168.1.60
2019/12/26 09:50:25 [INFO] consul: member 'node01' joined, marking health alive
2019/12/26 09:53:06 [INFO] serf: EventMemberJoin: node02 192.168.1.50
2019/12/26 09:53:06 [INFO] consul: member 'node02' joined, marking health alive
[root@docker01 ~]# consul  members
Node    Address            Status  Type    Build  Protocol  DC   Segment
master  192.168.1.70:8301  alive   server  1.5.1  2         dc1  <all>
node01  192.168.1.60:8301  alive   client  0.5.2  2         dc1  <default>
node02  192.168.1.50:8301  alive   client  0.5.2  2         dc1  <default>

//瀏覽器訪問consul服務,驗證叢集資訊

192.168.1.70:8500


 

3)下載部署consul-template

//在docker01上匯入consul-template_0.19.5_linux_amd64.zip

[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

4)docker02、docker03上部署registrator服務

registrator是一個能自動發現docker container提供的服務,並在後端服務註冊中心註冊服務或取消服務的工具,後端註冊中心支援consul、etcd、skydns2、zookeeper等

//docker02

[root@docker02 ~]# docker  load  <  myregistrator.tar
[root@docker02 ~]# docker  run  -d  \
>  --name  registrator  \
>  -v  /var/run/docker.sock:/tmp/docker.sock  \
>  --restart  always  \
>  gliderlabs/registrator  \
>  consul://192.168.1.60:8500

//執行一個nginx容器

[root@docker02 ~]# docker  run  -d  -P  --name  test  nginx:latest
b0665dcbd6c5        nginx:latest             "nginx -g 'daemon of…"   10 seconds ago      Up 9 seconds        0.0.0.0:32768->80/tcp 
//對映的埠為32768

//回到瀏覽器

 

//docker03

[root@docker03 ~]# docker load  <  myregistrator.tar
[root@docker02 ~]# docker  run  -d  \
>  --name  registrator  \
>  -v  /var/run/docker.sock:/tmp/docker.sock  \
>  --restart  always  \
>  gliderlabs/registrator  \
>  consul://192.168.1.50:8500

 

5)docker01部署一個nginx服務

//依賴環境

[root@docker01 ~]# yum -y install zlib-devel openssl-devel pcre-devel

[root@docker01 ~]# useradd  -M  -s  /sbin/nologin  nginx
[root@docker01 ~]# tar  zxf  nginx-1.14.0.tar.gz 
[root@docker01 ~]# cd  nginx-1.14.0/
[root@docker01 nginx-1.14.0]# ./configure  --prefix=/usr/local/nginx  \
>  --user=nginx  --group=nginx  \
>  --with-http_stub_status_module  \
>  --with-http_realip_module  \
>  --with-pcre  --with-http_ssl_module
[root@docker01 nginx-1.14.0]# make  &&  make  install
[root@docker01 nginx-1.14.0]# ln  -s  /usr/local/nginx/sbin/*   /usr/local/sbin/
[root@docker01 nginx-1.14.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.14.0]# nginx

PS:

這裡nginx作為反向代理,代理後端docker02、docker03上nignx的容器服務,所以我們先去docker02、docker03上部署一些服務,為了方便等會看到負載的效果,所以我們執行完成容器之後,做一個主介面內容的區分

docker02:web01 web02

docker03:web03 web04

//docker02

[root@docker02 ~]# docker  run  -itd  --name  web01  -P  nginx:latest 
[root@docker02 ~]# docker exec  -it  web01   /bin/bash
root@dac0cc15f3fe:/# cd  /usr/share/nginx/html/
root@dac0cc15f3fe:/usr/share/nginx/html# echo  "This web caontainer in dockek02-web01"  >  index.html 
root@dac0cc15f3fe:/usr/share/nginx/html# cat  index.html 
This web caontainer in dockek02-web01
[root@docker02 ~]# docker  run  -itd   --name  web02  -P  nginx:latest 
[root@docker02 ~]# docker exec  -it  web02  /bin/bash
root@26d622553e5e:/# cd  /usr/share/nginx/html/
root@26d622553e5e:/usr/share/nginx/html# echo  "This web caontainer in dockek02-web02"  >  index.html 
root@26d622553e5e:/usr/share/nginx/html# cat  index.html 
This web caontainer in dockek02-web02
[root@docker02 ~]# curl  127.0.0.1:32769
This web caontainer in dockek02-web01
[root@docker02 ~]# curl  127.0.0.1:32770
This web caontainer in dockek02-web02

//docker03

[root@docker03 ~]# docker run  -itd  --name  web03  -P  nginx:latest 
[root@docker03 ~]# docker exec -it  web03  /bin/bash
root@a10f25a91edf:/# cd  /usr/share/nginx/html/
root@a10f25a91edf:/usr/share/nginx/html# echo  "This web caontainer in dockek03-web03"  >  index.html 
root@a10f25a91edf:/usr/share/nginx/html# cat  index.html 
This web caontainer in dockek03-web03
[root@docker03 ~]# docker run  -itd  --name  web04  -P  nginx:latest 
[root@docker03 ~]# docker exec -it  web04  /bin/bash
root@6d30a445c9b8:/# cd  /usr/share/nginx/html/
root@6d30a445c9b8:/usr/share/nginx/html# echo  "his web caontainer in dockek03-web04"  >  index.html 
root@6d30a445c9b8:/usr/share/nginx/html# cat  index.html   
This web caontainer in dockek03-web04
[root@docker03 ~]# curl  127.0.0.1:32768
This web caontainer in dockek03-web03
[root@docker03 ~]# curl  127.0.0.1:32769
This web caontainer in dockek03-web04

更改nginx的配置檔案

[root@docker01 ~]# cd  /usr/local/nginx/
[root@docker01 nginx]# mkdir  consul
[root@docker01 nginx]# cd  consul/
[root@docker01 consul]# pwd
/usr/local/nginx/consul
[root@docker01 consul]# vim  nginx.ctmpl
[root@docker01 consul]# cat  nginx.ctmpl 
upstream  httpd_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
//在檔案最後,也就是倒數第二行新增:
include  /usr/local/nginx/consul/*.conf;
//使nginx的主配置檔案能夠識別到新產生的配置檔案
[root@docker01 ~]# nginx  -s  reload

//使用consul-template命令,根據模板生產的配置檔案,並重新載入nginx的配置檔案

[root@docker01 consul]# consul-template -consul-addr 192.168.1.70:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx  -s  reload"

//這時這個命令會佔用終端,可以使用nohup命令讓它保持後臺執行

[root@docker01 consul]# nohup  consul-template -consul-addr 192.168.1.70:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx  -s  reload"  &

//此時,應該能夠看到,新生產的vhost.conf配置檔案已經生效,訪問本機的8000埠可以得到不同容器提供的服務

[root@docker01 ~]# cd  /usr/local/nginx/consul/
[root@docker01 consul]# ls
nginx.ctmpl  vhost.conf
[root@docker01 consul]# cat  vhost.conf
upstream  httpd_backend {
	
	server 192.168.1.60:32768;
	
	server 192.168.1.60:32769;
	
	server 192.168.1.60:32770;
	
	server 192.168.1.50:32768;
	
	server 192.168.1.50:32769;
	
}

server {
    listen  8000;
    server_name  localhost;
    location  / {
    proxy_pass  http://httpd_backend;
    }
}
[root@docker01 consul]# curl  localhost:8000
This web caontainer in dockek02-web01
[root@docker01 consul]# curl  localhost:8000
This web caontainer in dockek02-web02
[root@docker01 consul]# curl  localhost:8000
This web caontainer in dockek03-web03
[root@docker01 consul]# curl  localhost:8000
This web caontainer in dockek03-web04

當然,這時不管是新增新的nginx的web容器,或是刪除,生產的配置檔案都會時時更新,這是我們在執行consul-template這條命令最後新增:/usr/local/sbin/nginx -s reload它的作用

//刪除之前的test容器,檢視vhost檔案

[root@docker02 ~]# docker rm  -f  test
[root@docker01 consul]# cat  vhost.conf 
upstream  httpd_backend {
	
	server 192.168.1.60:32769;
	
	server 192.168.1.60:32770;
	
	server 192.168.1.50:32768;
	
	server 192.168.1.50:32769;
}

//在執行一個web05,檢視vhost檔案的變化

[root@docker02 ~]# docker  run  -itd  --name  web05 -P nginx:latest 
upstream  httpd_backend {
	
	server 192.168.1.60:32769;
	
	server 192.168.1.60:32770;
	
	server 192.168.1.60:32771;
	
	server 192.168.1.50:32768;
	
	server 192.168.1.50:32769;
}

1、docker01主機上以二進位制包的方式部署consul服務並後臺執行,其身份為leader

2、docker02、docker03以容器的方式執行consul服務,並加入到docker01的consul群集中

3、在主機docker02、docker03上後臺執行registrator容器,使其自動發現docker容器提供的服務,併傳送給consul

4、在docker01上部署Nginx,提供反向代理服務,docker02、docker03主機上基於Nginx映象,各執行兩個web容器,提供不同的網頁檔案,以便測試效果

5、在docker01上安裝consul-template命令,將收集到的資訊(registrator收集到容器的資訊)寫入template模板中,並且最終寫入Nginx的配置檔案中

6、至此,實現客戶端通過訪問Nginx反向代理伺服器(docker01),獲得docker02、docker03伺服器上執行的Nginx容器提供的網頁檔案

 

Consul:分散式、高可用的,服務發現和配置的工具,資料中心

Registrator:負責收集dockerhost上,容器服務的資訊,並且傳送給consul

registrator是一個能自動發現docker container提供的服務,並在後端服務註冊中心註冊服務或取消服務的工具,後端註冊中心支援consul、etcd、skydns2、zookeeper等

Consul-template:根據編輯好的模板生成新的nginx配置檔案,並且負責載入nginx配置檔案

 

 

 

 

 

 

 

 

 

相關文章