docker 配置Consul+registrator實時服務發現

Consul是用於服務發現和配置的工具。
Consul是分佈式的,高度可用的,而且具備極高的可伸縮性。html

Consul服務提供如下關鍵特性:node

  • 服務發現:Consul 的客戶端可用提供一個服務,好比 api 或者mysql ,另一些客戶端可用使用 Consul 去發現一個指定服務的提供者.經過 DNS 或者 HTTP 應用程序可用很容易的找到他所依賴的服務;
  • 健康檢查:Consul 客戶端可用提供任意數量的健康檢查,指定一個服務(好比: webserver 是否返回了200 OK 狀態碼)或者使用本地節點(好比:內存使用是否大於90%). 這個信息可由 operator用來監視集羣的健康.被服務發現組件用來避免將流量發送到不健康的主機;
  • Key/Value存儲:應用程序可用根據本身的須要使用 Consul 的層級的 Key/Value 存儲.好比動態配置,功能標記,協調,領袖選舉等等,簡單的 HTTP API 讓他更易於使用;
  • 多數據中心:Consul支持開箱即用的多數據中心.這意味着用戶不須要擔憂須要創建額外的抽象層讓業務擴展到多個區域。

1、環境以下mysql

主機名 IP 服務
docker01 192.168.171.151 docker
docker02 192.168.171.150 docker
docker03 192.168.171.152 docker

工做示意圖以下linux

docker 配置Consul+registrator實時服務發現

示意圖的大概流程以下
一、docker01主機上以二進制包的方式部署consul服務並後臺運行,其身份爲leader;
二、docker0二、docker03以容器的方式運行consul服務,並加入到docker01的consul羣集中;
三、在主機docker0二、docker03上後臺運行registrator容器,使其自動發現docker容器提供的服務;
四、在docker01上部署Nginx,提供反向代理服務,docker0二、docker03主機上基於Nginx鏡像,各運行兩個web容器,提供不一樣的網頁文件,以便測試效果;
五、在docker01上安裝consul-template命令,將收集到的信息(registrator收集到容器的信息)寫入template模板中,而且最終寫入Nginx的配置文件中。
六、至此,實現客戶端經過訪問Nginx反向代理服務器(docker01),得到docker0二、docker03服務器上運行的Nginx容器提供的網頁文件。
注:registrator是一個自動發現docker container提供的服務,而且在後端服務註冊中心(數據中心)註冊服務。主要用來收集容器運行服務的信息,而且發送給consul。數據中心除了consul外,還有etcd、zookeeper等。nginx

所需源碼包web

2、在Docker01上執行二進制命令部署consul服務sql

[root@docker01 ~]# unzip consul_1.5.1_linux_amd64.zip       # 解壓consul命令
[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=192.168.171.151 -client=0.0.0.0 -node=master &
[1] 2713
[root@docker01 ~]# nohup: ignoring input and appending output to ‘nohup.out’
#運行上述命令後,會在當前目錄下生成一個名爲「nohup.out」的文件,其存放的是consul服務的運行日誌
#執行上述命令後,consul就放到後臺運行了,並返回其PID號,能夠經過「jobs -l」命令進行查看

上述命令的相關參數解釋以下docker

-server:添加一個服務;
-bootstrap:通常在server單節點的時候使用,自選舉爲leader;
-ui:開啓內部的web界面;
-bind:指定開啓服務的IP(就是本機IP咯);
-client:指定服務的客戶端(通常此處爲任意);
-node:在集羣內部通訊使用的名稱,默認是主機名。
開啓的端口做用以下
8300:集羣節點;
8301:集羣內部訪問的端口;
8302:跨數據中心之間的通訊;
8500:http_ui;
8600:DNS。bootstrap

#兩條查詢命令
[root@docker01 ~]# consul info    #能夠看到這個羣集的leader及版本信息
#如:leader_addr = 192.168.171.151:8300
[root@docker01 ~]# consul members          #查看集羣內部信息

客戶端訪問docker01的8500端口進行驗證,會看到如下頁面
docker 配置Consul+registrator實時服務發現
3、在docker02及docker03主機上以容器的方式運行consul服務vim

#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 -join 192.168.171.151 -advertise 192.168.171.150 -client 0.0.0.0 -node=node01
#上述命令中,「-join」是指定leader的IP地址(也就是docker01);「-advertise」是指定本身自己的IP地址
#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 -join 192.168.171.151 -advertise 192.168.171.152 -client 0.0.0.0 -node=node02
#與docker02主機執行的命令相似,可是改爲了本身的IP,及node名稱也改了
#注意:node名稱在consul羣集中,必須惟一
#注意:node名稱在consul羣集中,必須惟一
#注意:node名稱在consul羣集中,必須惟一

注:主機docker01的consul服務也能夠採用容器的方式部署,這裏只是爲了展現其多種部署方式而已
.
在docker01主機上,執行「consul members」命令,便可查看到docker02及docker03的信息,以下

[root@docker01 ~]# consul members
Node    Address               Status  Type    Build  Protocol  DC   Segment
master  192.168.171.151:8301  alive   server  1.5.1  2         dc1  <all>
node01  192.168.171.150:8301  alive   client  0.5.2  2         dc1  <default>
node02  192.168.171.152:8301  alive   client  0.5.2  2         dc1  <default>

客戶端訪問192.168.171.151的8500端口
docker 配置Consul+registrator實時服務發現
4、在docker02及docker03主機上以容器的方式運行registrator服務

#docker02配置以下
[root@docker02 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator consul://192.168.171.150:8500
#上述命令的做用是將收集的容器信息發送給本機的8500端口來顯示
#docker03配置以下
[root@docker03 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator consul://192.168.171.152:8500

docker 配置Consul+registrator實時服務發現
5、在主機docker01上部署Nginx服務,以便提供反向代理
優化nginx可參考:Nginx深度優化

[root@docker01 ~]# yum -y install openssl-devel pcre-devel 
[root@docker01 ~]# tar zxf nginx-1.14.0.tar.gz 
[root@docker01 ~]# useradd -M -s /sbin/nologin www
[root@docker01 ~]# cd nginx-1.14.0/
[root@docker01 nginx-1.14.0]# ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_realip_module --with-pcre --with-http_ssl_module && make && make install
[root@docker01 nginx-1.14.0]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
[root@docker01 nginx-1.14.0]# nginx

6、在docker01安裝consul-template命令工具,並編寫模板
consul-template的做用:將收集到的信息(把registrator收集到容器的信息)寫入template模板中,而且最終寫入Nginx的配置文件中。

一、生成consul-template命令工具(若要安裝新版本的能夠到Consul模板發佈頁面,下載最新版本使用)

[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安裝目錄下,編寫模板供consul-template命令工具使用,而且配置Nginx反向代理

[root@docker01 ~]# cd /usr/local/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 }}
}
#以上是go語言編寫的,目的是爲了收集Nginx相關的IP地址及端口信息
#下面是定義反向代理
server {
  listen 8000;                           # 監聽地址可任意指定,不要衝突便可
  server_name localhost;
  location / {
  proxy_pass http://http_backend;
  }
}
[root@docker01 consul]# nohup consul-template -consul-addr 192.168.171.151:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx -s reload" &
#將本機收集到的信息,生成一個vhost.conf文件
#此服務必須在後臺運行,纔可實現服務的實時發現與更新
[root@docker01 consul]# vim ../conf/nginx.conf             # 在主配置文件中進行調用生成的vhost.conf文件
include /usr/local/nginx/consul/*.conf;
}
#在配置文件末尾的花括號上方寫入「include」配置,進行調用vhost.conf文件

7、驗證服務的實時發現功能
配置至此,docker02或者docker03上一旦有任何Nginx相關的容器之後臺「-d」的運行方式運行,都會被添加到反向代理中來,進行調度,一旦容器發生意外關閉,則能夠自動從反向代理配置文件中剔除。
如今能夠在docker0二、和docker03上分別運行兩臺Nginx容器,其容器名稱依次爲web0一、web02.......,其網頁文件依次爲:this is web01 test、this is web02 test..........
爲其準備不一樣的網頁文件的目的就是方便客戶端訪問時區分訪問的是哪臺容器。

因爲其配置過程相似,我這裏就寫出一個運行Nginx容器的過程,其餘照作便可
配置示例以下(運行web01並修改其首頁文件)

[root@docker02 ~]# docker run -d -P --name web01 nginx
[root@docker02 ~]# docker exec -it web01 /bin/bash
root@592153f74591:/# echo "this is a web01 test." > /usr/share/nginx/html/index.html

在docker02及docker03運行四個Nginx容器後(必須之後臺運行的方式,也就是說在運行時必須有「-d」選項),那麼,此時訪問docker01的8000端口,就會循環訪問到這四個容器提供的網頁文件,以下

[root@docker01 ~]# curl 192.168.171.151:8000
this is a web01 test.
[root@docker01 ~]# curl 192.168.171.151:8000
this is a web02 test.
[root@docker01 ~]# curl 192.168.171.151:8000
this is a web03 test.
[root@docker01 ~]# curl 192.168.171.151:8000
this is a web04 test.
[root@docker01 ~]# curl 192.168.171.151:8000
this is a web01 test.
[root@docker01 ~]# curl 192.168.171.151:8000
this is a web02 test.
[root@docker01 ~]# curl 192.168.171.151:8000
this is a web03 test.
[root@docker01 ~]# curl 192.168.171.151:8000
this is a web04 test.
#而且查看如下文件,會看到其中的配置
[root@docker01 ~]# cd /usr/local/nginx/consul/
[root@docker01 consul]# cat vhost.conf              # 如下web池中的server都是基於編寫的模板自動生成的
upstream http_backend {

  server 192.168.171.150:32768;

  server 192.168.171.150:32769;

  server 192.168.171.152:32768;

  server 192.168.171.152:32769;

}

server {
  listen 8000;            
  server_name localhost;
  location / {
  proxy_pass http://http_backend;
  }
}
#因爲consul-template是在後臺運行的,因此,只要檢測到容器的變化,就會動態修改上述文件
#而且重啓Nginx服務,使更改生效

若如今刪除docker02及docker03全部Nginx容器,只保留一臺web01,而後再次訪問Nginx代理服務器的8000端口,則永遠只能訪問到web01的網頁,而且查看vhost.conf文件,以前添加的server地址及端口也沒有了,以下(自行刪除或中止Nginx容器)

[root@docker01 consul]# cat vhost.conf              # 該文件中只有web01容器的IP及端口信息了
upstream http_backend {

  server 192.168.171.150:32768;

}

server {
  listen 8000;            
  server_name localhost;
  location / {
  proxy_pass http://http_backend;
  }
}
# 進行屢次訪問,也只能訪問到web01的頁面
[root@docker01 consul]# curl 192.168.171.151:8000
this is a web01 test.
[root@docker01 consul]# curl 192.168.171.151:8000
this is a web01 test.
[root@docker01 consul]# curl 192.168.171.151:8000
this is a web01 test.
[root@docker01 consul]# curl 192.168.171.151:8000
this is a web01 test.
相關文章
相關標籤/搜索