Consul簡介及環(huán)境搭建
Consul簡介
Consul是由HashiCorp基于Go語言開發(fā)的支持多數(shù)據(jù)中心的分布式高可用服務(wù)發(fā)布和注冊軟件, 采用Raft算法保持服務(wù)的一致性, 且支持健康檢查.
和Eureka的侵入式服務(wù)中心不同的是, Consul是以獨立的軟件形式運行, 對項目侵入性小, 更方便部署.
Consul架構(gòu)
上圖為多機房數(shù)據(jù)中心部署, 每個數(shù)據(jù)中心至少三臺Consul, 一臺LEADER, 另外的兩臺是FOLLOWER.
Consul術(shù)語
代理(agent)
代理是Consul集群上每個成員的守護進程, 它是由consul agent命令開始運行. 代理能夠以客戶端或服務(wù)器模式運行. 由于所有節(jié)點都必須運行代理, 所以將節(jié)點引用為客戶端或服務(wù)器更為簡單, 但還有其他實例的代理. 所有代理可以運行DNS或HTTP接口, 并負(fù)責(zé)運行檢查和保持服務(wù)同步.
客戶端
客戶端可以將所有RPC請求轉(zhuǎn)發(fā)到服務(wù)器的代理. 客戶端是相對無狀態(tài)的. 客戶端執(zhí)行的唯一后臺活動是LANgossip池. 它消耗最小的資源開銷和少量的網(wǎng)絡(luò)帶寬.
服務(wù)器
服務(wù)器端是具有擴展的功能的代理, 它主要參與維護集群狀態(tài), 響應(yīng)RPC查詢, 與其他數(shù)據(jù)中心交換WAN gossip, 以及向leader節(jié)點或遠程數(shù)據(jù)中心轉(zhuǎn)發(fā)查詢.
數(shù)據(jù)中心
雖然數(shù)據(jù)中心的定義似乎很明顯, 但仍有一些細(xì)微的細(xì)節(jié)必須考慮. 比如說, 在EC2中, 多個可用中心 (EC2和AZ是AWS里的概念, 不了解的話可以去看看AWS文檔) 是否應(yīng)該被認(rèn)為是一個單個的數(shù)據(jù)中心呢? 我們將一個數(shù)據(jù)中心定義為一個私有, 低延遲和高帶寬的網(wǎng)絡(luò)環(huán)境, 這不包括通過公共互聯(lián)網(wǎng)的通信. 但是為了我們的目的, 單個EC2區(qū)域內(nèi)的多個可用區(qū)域?qū)⒈灰暈閱蝹€數(shù)據(jù)中心的一部分.
一致性
在我們的文檔中, "一致性"的意思是對于被選舉出的leader以及事物的順序的認(rèn)同. 因為這些事件被應(yīng)用到有限狀態(tài)機上, 我們對一致性的定義又暗含了復(fù)制備份的狀態(tài)機的一致性.
Gossip
consul是建立在Serf之上的, 它提供了一個完整的gossip協(xié)議, 用在很多地方. Serf提供了成員管理, 故障檢測和事件廣播的功能. Gossip的節(jié)點到節(jié)點之間的通信使用了UDP協(xié)議.
Lan Gossip
指在同一局域網(wǎng)或數(shù)據(jù)中心的節(jié)點上的LAN Gossip池. Client到Server會通過Lan Gossip, 所有的節(jié)點都在Gossip pool中
Wan Gossip
指包含服務(wù)器的WAN Gossip池, 這些服務(wù)器在不同的數(shù)據(jù)中心, 通過網(wǎng)絡(luò)進行通信.
Consul使用
devlopment模式
以開發(fā)模式啟動: consul agent -dev, 如果需要Web界面的話加-ui即可, 集群的LAN服務(wù)默認(rèn)啟動在8301端口上, WAN服務(wù)默認(rèn)啟動在8302端口上, Web服務(wù)默認(rèn)端口是8500, DNS服務(wù)默認(rèn)端口是8600, gRPC服務(wù)默認(rèn)端口是8502
默認(rèn)是以server角色啟動的, 啟動后用consul members可以查看服務(wù)下的節(jié)點信息, 或者通過HTTP接口請求http://localhost:8500/v1/catalog/nodes也可以看到節(jié)點信息數(shù)據(jù)以json形式返回.
使用dig命令可以查看consul中DNS服務(wù)的一些信息, 命令如: dig @127.0.0.1 -p 8600 nodeName
注冊服務(wù)
一般情況下consul會在啟動時通過參數(shù)的形式進行配置, 但這樣子比較麻煩, 我們通過在/etc/consul.d目錄下來新建配置文件的形式, 在每次啟動時加載配置文件來進行啟動.
consul的配置信息可以在 https://www.consul.io/docs/agent/options.html 查看, 其中部分選項如下:
-advertise: 通知展現(xiàn)地址用來改變我們給集群中的其他節(jié)點展現(xiàn)的地址, 一般情況下-bind地址就是展現(xiàn)地址
-bootstrap: 用來控制一個server是否在bootstrap模式, 在一個datacenter中只能有一個server處于bootstrap模式, 當(dāng)一個server處于bootstrap模式時, 可以自己選舉為raft leader.
-bootstrap-expect: 在一個datacenter中期望提供的server節(jié)點數(shù)目, 當(dāng)該值提供的時候, consul一直等到達到指定sever數(shù)目的時候才會引導(dǎo)整個集群, 該標(biāo)記不能和bootstrap公用
-bind: 該地址用來在集群內(nèi)部的通訊, 集群內(nèi)的所有節(jié)點到地址都必須是可達的, 默認(rèn)是0.0.0.0
-client: consul綁定在哪個client地址上, 這個地址提供HTTP曹锨、DNS炭懊、RPC等服務(wù), 默認(rèn)是127.0.0.1
-config-file: 明確的指定要加載哪個配置文件
-config-dir: 配置文件目錄, 里面所有以.json結(jié)尾的文件都會被加載
-data-dir: 提供一個目錄用來存放agent的狀態(tài), 所有的agent允許都需要該目錄, 該目錄必須是穩(wěn)定的, 系統(tǒng)重啟后都繼續(xù)存在
-dc: 該標(biāo)記控制agent允許的datacenter的名稱, 默認(rèn)是dc1
-encrypt: 指定secret key, 使consul在通訊時進行加密, key可以通過consul keygen生成, 同一個集群中的節(jié)點必須使用相同的key
-join: 加入一個已經(jīng)啟動的agent的ip地址, 可以多次指定多個agent的地址. 如果consul不能加入任何指定的地址中, 則agent會啟動失敗. 默認(rèn)agent啟動時不會加入任何節(jié)點.
-retry-join: 和join類似, 但是允許你在第一次失敗后進行嘗試.
-retry-interval: 兩次join之間的時間間隔, 默認(rèn)是30s
-retry-max: 嘗試重復(fù)join的次數(shù), 默認(rèn)是0, 也就是無限次嘗試
-log-level: consul agent啟動后顯示的日志信息級別. 默認(rèn)是info, 可選: trace主之、debug衬以、info、warn缓苛、err.
-node: 節(jié)點在集群中的名稱, 在一個集群中必須是唯一的, 默認(rèn)是該節(jié)點的主機名
-protocol: consul使用的協(xié)議版本
-rejoin: 使consul忽略先前的離開, 在再次啟動后仍舊嘗試加入集群中.
-server: 定義agent運行在server模式, 每個集群至少有一個server, 建議每個集群的server不要超過5個
-syslog: 開啟系統(tǒng)日志功能, 只在linux/osx上生效
-pid-file: 提供一個路徑來存放pid文件, 可以使用該文件進行SIGINT/SIGHUP(關(guān)閉/更新)agent
按照慣例, 我們將配置文件放在/etc/consul.d/目錄下, 分別在幾個機器上創(chuàng)建該目錄. 在以bootstrap模式啟動的server1上, 我們創(chuàng)建/etc/consul.d/bootstrap和/etc/consul.d/server目錄, 在server2和server3上我們創(chuàng)建/etc/consul.d/server目錄, 在agent上, 我們創(chuàng)建/etc/consul.d/agent目錄.
server1的bootstrap目錄下的配置文件config.json如下:
{
"bootstrap": true,
"server": true,
"datacenter": "sh",
"data_dir": "/tmp/consul",
"advertise_addr":"192.168.11.11",
"encrypt": "aHN+s49W3Qyr73tjCayjCw==",
"log_level": "INFO",
"enable_syslog": true
}
其他兩臺服務(wù)器中server目錄下的配置文件config.json如下:
{
"bootstrap": false,
"server": true,
"datacenter": "sh",
"data_dir": "/tmp/consul",
"advertise_addr":"192.168.33.10",
"encrypt": "aHN+s49W3Qyr73tjCayjCw==",
"log_level": "INFO",
"enable_syslog": true,
"start_join": ["192.168.33.33","10.29.34.216","192.168.11.11"]
}
代理服務(wù)器中agent目錄下的config.json如下:
{
"server": true,
"datacenter": "sh",
"data_dir": "/tmp/consul",
"ui" : true,
"encrypt": "aHN+s49W3Qyr73tjCayjCw==",
"log_level": "INFO",
"advertise_addr":"10.29.34.216",
"addresses": {
"http": "0.0.0.0"
},
"enable_syslog": true
}
這樣, 首先啟動server1上的consul: consul agent -config-dir /etc/consul.d/bootstrap, 然后依次啟動server2, server3上的consul:consul agent -config-dir /etc/consul.d/server. 這樣, 三個consul server就組成了一個cluster. 此時server1上的consul運行在bootstrap狀態(tài)下. 可以在不與server2以及server3商議的情況下直接執(zhí)行決議, 此時我們終結(jié)server1上運行的consul, 并執(zhí)行consul agent -config-dir /etc/consul.d/server, 讓server1以普通server的身份重新加入cluster. 最后啟動agent模式 consul agent -config-dir /etc/consul.d/agent.
** 注意: encrypt可以使用consul keygen命令來生成, 所有服務(wù)器上需要配置一樣, 如果因為哪里配置錯誤導(dǎo)致啟動失敗, 修改后還報失敗的話, 可以嘗試刪除$data_dir/serf/local.keyring后重新啟動 **
發(fā)現(xiàn)服務(wù)
在需要部署服務(wù)的機器上同樣創(chuàng)建/etc/consul.d/, 然后把不同的服務(wù)分開不同的目錄, 或者就直接在此目錄下創(chuàng)建json配置文件, 如: web1.json, web2.json等.
然后再通過consul agent指定配置文件的方式啟動服務(wù), 可以直接在配置文件中指定要注冊的服務(wù), 也可以在啟動后使用consul join命令來主動注冊服務(wù), 這樣再次登錄到web管理界面就可以發(fā)現(xiàn)我們新建的服務(wù)了.
Q&A
Q: 什么是bootstrap模式?
A: 使用該模式啟動的server端會自動把自己選擇為leader, 在搭建集群時為了方便會預(yù)先設(shè)置一臺服務(wù)器為bootstrap啟動