Consul是一種分佈式、高可用、支持水平擴展的服務註冊與發現工具。包含的特性有:服務發現、健康檢查、鍵值存儲、多數據中心和服務管理頁面等。html
官方架構設計圖:nginx
圖中包含兩個Consul數據中心(即兩個Consul集羣)。數據中心1由多個SERVER和CLIENT組成,數據中心2由多個CLIENT組成。對於Consul集羣而言,SERVER或CLIENT都是集羣的一個節點,服務可註冊到任意節點上,從而實現註冊信息共享。docker
# CLIENT bootstrap
表示consul的client模式,全部註冊到當前節點的服務會被轉發到SERVER,自己不持久化數據。其職責是健康檢查、服務註冊等,當服務數量特別龐大時,分別啓動多個client可減小server壓力。安全
# SERVER 服務器
表示consul的server模式,功能和CLIENT都同樣,區別是它能把全部信息持久化到本地,遇到故障時,信息是能夠被保留的。架構
# LEADER 分佈式
圖中中間SERVER帶有LEADER標識,說明在多個SERVER中,其爲老大。它負責各個節點的健康檢查和同步註冊信息給其餘SERVER。ide
官方文檔:https://www.consul.io/intro/index.html工具
-bootstrap-expect
--配置數據中心中預期的SERVER的數量,當集羣中啓動的SERVER達到預期值時,Consul開始引導集羣;
-bind
--內部集羣通訊綁定的地址,默認狀況下是"0.0.0.0";
-client
--consul服務偵聽地址,這個地址提供HTTP、DNS、RPC等服務,默認是127.0.0.1因此不對外提供服務,若是你要對外提供服務改爲0.0.0.0;
-config-file
--服務啓動時要加載的配置文件;
-config-dir
--配置文件目錄;
-config-format
--指定要加載的配置文件的格式;
-data-dir
--數據目錄;
-dev
--啓用開發服務器模式。對於在關閉全部持久性選項的狀況下快速啓動consul代理很是有用,不適合生產使用,由於它不將任何數據寫入磁盤;
-join
--啓動時要加入到的另外一位代理地址;
-retry-join
--加入失敗後重試鏈接,對於明確可用地址的狀況下頗有用;
更多詳細參數見: https://www.consul.io/docs/agent/options.html
筆者在作此實驗以前,也查找了許多資料及部署方式,網上不少資源都是在物理機上常規(非docker方式)部署consul集羣或者一臺服務器上部署整個consul集羣。而在生產環境中,出於數據安全及冗餘等問題,將consul集羣採用docker方式分佈式部署在多臺服務器上,方案尤佳,此實驗將採用此方式操做!
此實驗前提條件是全部服務器都有可用的DOCKER運行環境!官方概述說SERVER節點最好是3~5個,此實驗將部署3個server(因server和client的區別就在於數據的持久化差別,同時又涉及到集羣故障處理等操做實現,又因資源因素,此實驗不部署client),規劃以下:
192.168.10.11 SERVER1,選爲LEADER
192.168.10.12 SERVER2
192.168.10.13 SERVER3
192.168.10.14 REGISTRY
--net=host
--將容器須要映射的端口所有映射到物理機上,而且端口保持不變;
# SERVER1上操做
[root@11 ~]# docker run -d --name=consul --net=host -e CONSUL_BIND_INTERFACE=eth0 consul agent -server=true -client=0.0.0.0 -bind=192.168.10.11 -ui -bootstrap-expect=2
# 參數說明
一、eth0表明服務器卡網,也多是ens33,ens160等,根據服務器信息傳入相應參數便可;
二、經過bind本機ip,改變了consul服務對外的ip地址,默認是172.17.0.2;查看命令是 docker inspect --format '{{ .NetworkSettings.IPAddress }}' consul1 ,consul1是對應的容器名稱;
三、當須要指定配置文件和數據目錄時,可用以下命令啓動:
docker run -d --name=consul1 -v /consulconfig:/config/file -config-dir=/config/file -date-dir=/tmp/consul --net=host -e CONSUL_BIND_INTERFACE=eth0 consul agent -server=true -client=0.0.0.0 -bind=192.168.10.11 -ui -bootstrap-expect=2
# 查看日誌
# 此時集羣consul服務未達到預期的數量,會出現報錯(繼續完成其餘節點的部署將解決),以下:
[root@11 ~]# docker logs -f consul
# SERVER二、SERVER3上分別操做
# docker run -d --name=consul --net=host -e CONSUL_BIND_INTERFACE=eth0 consul agent -server -client=0.0.0.0 -ui -bootstrap-expect=2 -retry-join=192.168.10.11
# 此時登錄管理頁面,可查看到以下效果
# CLINET上操做(普及client部署命令,此實驗未有此步驟,可忽略!)
[root@13 ~]# docker run -d --name=consul3 --net=host -e CONSUL_BIND_INTERFACE=eth0 consul agent -client=0.0.0.0 -retry-join=192.168.10.11
# 查看集羣成員
docker exec -t consul consul members # 第一個consul爲容器名稱;
# 查看投票狀態
docker exec -t consul consul operator raft list-peers
官方文檔:https://hub.docker.com/_/consul
將容器中運行的服務註冊到Consul中,能夠經過調用API和其餘軟件進行操做,此處將介紹開源軟件Registrator對服務進行註冊操做。
# 重點申明
當服務器上的docker容器經過--net=host方式映射端口時,容器信息沒法自動註冊到consul中,故請經過-p參數實現端口映射!
# REGISTRY服務器上操做
# 啓動Registrator
docker run -d \
--name=registrator \
--net=host \
-v /var/run/docker.sock:/tmp/docker.sock \
--restart=always \
gliderlabs/registrator:latest \
-ip=192.168.10.16 \
consul://192.168.10.12:8500
# 參數說明
-ip是本機ip地址;
consul://192.168.10.12:8500是任意一臺server地址(11,12,13均可);
# 運行測試docker
[root@kazihuo ~]# docker run -itd -p 81:80 nginx
# 頁面查看
官方地址:https://gliderlabs.com/registrator/latest/
此集羣有3個server,而其指望值的數量是2,當集羣中有一臺server故障時,將自動選取新的leader,操做以下:
# SERVER1上停掉consul server;
[root@11 ~]# docker stop consul
# 在另外2臺server上任意一臺查看集羣狀態;
# 此時集羣中選取了新leader;
# docker exec -t consul consul members
# docker exec -t consul consul operator raft list-peers