服務介紹
Consul是一種分布式、高可用、支持水平擴展的服務注冊與發現工具。包含的特性有:服務發現、健康檢查、鍵值存儲、多數據中心和服務管理頁面等。
官方架構設計圖:
圖中包含兩個Consul數據中心(即兩個Consul集群)。數據中心1由多個SERVER和CLIENT組成,數據中心2由多個CLIENT組成。對於Consul集群而言,SERVER或CLIENT都是集群的一個節點,服務可注冊到任意節點上,從而實現注冊信息共享。
# CLIENT
表示consul的client模式,所有注冊到當前節點的服務會被轉發到SERVER,本身不持久化數據。其職責是健康檢查、服務注冊等,當服務數量特別龐大時,分別啟動多個client可減少server壓力。
# SERVER
表示consul的server模式,功能和CLIENT都一樣,區別是它能把所有信息持久化到本地,遇到故障時,信息是可以被保留的。
# LEADER
圖中中間SERVER帶有LEADER標識,說明在多個SERVER中,其為老大。它負責各個節點的健康檢查和同步注冊信息給其他SERVER。
官方文檔: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
# 參數說明
1、eth0代表服務器卡網,也可能是ens33,ens160等,根據服務器信息傳入相應參數即可;
2、通過bind本機ip,改變了consul服務對外的ip地址,默認是172.17.0.2;查看命令是 docker inspect --format '{{ .NetworkSettings.IPAddress }}' consul1 ,consul1是對應的容器名稱;
3、當需要指定配置文件和數據目錄時,可用如下命令啟動:
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
# SERVER2、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