Consul是基於GO語言開發的開源工具,主要面向分佈式,服務化的系統提供服務註冊、服務發現和配置管理的功能。Consul的功能都很實用,其中包括:服務註冊/發現、健康檢查、Key/Value存儲、多數據中心和分佈式一致性保證等特性。Consul自己只是一個二進制的可執行文件,因此安裝和部署都很是簡單,只須要從官網下載後,在執行對應的啓動腳本便可。html
基礎特性
1.服務註冊/發現
爲何微服務架構下就須要作服務註冊和服務發現呢?微服務的目標就是要將原來大一統的系統架構,拆分紅細粒度的按功能職責分紅的小系統,這樣就會出現不少小的系統,部署的節點也會隨之增長。試想一下,若是沒有一個統一的服務組件來管理各系統間的列表,微服務架構是很難落地實現的。
Consul提供的服務註冊/發現功能在數據強一致性和分區容錯性上都有很是好的保證,但在集羣可用性下就會稍微差一些(相比Euerka來講)。node
2.數據強一致性保證
Consul採用了一致性算法Raft來保證服務列表數據在數據中心中各Server下的強一致性,這樣能保證同一個數據中心下無論某一臺Server Down了,請求從其餘Server中一樣也能獲取的最新的服務列表數據。數據強一致性帶來的反作用是當數據在同步或者Server在選舉Leader過程當中,會出現集羣不可用。linux
3.多數據中心
Consul支持多數據中心(Data Center),多個數據中心之間經過Gossip協議進行數據同步。多數據中心的好處是當某個數據中心出現故障時,其餘數據中心能夠繼續提供服務,提高了可用性。nginx
4.健康檢查
Consul支持基本硬件資源方面的檢查,如:CPU、內存、硬盤等web
5.Key/Value存儲
Consul支持Key/Value存儲功能,能夠將Consul做爲配置中心使用,能夠將一些公共配置信息配置到Consul,而後經過Consul提供的 HTTP API來獲取對應Key的Value。算法
主機名 | IP地址 | 所需組件 |
---|---|---|
docker01 | 192.168.45.129 | consul,consul-template,nginx |
docker02 | 192.168.45.141 | consul, registrator |
docker03 | 192.168.45.142 | consul, registrator |
注:實驗環境關閉防火牆、禁用SElinux
所需的安裝包:連接:https://pan.baidu.com/s/1R9ms2y0j5cdFmBvtcvMqiA
提取碼:olcy
一)、在Docker01上執行二進制命令部署consul服務docker
[root@docker01 ~]# rz //上傳壓縮包 [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 //賦予執行權限 [root@docker01 ~]# nohup consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.45.129 -client=0.0.0.0 -node=master & [1] 3904 [root@docker01 ~]# nohup: 忽略輸入並把輸出追加到"nohup.out" //執行命令後,會提示該信息,並佔用終端,按兩下回車鍵便可, //運行上述命令後,會在當前目錄下生成一個名爲「nohup.out」的文件,其存放的是consul服務的運行日誌 //執行上述命令後,consul就放到後臺運行了,並返回其PID號,能夠經過「jobs -l」命令進行查看
上述命令的相關參數解釋以下: * -server:添加一個服務; * -bootstrap:通常在server單節點的時候使用,自選舉爲leader; * -ui:開啓內部的web界面; * -bind:指定開啓服務的IP(就是本機IP咯); * -client:指定服務的客戶端(通常此處爲任意); * -node:在集羣內部通訊使用的名稱,默認是主機名。 * 開啓的端口做用以下: * 8300:集羣節點; * 8301:集羣內部訪問的端口; * 8302:跨數據中心之間的通訊; * 8500:http_ui; * 8600:DNS
[root@docker01 ~]# consul info //能夠看到這個羣集的leader及版本信息 //如:leader_addr = 192.168.45.129:8300 [root@docker01 ~]# consul members //查看consul集羣內成員的信息
至此,客戶端能夠訪問docker01的8500端口進行驗證:
二)、docker0二、docker03,加入consul集羣bootstrap
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.45.129 -advertise 192.168.45.141 -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.45.129 -advertise 192.168.45.142 -client 0.0.0.0 -node=node02 //上述命令中,「-join」是指定leader的IP地址(也就是docker01);「-advertise」是指定本身自己的IP地址 //注意:node名稱在consul羣集中,必須惟一
至此,執行「consul members」命令便可查看到docker02及docker03的信息:vim
[root@docker01 ~]# consul members Node Address Status Type Build Protocol DC Segment master 192.168.45.129:8301 alive server 1.5.1 2 dc1 <all> node01 192.168.45.141:8301 alive client 0.5.2 2 dc1 <default> node02 192.168.45.142:8301 alive client 0.5.2 2 dc1 <default>
瀏覽器訪問consul服務,驗證集羣信息:
三)、docker02及docker03主機上以容器的方式運行registrator服務
注:registrator是一個能自動發現docker container提供的服務,並在後端服務註冊中心註冊服務或取消服務的工具,後端註冊中心支持conusl、etcd、skydns二、zookeeper等。後端
docker02配置以下: [root@docker02 ~]# docker run -d --name registrator -v /var/run/docker.sock:/tmp/docker.sock --restart always gliderlabs/registrator consul://192.168.45.141: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.45.142:8500 //上述命令的做用是將收集的容器信息發送給本機的8500端口來cha顯示
瀏覽器測試訪問,這裏我只訪問了node1,這裏就不訪問node2了:
四)、在主機docker01上部署Nginx服務,以便提供反向代理
[root@docker01 ~]# yum -y install gcc openssl openssl-devel zlib zlib- devel pcre pcre-devel [root@docker01 ~]# rz [root@docker01 ~]# tar zxf nginx-1.14.0.tar.gz -C /usr/src/ [root@docker01 ~]# useradd -M -s /sbin/nologin nginx [root@docker01 ~]# cd /usr/src/nginx-1.14.0/ [root@docker01 nginx-1.14.0]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ [root@docker01 nginx-1.14.0]# nginx //開啓nginx服務 [root@docker01 nginx-1.14.0]# netstat -anput | grep nginx //確認nginx服務已開啓 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 7232/nginx: master
五)、在docker01安裝consul-template命令工具,並編寫模板
注:consul-template的做用就是將收集到的信息(把registrator收集到容器的信息)寫入template模板中,而且最終寫入Nginx的配置文件中。
[root@docker01 ~]# rz //上傳我提供的包 [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 //賦予執行權限 [root@docker01 ~]# cd /usr/local/nginx/ //在Nginx安裝目錄下,編寫模板供consul-template命令工具使用,而且配置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 }} } server { listen 8000; //監聽地址可任意指定,不要衝突便可 server_name localhost; location / { proxy_pass http://http_backend; } } //編輯完成後,保存退出便可
[root@docker01 consul]# vim ../conf/nginx.conf //在主配置文件中進行調用生成的vhost.conf文件 include /usr/local/nginx/consul/*.conf; } //在配置文件末尾的花括號上方寫入「include」配置,進行調用vhost.conf文件 [root@docker01 consul]# nginx -s reload //重啓nginx服務 [root@docker01 consul]# nohup consul-template -consul-addr 192.168.45.129:8500 -template "/usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:/usr/local/sbin/nginx -s reload" & [2] 64430 [root@docker01 consul]# nohup: 忽略輸入並把輸出追加到"nohup.out" [root@docker01 consul]# //一樣也是將這條命令放入後臺執行,不然會佔用前臺的終端 //這條命令的做用就i是將本機收集到的信息,生成一個vhost.conf的文件,將命令放入後臺才能保證明時發現同步並更新
注:這裏附加了一張圖
六)、驗證服務的實時發現功能
配置至此,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@1aaf578ec6f7:/# echo "this is a web01 test." > /usr/share/nginx/html/index.html
注:在docker02及docker03運行四個Nginx容器後(必須之後臺運行的方式,也就是說在運行時必須有「-d」選項),那麼,此時訪問docker01的8000端口,就會循環訪問到這四個容器提供的網頁文件,以下:
[root@docker01 consul]# curl 192.168.45.141:8000 this is a web01 test. [root@docker01 consul]# curl 192.168.45.141:8000 this is a web02 test. [root@docker01 consul]# curl 192.168.45.141:8000 this is a web03 test. [root@docker01 consul]# curl 192.168.45.141:8000 this is a web04 test. [root@docker01 consul]# curl 192.168.45.141:8000 this is a web01 test. [root@docker01 consul]# curl 192.168.45.141:8000 this is a web02 test. //而且查看如下文件,會看到其中的配置 [root@docker01 consul]# pwd /usr/local/nginx/consul [root@docker01 consul]# cat vhost.conf //如下web池中的server都是基於編寫的模板自動生成的 upstream http_backend { server 192.168.45.141:32768; server 192.168.45.141:32769; server 192.168.45.142:32768; server 192.168.45.142:32769; } server { listen 8000; server_name localhost; location / { proxy_pass http://http_backend; } } //因爲consul-template是在後臺運行的,因此,只要檢測到容器的變化,就會動態修改上述文件 //而且重啓Nginx服務,使更改生效
至此,consul+registrator+docker實時服務發現就配置完成了