由于文章太長,簡書放不下点骑,完整文檔見Consul文檔匾委。
一、安裝 Consul
Consul 的安裝很簡單诅炉,安裝 Consul 有以下兩種方式:
- 使用預編譯的二進制文件
- 使用源代碼安裝
下載一個預編譯的二進制文件是最簡單的蜡歹,我們通過TLS和SHA256總和提供下載來驗證二進制文件。 我們還分發(fā)了可以驗證的SHA256總和的PGP簽名涕烧。
1.1 預編譯的二進制文件
要安裝預編譯的二進制文件月而,請為您的系統(tǒng)下載相應的軟件包。 Consul目前打包成一個zip文件议纯。 我們近期沒有提供系統(tǒng)軟件包的計劃父款。
一旦zip被下載,解壓縮到任何目錄瞻凤。 內(nèi)部的Consul二進制文件是運行Consul(或者consul.exe for Windows)所必需的憨攒。 如果有任何額外的文件,請不需要運行Consul阀参。
將二進制文件復制到系統(tǒng)中的任何位置肝集。 如果您打算從命令行訪問它,請設置PATH環(huán)境變量蛛壳。
1.2 從源代碼編譯
要從源代碼編譯贩虾,您需要安裝并正確配置Go(包括GOPATH環(huán)境變量集)以及PATH中的git副本调限。
1.2.1 從GitHub克隆Consul資源庫到你的GOPATH中:
$ mkdir -p $GOPATH/src/github.com/hashicorp && cd $!
$ git clone https://github.com/hashicorp/consul.git
$ cd consul
1.2.2 引導項目憔四。 這將下載和編譯Consul所需的庫和工具:
$ make bootstrap
1.2.3 為你當前系統(tǒng)編譯Consul,并把二進制文件放入./bin/(相對于git checkout)勉痴。 make dev目標僅僅是一個快捷方式,只為您的本地構(gòu)建環(huán)境(沒有交叉編譯的目標)構(gòu)建Consul树肃。
$ make dev
1.3 安裝驗證
要確認Consul已正確安裝蒸矛,請在您的系統(tǒng)上運行consul -v
。 你應該看到幫助輸出胸嘴。 如果您正在從命令行執(zhí)行它雏掠,請確保已設置好PATH環(huán)境變量,否則您可能會收到Consul找不到的錯誤劣像。
[root@localhost ~]# consul -v
Consul v1.0.1
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
二乡话、Consul 升級
Consul是在任何參與Consul集群的節(jié)點上長期運行的代理。 這些節(jié)點一直相互通訊耳奕。 因此绑青,在使用Consul時,協(xié)議級別的兼容性和易于升級是一個重要的事項屋群。
下面介紹如何在新版本發(fā)布時升級Consul闸婴。
2.1 標準升級
為了升級,我們努力確保向后兼容性芍躏。 為了支持這個邪乍,建立了節(jié)點之間通訊協(xié)議的版本。 這使得客戶端和服務器能夠在可用時智能地啟用新功能对竣,否則將優(yōu)雅地退回到向后兼容的操作模式庇楞。
對于大多數(shù)升級,過程很簡單否纬。 假設Consul的當前版本是A吕晌,發(fā)布了版本B。
- 1临燃、在每臺服務器上安裝Consul版本B聂使。
- 2、關(guān)閉版本A谬俄,重新啟動版本B柏靶。
- 3、一旦所有服務器都升級完畢溃论,就開始按照相同的流程升級客戶端屎蜓。
- 4、完成钥勋! 你現(xiàn)在正在運行最新的Consul代理炬转。 您可以通過運行
consul members
來驗證這一點辆苔,以確保所有成員擁有最新版本和最高協(xié)議版本。
2.2 向后不兼容的升級
在某些情況下扼劈,可能會發(fā)布向后不兼容的更新驻啤。 這尚未成為問題,但為了支持升級荐吵,我們支持設置顯式協(xié)議版本骑冗。 這會禁用不兼容的功能并啟用兩階段升級。
對于下面的步驟先煎,假設你正在運行Consul版本A贼涩,然后發(fā)布了版本B。
- 1薯蝎、在每個節(jié)點上安裝Consul的B版本遥倦。
- 2、關(guān)閉版本A占锯,并使用
-protocol = PREVIOUS
選項啟動版本B袒哥,其中“PREVIOUS”是版本A的協(xié)議版本(可通過運行consul -v
或consul members
來獲取)消略。 - 3堡称、一旦所有節(jié)點都運行版本B,請遍歷每個節(jié)點并重新啟動沒有
-protocol
選項的版本B代理疑俭。 - 4、完成婿失! 你現(xiàn)在正在運行最新的Consul代理钞艇,并使用最新的協(xié)議。 您可以通過運行
consul members
來確認所有成員都使用同一個最新的協(xié)議版本豪硅。
做這項工作的關(guān)鍵是Consul的協(xié)議兼容性哩照。 協(xié)議版本系統(tǒng)在下面討論。
2.3 協(xié)議版本
默認情況下懒浮,Consul代理會說明最新的協(xié)議飘弧。 然而,如果有協(xié)議的變化砚著,每一個新版本的Consul也 會說明之前的協(xié)議次伶。
你可以通過運行consul -v
來查看你的Consul版本所能接受的協(xié)議版本。你會看到類似于下面的輸出:
[root@localhost ~]# consul -v
Consul v1.0.1
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
這顯示的是Consul的版本稽穆,以及這個代理使用和可以接受的協(xié)議版本冠王。
有時Consul會默認使用一個比它接受的更低的協(xié)議版本,以便與舊的代理兼容舌镶。 例如柱彻,接受版本3的Consul代理聲稱版本2豪娜,并且僅向接受版本3的代理發(fā)送版本3消息。這允許功能在代理升級時自動升級哟楷,并且是可能時使用的策略瘤载。 如果這是不可能的,那么您將需要使用上述說明進行不兼容的升級卖擅,并且在給定版本的說明中將清楚地列出這樣的要求鸣奔。
通過在consul代理上指定-protocol
選項,你可以告訴Consul代理使用任何可以理解的協(xié)議版本磨镶。 這只是指定協(xié)議版本溃蔫。 每一個Consul代理都可以隨時了解它在consul -v
上聲稱的所有協(xié)議版本。
通過運行以前的協(xié)議版本琳猫,Consul的某些功能伟叛,特別是較新的功能,可能無法使用脐嫂。 如果是這樣的話统刮,Consul通常會提醒你。 通常账千,您應該始終升級集群侥蒙,以便運行最新的協(xié)議版本。
三匀奏、協(xié)議兼容性承諾
我們希望Consul能夠運行在大批長期運營的代理身上鞭衩。 因為在這種環(huán)境下安全升級代理在很大程度上依賴于向后兼容性,所以我們強烈承諾保持不同Consul版本之間的協(xié)議兼容性娃善。
我們承諾论衍,Consul的每一個后續(xù)版本將保持向后兼容至少一個以前的版本。 具體地說:版本0.5可以說是0.4(反之亦然)聚磺,但可能不能說0.1坯台。
除非另有說明,向后兼容性是自動的瘫寝。Consul代理默認會使用最新的協(xié)議蜒蕾,但可以理解更早的協(xié)議。
注意:如果使用較早的協(xié)議焕阿,新功能可能無法使用咪啡。
Consul 使用較早的協(xié)議的能力是確保任何代理程序都可以升級而不會造成集群中斷。 Consul代理可以一次更新一個暮屡,一次一個版本瑟匆。
協(xié)議兼容性表
Consul版本 | 兼容協(xié)議 |
---|---|
0.1 - 0.3 | 1 |
0.4 | 1, 2 |
0.5 | 1, 2。 0.5.X服務器不能與舊服務器混合使用。 |
0.6 | 1, 2, 3 |
>= 0.7 | 2, 3愁溜。向兼容代理通訊時會自動使用協(xié)議> 2 |
注意:Raft協(xié)議是單獨版本疾嗅,但與至少一個以前的版本保持兼容。
四冕象、升級特定的版本
升級部分涵蓋了進行標準升級的細節(jié)代承。 但是,由于新功能或行為改變渐扮,Consul的特定版本可能會提供更多的升級細節(jié)论悴。 此處用于將這些詳細信息與標準升級流程分開記錄。
4.1 Consul 1.0.1
在升級過程中仔細檢查并刪除老的服務器墓律。
在使用Raft協(xié)議3運行時膀估,Consul 1.0(和Consul的早期版本)有一個問題,即執(zhí)行Consul服務器的滾動更新可能會導致集群中剩余的舊服務器中斷耻讽,自動控制系統(tǒng)通常會在新服務器聯(lián)機時刪除舊服務器察纯,但還等著將服務器推向成對的投票人,以維持一個奇數(shù)的法定人數(shù)针肥,這個成對的推廣功能被取消饼记,服務器一旦穩(wěn)定就成為選民,使得自動控制系統(tǒng)以更安全的方式移除舊服務器慰枕。
從Consul 1.0升級時具则,您可能需要手動force-leave
將舊服務器作為Consul 1.0.1滾動更新的一部分。
4.2 Consul 1.0
Consul 1.0這里記錄了幾個重要的重大改變具帮。升級前請務必閱讀所有的細節(jié)博肋。
Raft協(xié)議現(xiàn)在默認為3
-raft-protocol
默認值已從2更改為3,默認啟用所有自動控制功能蜂厅。
Raft協(xié)議版本3要求Consul在所有服務器上運行0.8.0或更高版本才能工作匪凡,所以如果您正在使用集群中較舊的服務器進行升級,則需要將其設置為2來升級葛峻。 有關(guān)更多詳細信息锹雏,請參閱Raft協(xié)議版本兼容 巴比。用最新的Raft協(xié)議運行時术奖,用于停機恢復的peers.json
的格式也是不同的。 請參閱手動恢復使用peers.json獲取所需格式的說明轻绞。
請注意采记,Raft協(xié)議與協(xié)議兼容性承諾頁面上介紹的Consul內(nèi)部協(xié)議不同,正如在consul members
和consul version
中所示政勃。要查看每臺服務器上使用的Raft協(xié)議的版本唧龄,請使用consul operator raft list-peers
命令。
升級服務器最簡單的方法是讓每臺服務器離開集群奸远,升級其Consul版本既棺,然后將其添加回來讽挟。 確保新服務器成功加入,并且在將升級前滾到下一個服務器之前丸冕,集群已經(jīng)穩(wěn)定耽梅。 也可以啟動一套新的服務器,然后以相似的方式慢慢地恢復每個舊的服務器上胖烛。
當使用Raft協(xié)議版本3時眼姐,當Consul對其內(nèi)部Raft仲裁配置進行更改時,服務器由-node-id標識佩番,而不是其IP地址众旗。 這意味著,一旦集群升級了所有運行Raft協(xié)議版本3的服務器趟畏,它將不再允許運行任何舊的Raft協(xié)議版本的服務器被添加贡歧。 如果運行一個單獨的Consul服務器,重新啟動它將導致該服務器無法將自己選為領導者拱镐。 為避免這種情況艘款,可以將Raft協(xié)議設置回2,或者使用手動恢復使用peers.json將服務器映射到Raft仲裁配置中的節(jié)點ID沃琅。
配置文件需要擴展名
作為支持Consul配置文件的HCL格式的一部分哗咆,Consul加載的所有配置文件都需要.hcl或.json擴展名,即使使用-config-file參數(shù)直接指定文件也是如此益眉。
已棄用的選項已被刪除
移除選項 | 替換選項 |
---|---|
-atlas | 沒有晌柬,Atlas不再支持。 |
-atlas-token | 沒有郭脂,Atlas不再支持年碘。 |
-atlas-join | 沒有,Atlas不再支持展鸡。 |
-atlas-endpoint | 沒有屿衅,Atlas不再支持。 |
-dc | -datacenter |
-retry-join-azure-tag-name | -retry-join |
-retry-join-azure-tag-value | -retry-join |
-retry-join-ec2-region | -retry-join |
-retry-join-ec2-tag-key | -retry-join |
-retry-join-ec2-tag-value | -retry-join |
-retry-join-gce-credentials-file | -retry-join |
-retry-join-gce-project-name | -retry-join |
-retry-join-gce-tag-name | -retry-join |
-retry-join-gce-zone-pattern | -retry-join |
addresses.rpc | 無莹弊,不再支持CLI命令的RPC服務器涤久。 |
advertise_addrs |
ports with advertise_addr and/or advertise_addr_wan
|
atlas_infrastructure | 沒有,Atlas不再支持忍弛。 |
atlas_token | 沒有响迂,Atlas不再支持。 |
atlas_acl_token | 沒有细疚,Atlas不再支持蔗彤。 |
atlas_join | 沒有,Atlas不再支持。 |
atlas_endpoint | 沒有然遏,Atlas不再支持贫途。 |
dogstatsd_addr | telemetry.dogstatsd_addr |
dogstatsd_tags | telemetry.dogstatsd_tags |
http_api_response_headers | http_config.response_headers |
ports.rpc | 無,不再支持CLI命令的RPC服務器待侵。 |
recursor | recursors |
retry_join_azure | -retry-join |
retry_join_ec2 | -retry-join |
retry_join_gce | -retry-join |
statsd_addr | telemetry.statsd_address |
statsite_addr | telemetry.statsite_address |
statsite_prefix | telemetry.metrics_prefix |
telemetry.statsite_prefix | telemetry.metrics_prefix |
(service definitions) serviceid | service_id |
(service definitions) dockercontainerid | docker_container_id |
(service definitions) tlsskipverify | tls_skip_verify |
(service definitions) deregistercriticalserviceafter | deregister_critical_service_after |
Consul先前不推薦使用的命令行標志和配置選項已被刪除潮饱,因此在升級之前需要將這些選項映射到它們的等價選項。 以下是已刪除選項及其等價選項的完整列表:
移除選項 | 替換選項 |
---|---|
-atlas | 沒有诫给,Atlas不再支持香拉。 |
-atlas-token | 沒有,Atlas不再支持中狂。 |
-atlas-join | 沒有凫碌,Atlas不再支持。 |
-atlas-endpoint | 沒有胃榕,Atlas不再支持盛险。 |
-dc | -datacenter |
-retry-join-azure-tag-name | -retry-join |
-retry-join-azure-tag-value | -retry-join |
-retry-join-ec2-region | -retry-join |
-retry-join-ec2-tag-key | -retry-join |
-retry-join-ec2-tag-value | -retry-join |
-retry-join-gce-credentials-file | -retry-join |
-retry-join-gce-project-name | -retry-join |
-retry-join-gce-tag-name | -retry-join |
-retry-join-gce-zone-pattern | -retry-join |
addresses.rpc | 無,不再支持CLI命令的RPC服務器勋又。 |
advertise_addrs |
ports with advertise_addr and/or advertise_addr_wan
|
atlas_infrastructure | 沒有苦掘,Atlas不再支持。 |
atlas_token | 沒有楔壤,Atlas不再支持鹤啡。 |
atlas_acl_token | 沒有,Atlas不再支持蹲嚣。 |
atlas_join | 沒有递瑰,Atlas不再支持。 |
atlas_endpoint | 沒有隙畜,Atlas不再支持抖部。 |
dogstatsd_addr | telemetry.dogstatsd_addr |
dogstatsd_tags | telemetry.dogstatsd_tags |
http_api_response_headers | http_config.response_headers |
ports.rpc | 無,不再支持CLI命令的RPC服務器议惰。 |
recursor | recursors |
retry_join_azure | -retry-join |
retry_join_ec2 | -retry-join |
retry_join_gce | -retry-join |
statsd_addr | telemetry.statsd_address |
statsite_addr | telemetry.statsite_address |
statsite_prefix | telemetry.metrics_prefix |
telemetry.statsite_prefix | telemetry.metrics_prefix |
(service definitions) serviceid | service_id |
(service definitions) dockercontainerid | docker_container_id |
(service definitions) tlsskipverify | tls_skip_verify |
(service definitions) deregistercriticalserviceafter | deregister_critical_service_after |
statsite_prefix
重命名為 metrics_prefix
由于應用于所有統(tǒng)計提供者的statsite_prefix配置選項慎颗,statsite_prefix已重命名為metrics_prefix。 升級到此版本的Consul時需要更新配置文件言询。
advertise_addrs
已被刪除
此配置選項已被刪除俯萎,因為它與advertise_addr和advertise_addr_wan結(jié)合使用端口冗余,并錯誤地指出您可以配置主機和端口倍试。
下線行為改變?yōu)間o-discover Configs
使用go-discover
云自動加入的-retry-join
和-retry-join-wan
值的格式已更改讯屈。 key = val序列中的值不能再進行URL編碼蛋哭,只要它們不包含空格县习,反斜杠或雙引號就可以作為文字提供。如果值包含這些字符,那么在"some key"= "some value"雙引號字符串中的特殊字符可以用反斜杠\轉(zhuǎn)義躁愿。
HTTP請求類型在許多HTTP API中被強制執(zhí)行
以前使用任何HTTP請求類型的HTTP API中的許多端點現(xiàn)在檢查特定的HTTP請求類型并強制執(zhí)行它們叛本。 這可能會破壞客戶依靠舊的行為。 以下是更新的端點和所需的HTTP請求類型的完整列表:
Endpoint | HTTP 請求類型 |
---|---|
/v1/acl/info | GET |
/v1/acl/list | GET |
/v1/acl/replication | GET |
/v1/agent/check/deregister | PUT |
/v1/agent/check/fail | PUT |
/v1/agent/check/pass | PUT |
/v1/agent/check/register | PUT |
/v1/agent/check/warn | PUT |
/v1/agent/checks | GET |
/v1/agent/force-leave | PUT |
/v1/agent/join | PUT |
/v1/agent/members | GET |
/v1/agent/metrics | GET |
/v1/agent/self | GET |
/v1/agent/service/register | PUT |
/v1/agent/service/deregister | PUT |
/v1/agent/services | GET |
/v1/catalog/datacenters | GET |
/v1/catalog/deregister | PUT |
/v1/catalog/node | GET |
/v1/catalog/nodes | GET |
/v1/catalog/register | PUT |
/v1/catalog/service | GET |
/v1/catalog/services | GET |
/v1/coordinate/datacenters | GET |
/v1/coordinate/nodes | GET |
/v1/health/checks | GET |
/v1/health/node | GET |
/v1/health/service | GET |
/v1/health/state | GET |
/v1/internal/ui/node | GET |
/v1/internal/ui/nodes | GET |
/v1/internal/ui/services | GET |
/v1/session/info | GET |
/v1/session/list | GET |
/v1/session/node | GET |
/v1/status/leader | GET |
/v1/status/peers | GET |
/v1/operator/area/:uuid/members | GET |
/v1/operator/area/:uuid/join | PUT |
未經(jīng)授權(quán)的KV請求返回403
啟用ACL時彤钟,使用未經(jīng)授權(quán)的令牌讀取密鑰將返回403.之前返回了404響應来候。
Agent自身端點的配置部分已更改
/v1/agent/self端點的Config部分經(jīng)常被直接返回Consul的內(nèi)部數(shù)據(jù)結(jié)構(gòu)之一。 這個配置結(jié)構(gòu)已經(jīng)在DebugConfig下移動了逸雹,并且是為了調(diào)試使用而隨時更改的文檔营搅,一小部分Config元素已經(jīng)被維護和記錄。 有關(guān)詳細信息梆砸,請參閱配置端點文檔转质。
已棄用的configtest命令已刪除
configtest命令已被棄用,并已由validate命令取代帖世。
驗證命令中的未記錄標志已刪除
validate命令支持-config-file和-config-dir命令行標志休蟹,但沒有記錄它們。 由于不需要標志日矫,所以這個支持已被刪除赂弓。
Metric名稱已更新
Metric名稱不再以consul.consul開頭。 為了幫助轉(zhuǎn)換儀表板和其他Metric消費者哪轿,enable_deprecated_names字段已經(jīng)添加到配置的遙測部分盈魁,這將使舊命名方案的Metric與新的一起發(fā)送。 以下前綴受到影響:
Prefix |
---|
consul.consul.acl |
consul.consul.autopilot |
consul.consul.catalog |
consul.consul.fsm |
consul.consul.health |
consul.consul.http |
consul.consul.kvs |
consul.consul.leader |
consul.consul.prepared-query |
consul.consul.rpc |
consul.consul.session |
consul.consul.session_ttl |
consul.consul.txn |
代理程序啟動時檢查已驗證
Consul代理現(xiàn)在驗證其配置中的運行狀況檢查定義窃诉,如果任何檢查無效备埃,將在啟動時失敗。 在之前的Consul版本中褐奴,無效健康檢查會被跳過离钝。
五同辣、Consul 內(nèi)部實現(xiàn)
這部分內(nèi)容涵蓋Consul內(nèi)部的一些內(nèi)容,如架構(gòu),一致性和 gossip協(xié)議立砸,以及安全模式。
注意:了解Consul的內(nèi)部是沒有必要成功地使用它久窟。 我們在這里記錄尉尾,對于Consul如何工作是完全透明的。
5.1 Consul 架構(gòu)
Consul是一個復雜的系統(tǒng)萌庆,有許多不同的靈活部件溶褪。 為了幫助Consul的用戶和開發(fā)人員了解 Consul 是如何運行的,該頁面記錄了系統(tǒng)架構(gòu)践险。
高級話題猿妈! 這個頁面涵蓋了Consul內(nèi)部的技術(shù)細節(jié)吹菱。 有效地運作和使用Consul不需要知道這些細節(jié)。 這些細節(jié)記錄在這里為那些誰想要了解他們彭则,而不需要通過源代碼進行探討鳍刷。
一些專用術(shù)語
在描述架構(gòu)之前,我們提供術(shù)語表來幫助澄清正在討論的內(nèi)容:
- Agent——Agent是Consul集群中每個成員長時間運行的守護進程俯抖。它是通過運行
consul agent
啟動的输瓜。Agent 可以運行在client
或server
模式。由于所有節(jié)點都必須運行一個agent芬萍,因此將節(jié)點稱為客戶端或服務器更簡單尤揣,但agent還有其他實例。所有agent都可以運行DNS或HTTP接口柬祠,并負責運行檢查和保持服務同步芹缔。 - Client——Client是將所有RPC轉(zhuǎn)發(fā)給服務器的agent。client是相對無狀態(tài)的瓶盛。client執(zhí)行的唯一后臺活動是參與局域網(wǎng)gossip池最欠。 這具有最小的資源開銷并且僅消耗少量的網(wǎng)絡帶寬。
- Server——Server是具有擴展職責的 agent惩猫,包括參與Raft仲裁芝硬,維護集群狀態(tài),響應RPC查詢轧房,通過廣域網(wǎng)的 gossip與其他數(shù)據(jù)中心通訊拌阴,以及將查詢轉(zhuǎn)發(fā)給leader或遠程數(shù)據(jù)中心。
- Datacenter——雖然數(shù)據(jù)中心的定義似乎是顯而易見的奶镶,但必須考慮一些細微的細節(jié)迟赃。例如,在EC2中厂镇,多個可用區(qū)域被認為是由一個數(shù)據(jù)中心組成的纤壁? 我們將數(shù)據(jù)中心定義為私有、低延遲和高帶寬的網(wǎng)絡環(huán)境捺信。 這不包括通過公共互聯(lián)網(wǎng)的通信酌媒,但為了我們的目的,單個EC2區(qū)域內(nèi)的多個可用區(qū)域?qū)⒈灰暈閱蝹€數(shù)據(jù)中心的一部分迄靠。
- Consensus——在我們的文檔中使用Consensus來表示對當選領導人的同意以及對交易順序的協(xié)議秒咨。由于這些事務被應用于有限狀態(tài)機,我們對Consensus的定義意味著復制狀態(tài)機的一致性掌挚。 Consensus在Wikipedia上有更詳細的描述雨席,我們的實現(xiàn)在這里描述。
- Gossip——Consul建立在Serf之上吠式,它提供了一個完整的gossip協(xié)議用于多種目的陡厘。 Serf提供會員資格抽米、失敗檢測和事件廣播。 在Gossip文檔中更多地描述了這些用法雏亚。 只要知道gossip涉及隨機的節(jié)點到節(jié)點的通信就足夠了,主要是通過UDP摩钙。
- LAN Gossip——指包含全部位于同一局域網(wǎng)或數(shù)據(jù)中心的節(jié)點的局域網(wǎng)gossip池罢低。
- WAN Gossip——指僅包含服務器的WAN gossip池。 這些服務器主要位于不同的數(shù)據(jù)中心胖笛,通常通過互聯(lián)網(wǎng)或廣域網(wǎng)進行通信网持。
- RPC——遠程過程調(diào)用。 這是一個請求/響應機制长踊,允許客戶端發(fā)出服務器請求功舀。
內(nèi)部架構(gòu)
從一萬英尺的高度來看,Consul的架構(gòu)是這樣的:
我們來分解這個圖像并且描述每一個部分身弊。 首先辟汰,我們可以看到有兩個數(shù)據(jù)中心,分別是“一”和“二”阱佛。 Consul對多個數(shù)據(jù)中心有一流的支持帖汞,并期望這是常見的情況。
在每個數(shù)據(jù)中心內(nèi)凑术,我們都有客戶端和服務器的混合翩蘸。 預計有三到五臺服務器。 這在故障情況下的可用性和性能之間取得平衡淮逊,因為隨著更多機器的添加催首,一致性逐漸變慢。 但是泄鹏,客戶數(shù)量沒有限制郎任,可以輕松擴展到數(shù)千或數(shù)萬。
數(shù)據(jù)中心內(nèi)的所有節(jié)點都參與到gossip協(xié)議中备籽。 這意味著有一個gossip池包含給定數(shù)據(jù)中心的所有節(jié)點涝滴。 這有幾個目的:首先,不需要為客戶端配置服務器的地址; 發(fā)現(xiàn)是自動完成的胶台。 其次歼疮,檢測節(jié)點故障的工作不是放在服務器上,而是分布式的诈唬。 這使得失敗檢測比原來的心跳計劃更具可擴展性韩脏。 第三,它被用作消息層來通知重要事件铸磅,例如發(fā)生 leader選舉赡矢。
每個數(shù)據(jù)中心中的服務器都是單個Raft對等設備的一部分杭朱。 這意味著他們一起工作,選出一個單獨的leader吹散。 leader負責處理所有查詢和交易弧械。 交易也必須復制到所有同行作為一致性協(xié)議的一部分。 由于這個要求空民,當一個非leader服務器接收到一個RPC請求時刃唐,它將其轉(zhuǎn)發(fā)給集群leader。
服務器節(jié)點也作為WAN gossip池的一部分運行界轩。 此池與局域網(wǎng)池不同画饥,因為它針對較高的互聯(lián)網(wǎng)延遲進行了優(yōu)化,預計只包含其他Consul服務器節(jié)點浊猾。 這個池的目的是讓數(shù)據(jù)中心以低調(diào)的方式發(fā)現(xiàn)彼此抖甘。 在線新建一個數(shù)據(jù)中心就像加入現(xiàn)有的廣域網(wǎng)gossip一樣簡單。 因為服務器都在這個池中運行葫慎,所以它也支持跨數(shù)據(jù)中心的請求衔彻。 當服務器接收到對其他數(shù)據(jù)中心的請求時,會將其轉(zhuǎn)發(fā)到正確的數(shù)據(jù)中心中的隨機服務器偷办。 該服務器可能會轉(zhuǎn)發(fā)給自己的 leader米奸。
這導致數(shù)據(jù)中心之間的耦合度非常低,但由于故障檢測爽篷,連接緩存和多路復用悴晰,跨數(shù)據(jù)中心的請求相對較快且可靠。
一般來說逐工,數(shù)據(jù)不會在不同的Consul數(shù)據(jù)中心之間復制铡溪。 當請求另一個數(shù)據(jù)中心中的資源時,本地Consul服務器將RPC請求轉(zhuǎn)發(fā)給該資源的遠程Consul服務器泪喊,并返回結(jié)果棕硫。 如果遠程數(shù)據(jù)中心不可用,那么這些資源也將不可用袒啼,但這不會影響本地數(shù)據(jù)中心哈扮。 有一些特殊情況,可以復制有限的數(shù)據(jù)子集蚓再,例如Consul的內(nèi)置ACL復制功能滑肉,或者外聯(lián)工具(如consul-replicate)。
深入研究
在這一點上摘仅,我們已經(jīng)介紹了Consul的高層架構(gòu)靶庙,但是每個子系統(tǒng)都有更多的細節(jié)。 與gossip協(xié)議一樣娃属, 一致性協(xié)議也有詳細文檔六荒。 所使用的安全模型和協(xié)議的文檔也是可用的护姆。
有關(guān)其他詳細信息,請查閱代碼掏击,在IRC中詢問卵皂,或者聯(lián)系郵件列表。
5.2 一致性協(xié)議
Consul使用一致性協(xié)議來提供一致性(由CAP定義)砚亭。一致性協(xié)議是基于“Raft:尋找一個可理解的一致性算法”灯变。 有關(guān)Raft的視覺解釋,請參閱數(shù)據(jù)的秘密生活钠惩。
Raft 協(xié)議概述
Raft是基于Paxos的一致性算法柒凉。與Paxos相比族阅,Raft被設計為具有更少的狀態(tài)和更簡單篓跛,更易于理解的算法。
在討論Raft時有幾個關(guān)鍵的術(shù)語:
- Log——Raft系統(tǒng)的主要工作單位是日志條目坦刀。 一致性問題可以分解為復制日志愧沟。 日志是條目的有序序列。 如果所有成員對條目和順序達成一致鲤遥,我們認為日志是一致的沐寺。
- FSM——有限狀態(tài)機。 有限狀態(tài)機是有限狀態(tài)的集合盖奈,它們之間有轉(zhuǎn)換混坞。 隨著新的日志被應用,F(xiàn)SM被允許在狀態(tài)之間轉(zhuǎn)換钢坦。 應用相同的日志序列必須導致相同的狀態(tài)究孕,這意味著行為必須是確定性的。
- Peer set——對等集是參與日志復制的所有成員的集合爹凹。 為了Consul的目的厨诸,所有服務器節(jié)點都在本地數(shù)據(jù)中心的對等集中。
- Quorum——法定人數(shù)是同行中的大多數(shù)成員:對于一組規(guī)模n禾酱,法定人數(shù)至少需要(n/2)+1個成員微酬。 例如,如果對等集中有5個成員颤陶,則需要3個節(jié)點來形成法定人數(shù)颗管。 如果由于某種原因?qū)е路ǘ〝?shù)量的節(jié)點不可用,則集群變得不可用滓走,并且不能提交新的日志忙上。
- Committed Entry——當一個條目持久地存儲在一個法定的節(jié)點上時,這個條目被認為是提交的闲坎。 一旦條目被提交疫粥,就可以應用茬斧。
- Leader——在任何給定的時間,對等組選擇單個節(jié)點作為領導者梗逮。 領導者負責接收新的日志條目项秉,復制到關(guān)注者,以及管理條目何時被提交慷彤。
Raft是一個復雜的協(xié)議娄蔼,在這里不會詳細介紹(對于那些希望得到更全面了解的人,這篇文章有更詳細介紹)底哗。但是岁诉,我們會試圖提供一個高層次的描述,這對于建立一個總體的認識可能是有用的跋选。
Raft 節(jié)點處于三種狀態(tài)之一:follower, candidate, leader涕癣。所有節(jié)點最初都是作為follower開始的。在這個狀態(tài)下前标,節(jié)點可以接受 leader 的日志條目和投票坠韩。如果一段時間內(nèi)沒有收到條目,則節(jié)點自我提升到candidate狀態(tài)炼列。在candidate狀態(tài)只搁,節(jié)點向同伴請求投票。如果candidate獲得法定人數(shù)俭尖,則提升為 leader氢惋。leader 必須接受新的日志條目并且復制到其它的 follower 上。另外稽犁,如果陳舊的數(shù)據(jù)不可接受焰望,則所有的查詢也必須在 leader 上進行。
一旦一個集群有一個 leader缭付,它就能接受新的日志條目柿估。客戶端可以請求 leader 增加一個新的日志條目(從 Raft 角度來看陷猫,日志條目是一個不透明的二進制 blob)秫舌。然后,leader將條目寫入持久存儲绣檬,并嘗試復制到其它的 follower 上面足陨。一旦日志條目被認為是提交的,它可以應用到有限狀態(tài)機娇未。有限狀態(tài)機是應用程序特定的墨缘;在 Consul 里,我們使用MemDB去維護集群的狀態(tài)。Consul 在 committed 和 applied 時會進行寫阻塞镊讼。在與查詢的一致模式一起使用時宽涌,這實現(xiàn)了在寫入語義之后的讀取。
顯然蝶棋,允許日志復制無限制的增長是不可取的卸亮。Raft 提供了一種機制,通過該機制玩裙,當前狀態(tài)被快照并且日志被壓縮兼贸。由于FSM抽象,恢復FSM的狀態(tài)必須導致與舊日志重播相同的狀態(tài)吃溅。這允許Raft在某個時間點捕獲FSM狀態(tài)溶诞,然后刪除所有用來達到該狀態(tài)的日志。這是在沒有用戶干預的情況下自動執(zhí)行的决侈,并且可以防止無限制的磁盤使用螺垢,同時最大限度地減少重新使用日志的時間。使用BoltDB的好處之一是它允許Consul繼續(xù)接受新的事務颜及,即使在舊狀態(tài)被快照時甩苛,也防止了任何可用性問題蹂楣。
一致性直到到達法定人數(shù)都是容錯的俏站。如果法定人數(shù)的節(jié)點不可用,則是無法處理日志條目和同伴成員的理由痊土。例如:假設只有兩個對等體 A 和 B肄扎。則法定人數(shù)大小就是2,這意味著兩個節(jié)點必須同意提交日志條目赁酝。如果 A 或 B 失敗犯祠,現(xiàn)在不可能達到法定人數(shù)。這意味著集群無法添加或刪除節(jié)點或提交任何其他日志條目酌呆。這導致不可用衡载。此時,需要手動干預來移除 A 或 B隙袁,并且在引導模式下重新啟動剩余的節(jié)點痰娱。
3個節(jié)點的 Raft 集群可以容忍單個節(jié)點故障,而5個節(jié)點的集群可以容忍2個節(jié)點故障菩收。推薦的配置是每個數(shù)據(jù)中心配置3或5個 Consul 服務器梨睁。這最大限度地提高可用性,而不會大大犧牲性能娜饵。下面的部署表總結(jié)了潛在的集群大小和每個集群的容錯坡贺。
在性能方面,Raft 與Paxos相當。假設穩(wěn)定的領導遍坟,提交日志條目需要一次往返一半的群集拳亿。 因此,性能受到磁盤I / O和網(wǎng)絡延遲的限制愿伴。盡管Consul并不是一個高吞吐量的寫入系統(tǒng)风瘦,但它依賴于網(wǎng)絡和硬件配置,每秒處理數(shù)百到數(shù)千個事務公般。
Consul 里的 Raft
只有Consul服務器節(jié)點參與Raft并且是對等集合的一部分万搔。所有客戶端節(jié)點都向服務器轉(zhuǎn)發(fā)請求。這種設計的部分原因是官帘,隨著更多的成員被添加到對等設置瞬雹,法定數(shù)量的大小也增加。 這會引起性能問題刽虹,因為您可能正在等待數(shù)百臺機器同意進入而不是少數(shù)幾臺機器酗捌。
開始時,一個Consul服務器被置于“bootstrap”模式涌哲。這種模式可以讓自己當選領導者胖缤。 一旦領導者被選舉出來,其他服務器可以被添加到對等組中阀圾,以保持一致性和安全性哪廓。 最后,一旦添加了前幾個服務器初烘,引導模式可以被禁用涡真。更詳細的介紹參考這個文檔
。
由于所有服務器都作為對等設備的一部分參與肾筐,他們都知道當前的領導者哆料。 當RPC請求到達非領導服務器時,請求被轉(zhuǎn)發(fā)給領導吗铐。 如果RPC是查詢類型东亦,意味著它是只讀的,那么領導者將根據(jù)FSM的當前狀態(tài)生成結(jié)果唬渗。 如果RPC是一個事務類型典阵,這意味著它修改了狀態(tài),那么領導者會生成一個新的日志條目并使用Raft來應用它谣妻。 一旦日志條目被提交并應用到FSM萄喳,交易就完成了。
由于Raft復制的性質(zhì)蹋半,性能對網(wǎng)絡延遲很敏感他巨。 出于這個原因,每個數(shù)據(jù)中心選擇一個獨立的領導者,并維護一個不相交的對等集染突。 數(shù)據(jù)由數(shù)據(jù)中心分區(qū)捻爷,因此每個領導者只負責數(shù)據(jù)中心的數(shù)據(jù)。 當收到遠程數(shù)據(jù)中心的請求時份企,請求被轉(zhuǎn)發(fā)給正確的領導也榄。 這種設計允許更低的延遲交易和更高的可用性而不犧牲一致性。
一致性模式
盡管所有對復制日志的寫入都是通過Raft進行的司志,但讀取更靈活甜紫。 為了支持開發(fā)人員可能需要的各種權(quán)衡怯邪,Consul支持3種不同的讀取一致性模式犁功。
三種讀取模式是:
- default。參考這篇文章為 Raft 引入 leader lease 機制解決集群腦裂時的 stale read 問題巢音。
- consistent激才。這種模式是非常一致的拓型,沒有告誡。 它要求一個領導者與一個同事的法定人數(shù)進行核實瘸恼,它仍然是領導者劣挫。 這引入了所有服務器節(jié)點的額外往返。 折衷總是一致的讀取东帅,但由于額外的往返導致延遲增加压固。
- stale。這種模式允許任何服務器為讀取服務冰啃,而不管它是否是領導者邓夕。 這意味著讀取可以任意陳舊刘莹,但通常在領導者的50毫秒內(nèi)阎毅。 權(quán)衡是非常快速和可擴展的讀取点弯,但陳舊的價值扇调。 這種模式允許沒有領導者的讀取意味著不可用的集群仍然能夠響應。
有關(guān)使用這些不同模式的更多文檔抢肛,參考HTTP API狼钮。
部署表
以下是顯示各種群集大小的法定大小和容錯的表格。 推薦的部署是3或5個服務器捡絮。 一個單一的服務器部署是非常不鼓勵的熬芜,因為在故障情況下數(shù)據(jù)丟失是不可避免的。
Servers | Quorum Size | Failure Tolerance |
---|---|---|
1 | 1 | 0 |
2 | 2 | 0 |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
7 | 4 | 3 |
5.3 Gossip Protocol
Consul使用Gossip Protocol來管理成員資格并向集群廣播消息福稳。所有這些都是通過使用Serf庫提供的涎拉。Serf使用的Gossip Protocol是基于"SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol",并進行了一些小修改。Serf's protocol詳情請看這里鼓拧。
Gossip in Consul
領事使用兩個不同的gossip池半火。 我們將每個池分別稱為LAN或WAN池。 每個Consul運行的數(shù)據(jù)中心都有一個包含數(shù)據(jù)中心所有成員(包括客戶端和服務器)的LAN gossip池季俩。 LAN池用于幾個目的钮糖。 成員信息允許客戶端自動發(fā)現(xiàn)服務器,減少所需的配置量酌住。 分布式故障檢測允許整個集群共享故障檢測工作店归,而不是集中在幾臺服務器上。 最后酪我,gossip池允許可靠和快速的事件廣播娱节,如領導人選舉事件。
WAN池是全球唯一的祭示,因為無論數(shù)據(jù)中心如何肄满,所有服務器都應該參與WAN池。 WAN池提供的成員資格信息允許服務器執(zhí)行跨數(shù)據(jù)中心請求质涛。 集成的故障檢測功能使Consul可以正常處理丟失連接的整個數(shù)據(jù)中心稠歉,或者只處理遠程數(shù)據(jù)中心內(nèi)的單個服務器。
所有這些功能都是利用Serf提供的汇陆。 它被用作嵌入式庫來提供這些功能怒炸。 從用戶的角度來看,這并不重要毡代,因為抽象應該被Consul所掩蓋阅羹。 作為一名開發(fā)人員,了解這個庫如何被利用是非常有用的教寂。
Lifeguard Enhancements
SWIM假定本地節(jié)點是健康的捏鱼,因為軟實時處理包是可能的。 但是酪耕,如果本地節(jié)點遇到CPU或網(wǎng)絡耗盡导梆,則可能違反此假設。 其結(jié)果是迂烁,serfHealth檢查狀態(tài)可能會偶爾發(fā)生抖動看尼,導致錯誤的監(jiān)視警報,增加了遙測的噪聲盟步,并導致整個群集浪費CPU和網(wǎng)絡資源來診斷可能不存在的故障藏斩。
Lifeguard通過SWIM的新型增強完全解決這個問題。
有關(guān)Lifeguard的更多詳情却盘,請閱讀Making Gossip More Robust with Lifeguard這篇博客文章狰域,其中提供了HashiCorp研究論文的高級概述Lifeguard : SWIM-ing with Situational Awareness窜觉。Serf gossip protocol guide還提供了有關(guān)gossip protocol 和 Lifeguard的一些較低層次的細節(jié)。
5.4 Network Coordinates
Consul使用網(wǎng)絡層析成像系統(tǒng)來計算集群中節(jié)點的網(wǎng)絡坐標北专。 這些坐標允許使用非常簡單的計算在任何兩個節(jié)點之間估計網(wǎng)絡往返時間禀挫。 這允許許多有用的應用程序,例如查找離請求節(jié)點最近的服務節(jié)點拓颓,或者故障轉(zhuǎn)移到下一個最近的數(shù)據(jù)中心中的服務语婴。
所有這些都是通過使用Serf庫提供的。 Serf的網(wǎng)絡層析成像基于"Vivaldi: A Decentralized Network Coordinate System"驶睦,并基于其他研究進行了一些改進砰左。 這里有關(guān)于Serf的網(wǎng)絡坐標的更多細節(jié)。
Network Coordinates in Consul
Consul內(nèi)部的網(wǎng)絡坐標清單有幾種形式:
- consul rtt命令可用于查詢?nèi)我鈨蓚€節(jié)點之間的網(wǎng)絡往返時間场航。
- 目錄端點和運行狀況端點可以使用"?near="參數(shù)根據(jù)給定節(jié)點的網(wǎng)絡往返時間對查詢結(jié)果進行排序缠导。
- 準備好的查詢可以根據(jù)網(wǎng)絡往返時間自動將服務故障轉(zhuǎn)移到其他Consul數(shù)據(jù)中心。 有關(guān)示例溉痢,請參閱地理故障轉(zhuǎn)移僻造。
-
坐標端點顯示原始網(wǎng)絡坐標以用于其他應用程序。
Consul使用Serf來管理兩個不同的gossip池孩饼,一個是給定數(shù)據(jù)中心成員的局域網(wǎng)髓削,另一個是由所有數(shù)據(jù)中心的Consul服務器組成的WAN。 請注意镀娶,這兩個池之間的網(wǎng)絡坐標不兼容立膛。 局域網(wǎng)坐標只有在與其他局域網(wǎng)坐標進行計算時才有意義,而廣域網(wǎng)坐標只對其他廣域網(wǎng)坐標有意義梯码。
使用坐標
一旦有了它們的坐標宝泵,計算任何兩個節(jié)點之間估計的網(wǎng)絡往返時間就很簡單。 以下是從坐標端點返回的示例坐標轩娶。
"Coord": {
"Adjustment": 0.1,
"Error": 1.5,
"Height": 0.02,
"Vec": [0.34,0.68,0.003,0.01,0.05,0.1,0.34,0.06]
}
所有值都是以秒為單位的浮點數(shù)儿奶,除了不用于距離計算的誤差項。
Go中有一個完整的例子罢坝,展示了如何計算兩個坐標之間的距離:
import (
"math"
"time"
"github.com/hashicorp/serf/coordinate"
)
func dist(a *coordinate.Coordinate, b *coordinate.Coordinate) time.Duration {
// Coordinates will always have the same dimensionality, so this is
// just a sanity check.
if len(a.Vec) != len(b.Vec) {
panic("dimensions aren't compatible")
}
// Calculate the Euclidean distance plus the heights.
sumsq := 0.0
for i := 0; i < len(a.Vec); i++ {
diff := a.Vec[i] - b.Vec[i]
sumsq += diff * diff
}
rtt := math.Sqrt(sumsq) + a.Height + b.Height
// Apply the adjustment components, guarding against negatives.
adjusted := rtt + a.Adjustment + b.Adjustment
if adjusted > 0.0 {
rtt = adjusted
}
// Go's times are natively nanoseconds, so we convert from seconds.
const secondsToNanoseconds = 1.0e9
return time.Duration(rtt * secondsToNanoseconds)
}
5.5 Sessions
Consul提供了一個可用于構(gòu)建分布式鎖的會話機制廓握。 會話充當節(jié)點之間的綁定層,運行狀況檢查和鍵/值數(shù)據(jù)嘁酿。 它們旨在提供細粒度鎖定,并深受The Chubby Lock Service for Loosely-Coupled Distributed Systems的啟發(fā)男应。
Session Design
Consul中的一個會話代表一個具有非常特定語義的合約闹司。 當構(gòu)建會話時,可以提供節(jié)點名稱沐飘,健康檢查列表游桩,行為牲迫,TTL和鎖定延遲。 新構(gòu)建的會話提供了一個可用于標識的命名標識借卧。 該ID可以與KV存儲一起使用以獲取鎖定:用于相互排斥的咨詢機制盹憎。
以下是顯示這些組件之間的關(guān)系的圖表:
Consul所提供的合約,在下列情況下铐刘, 會話將失效:
- 節(jié)點被注銷
- 任何健康檢查被取消注冊
- 任何健康檢查進入臨界狀態(tài)
- 會話被明確銷毀
- TTL到期陪每,如果適用
當會話失效時,會話被破壞镰吵,不能再使用檩禾。 關(guān)聯(lián)的鎖發(fā)生什么取決于在創(chuàng)建時指定的行為。 Consul支持發(fā)布和刪除行為疤祭。 如果沒有指定盼产,則釋放行為是默認行為。
如果正在使用釋放行為勺馆,則釋放與該會話關(guān)聯(lián)的任何鎖戏售,并且該密鑰的ModifyIndex遞增。 或者草穆,如果使用刪除行為蜈项,則簡單地刪除與任何保持鎖相對應的密鑰。 這可以用來創(chuàng)建Consul自動刪除的臨時條目续挟。
雖然這是一個簡單的設計紧卒,但卻可以實現(xiàn)多種使用模式。 默認情況下诗祸,基于gossip的故障檢測器被用作關(guān)聯(lián)的健康檢查跑芳。 這個失敗檢測器允許Consul檢測一個正在鎖定的節(jié)點何時失敗并自動釋放鎖定。 這種能力為Consul鎖提供活力直颅。 即在失敗的情況下博个,系統(tǒng)可以繼續(xù)取得進展。 但是功偿,由于沒有完美的故障檢測器盆佣,所以即使鎖擁有者仍然活著,也可能產(chǎn)生誤報(檢測到故障)械荷,從而導致鎖被釋放共耍。 這意味著我們正在犧牲一些安全。
相反吨瞎,可以創(chuàng)建沒有關(guān)聯(lián)健康檢查的會話痹兜。 這消除了假陽性的可能性,并且為了安全而進行交易颤诀。 你絕對可以肯定字旭,即使現(xiàn)有業(yè)主失敗对湃,Consul也不會解鎖。 由于Consul API允許會話強制銷毀遗淳,因此可以構(gòu)建系統(tǒng)拍柒,在發(fā)生故障的情況下需要操作員進行干預,同時排除了腦裂的可能性屈暗。
第三種健康檢查機制是會話TTL拆讯。 創(chuàng)建會話時,可以指定TTL恐锦。 如果TTL時間間隔過期而沒有更新往果,則會話已經(jīng)過期并觸發(fā)失效。 這種類型的故障檢測器也被稱為心跳故障檢測器一铅。 它比基于gossip的故障檢測器的可擴展性低陕贮,因為它增加了對服務器的負擔,但在某些情況下可能適用潘飘。 TTL的合同是代表失效的下限; 也就是說Consul在達到TTL之前不會過期會話肮之,但是允許延遲超過TTL的期限。 TTL在會話創(chuàng)建卜录,會話更新和領導者故障切換時被更新戈擒。 使用TTL時,客戶端應該了解時鐘偏移問題:即客戶端上的時間不能像Consul服務器上那樣以相同的速率進行艰毒。 最好設置保守的TTL值筐高,并在TTL之前更新以解決網(wǎng)絡延遲和時間偏差。
最后的細微差別是會話可能會提供鎖定延遲丑瞧。 這是一個持續(xù)時間柑土,介于0到60秒之間。 當會話失效發(fā)生時绊汹,Consul防止在鎖定延遲時間間隔內(nèi)重新獲得之前保存的任何鎖定; 這是Google的Chubby所鼓舞的保障稽屏。 這種延遲的目的是讓潛在的現(xiàn)場領導者檢測到失效并停止處理可能導致不一致狀態(tài)的請求。 雖然不是一個防彈的方法西乖,但它確實避免了將睡眠狀態(tài)引入到應用程序邏輯中的需要狐榔,并且可以幫助減輕許多問題。 默認情況下是使用15秒的延遲获雕,客戶端可以通過提供零延遲值來禁用此機制薄腻。
K/V集成
KV存儲和會話之間的整合是會話使用的主要場所。 會話必須在使用之前創(chuàng)建典鸡,然后通過其ID來引用被廓。
KV API被擴展為支持獲取和發(fā)布操作。 獲取操作的行為類似于“檢查和設置”操作萝玷,只有在沒有現(xiàn)有鎖持有者(當前鎖持有者可以重新獲取嫁乘,見下文)時才能成功。 成功時球碉,會有一個正常的密鑰更新蜓斧,但LockIndex也有一個增量,Session值會更新以反映持有該鎖的會話睁冬。
如果在獲取期間鎖已經(jīng)被給定的會話持有挎春,那么LockIndex不會遞增,而是關(guān)鍵內(nèi)容被更新豆拨。 這使得當前鎖持有者可以更新關(guān)鍵內(nèi)容直奋,而不必放棄鎖并重新獲取它。
一旦舉行施禾,鎖可以釋放使用相應的釋放操作脚线,提供相同的會話。 再次弥搞,這就像一個檢查和設置操作邮绿,因為如果給定一個無效的會話,請求將失敗攀例。 一個重要的注意事項是鎖可以被釋放船逮,而不是會話的創(chuàng)建者。 這是設計上的粤铭,因為它允許運營商進行干預挖胃,并在必要時強制終止會話。 如上所述梆惯,會話失效也會導致所有持有的鎖被釋放或刪除酱鸭。 當一個鎖被釋放時,LockIndex不會改變; 但是加袋,會話被清除并且ModifyIndex遞增凛辣。
這些語義(大量借用Chubby)允許(Key,LockIndex职烧,Session)的元組作為唯一的“音序器”扁誓。 該順控程序可以被傳遞并用于驗證請求是否屬于當前鎖持有者。 因為每次獲取都會增加LockIndex蚀之,即使同一個會話重新獲取一個鎖蝗敢,排序器也能夠檢測到一個陳舊的請求。 同樣足删,如果一個會話是無效的寿谴,與給定的LockIndex對應的Session將是空白的。
要清楚的是失受,這個鎖定系統(tǒng)是純粹的咨詢讶泰。 沒有強制執(zhí)行咏瑟,客戶必須獲得一個鎖來執(zhí)行任何操作。 任何客戶端都可以讀取痪署,寫入和刪除一個密鑰码泞,而不必擁有相應的鎖。 領事的目標不是保護不當客戶狼犯。
Leader Election
會話提供的原語和KV存儲的鎖定機制可用于構(gòu)建客戶端領導者選舉算法余寥。 這些在leader選舉指南中有更詳細的介紹。
Prepared Query Integration
準備好的查詢可以附加到會話中悯森,以便在會話失效時自動刪除準備好的查詢宋舷。
5.6 Anti-Entropy
Consul使用維護服務和健康信息的先進方法。本頁詳細介紹了如何注冊服務和檢查瓢姻,如何填充目錄以及在更改時更新健康狀態(tài)信息的方式祝蝠。
組件
首先要了解服務和健康檢查中涉及的組件:Agent和catalog。這些在下面的概念描述汹来,使Anti-Entropy更容易理解续膳。
Agent
每個Consul Agent維護自己的一套服務和檢查注冊以及健康信息。Agent負責執(zhí)行自己的健康檢查并更新其本地狀態(tài)收班。
Agent上下文中的服務和檢查具有豐富的可用配置選項坟岔。 這是因為Agent負責通過使用健康檢查來生成關(guān)于其服務及其健康的信息。
Catalog
Consul的服務發(fā)現(xiàn)由服務目錄支持摔桦。該目錄是通過匯總Agent提交的信息而形成的社付。該目錄維護集群的高級視圖,包括哪些服務可用邻耕,哪些節(jié)點運行這些服務鸥咖,健康信息等等。該目錄用于通過Consul提供的各種接口公開這些信息兄世,包括DNS和HTTP啼辣。
與Agent相比,目錄上下文中的服務和檢查具有更為有限的一組字段御滩。 這是因為該目錄僅負責記錄和返回有關(guān)服務鸥拧,節(jié)點和運行狀況的信息。
該目錄僅由服務器節(jié)點維護削解。這是因為目錄是通過Raft日志復制的富弦,以提供對集群的統(tǒng)一和一致的視圖。
Anti-Entropy
熵是系統(tǒng)日益混亂的趨勢氛驮。Consul的反熵機制旨在對付這種趨勢腕柜,甚至通過其組成部分的失敗來保持集群的狀態(tài)。
如上所述,Consul在全局目錄和Agent 本地之間有明確的分離盏缤。反熵機制調(diào)和了這兩種世界觀:反熵是本地Agent與目錄的同步砰蠢。 例如,當用戶注冊新服務或與Agent核對時蛾找,Agent會依次通知目錄該新的支票存在娩脾。 同樣赵誓,從代理中刪除支票時打毛,也會從目錄中刪除支票。
反熵也被用來更新可用性信息俩功。 當代理商運行健康檢查時幻枉,他們的狀態(tài)可能會改變,在這種情況下诡蜓,他們的新狀態(tài)將被同步到目錄中熬甫。 使用這些信息,目錄可以根據(jù)其可用性蔓罚,智能地響應有關(guān)其節(jié)點和服務的查詢椿肩。
在此同步過程中,還會檢查目錄的正確性豺谈。 如果目錄中存在Agent不知道的任何服務或檢查郑象,它們將被自動刪除,以使目錄反映該Agent的適當?shù)囊唤M服務和運行狀況信息茬末。 Consul將Agent的狀態(tài)視為權(quán)威厂榛;如果Agent和目錄視圖之間有任何差異,則將始終使用Agent本地視圖丽惭。
定期同步
除了在對Consul進行更改時運行外击奶,反熵也是一個長期運行的過程,它會定期喚醒以同步服務并檢查目錄中的狀態(tài)责掏。 這可以確保目錄與Agent的真實狀態(tài)緊密匹配柜砾。 這也使Consul能夠重新填充服務目錄,即使在數(shù)據(jù)丟失的情況下也是如此换衬。
為避免飽和痰驱,定期反熵運行之間的時間量將根據(jù)集群大小而變化。 下表定義了集群大小和同步間隔之間的關(guān)系:
Cluster Size | Periodic Sync Interval |
---|---|
1 - 128 | 1 minute |
129 - 256 | 2 minutes |
257 - 512 | 3 minutes |
513 - 1024 | 4 minutes |
... | ... |
上面的時間間隔是近似的冗疮。每個Consul代理將在間隔窗口內(nèi)選擇一個隨機錯開的開始時間萄唇,以避免雷鳴般的牛群。
盡力而為的同步
在一些情況下术幔,反熵可能會失敗另萤,包括代理程序或其運行環(huán)境配置錯誤,I / O問題(完整磁盤,文件系統(tǒng)權(quán)限等)四敞,網(wǎng)絡問題(代理程序無法與服務器通信)等等泛源。 因此,代理嘗試以盡力而為的方式進行同步忿危。
如果在反熵運行期間遇到錯誤达箍,則會記錄錯誤,并且代理繼續(xù)運行铺厨。 定期運行反熵機制以自動從這些類型的瞬態(tài)故障中恢復缎玫。
EnableTagOverride
服務注冊的同步可以被部分修改以允許外部代理改變服務的標簽。 這在外部監(jiān)視服務需要成為標簽信息的真實來源的情況下非常有用解滓。 例如赃磨,Redis數(shù)據(jù)庫及其監(jiān)控服務Redis Sentinel就有這種關(guān)系。 Redis實例負責其大部分配置洼裤,但Sentinel確定Redis實例是主要還是次要實例邻辉。 使用Consul服務配置項EnableTagOverride,您可以指示運行Redis數(shù)據(jù)庫的Consul代理在反熵同步期間不更新標簽腮鞍。 有關(guān)更多信息值骇,請參閱服務頁面。
5.7 安全模型
Consul依靠輕量級gossip機制和RPC系統(tǒng)來提供各種功能移国。這兩個系統(tǒng)都有不同的安全機制吱瘩。然而监徘,Consul的安全機制有一個共同的目標:提供機密性操软,完整性和認證。
gossip協(xié)議由Serf提供支持伟葫,Serf使用對稱密鑰或共享密鑰加密系統(tǒng)裹芝。 這里有更多關(guān)于Serf安全的細節(jié)部逮。 有關(guān)如何在Consul中啟用Serf的gossip加密的詳細信息,請參閱此處的加密文檔嫂易。
RPC系統(tǒng)支持使用端對端的TLS和可選的客戶端認證兄朋。 TLS是廣泛部署的非對稱密碼系統(tǒng),是網(wǎng)絡安全的基礎怜械。
這意味著Consul溝通是防止竊聽颅和,篡改和欺騙。 這使得Consul可以通過不受信任的網(wǎng)絡(如EC2和其他共享主機提供商)運行缕允。
威脅模型
以下是我們的威脅模型的各個部分:
- 非會員可以訪問數(shù)據(jù)
- 由于惡意消息而導致集群狀態(tài)操作
- 由于惡意消息而產(chǎn)生假數(shù)據(jù)
- 篡改造成國家腐敗
- 針對節(jié)點的拒絕服務
另外峡扩,我們認識到,可以長時間觀察網(wǎng)絡流量的攻擊者可以推斷集群成員障本。 Consul使用的gossip機制依賴于向隨機成員發(fā)送消息教届,因此攻擊者可以記錄所有目標并確定群集的所有成員响鹃。
在將安全性設計為系統(tǒng)時,將其設計為適合威脅模型案训。 我們的目標不是保護絕密數(shù)據(jù)买置,而是提供一個“合理的”安全級別,要求攻擊者投入大量的資源來擊敗强霎。
網(wǎng)絡端口
有關(guān)配置網(wǎng)絡規(guī)則以支持Consul忿项,請參閱Consul使用的端口列表以及使用哪些功能的詳細信息。
5.8 Jepsen Testing
Jepsen是由Kyle Kingsbury編寫的一個工具城舞,旨在測試分布式系統(tǒng)的分區(qū)容差轩触。 它創(chuàng)建網(wǎng)絡分區(qū),同時隨機操作模糊系統(tǒng)椿争。 分析結(jié)果怕膛,看看系統(tǒng)是否違反了它聲稱擁有的任何一致性屬性。
作為我們Consul測試的一部分秦踪,我們運行了一個Jepsen測試來確定是否可以發(fā)現(xiàn)任何一致性問題。 在我們的測試中掸茅,Consul從分區(qū)中恢復正常椅邓,沒有引入任何一致性問題。
Running the tests
目前昧狮,使用Jepsen進行測試相當復雜景馁,因為它需要設置多個虛擬機,SSH密鑰逗鸣,DNS配置以及一個可用的Clojure環(huán)境合住。 我們希望盡快為我們的Consul測試代碼貢獻一份測試代碼,并為Jepsen測試提供一個Vagrant環(huán)境撒璧。
Output
以下是Jepsen的輸出透葛。 我們多次跑Jepsen,每次都是通過的卿樱。 這個輸出僅代表一次運行僚害。
六、Consul命令(CLI)
見Consul命令(CLI)繁调,太長簡書放不下萨蚕。