Consul 入门指南
一、安裝 Consul
Consul 下載地址:https://www.consul.io/downloads.html,下載后解壓就是一個可執行的二進制文件consul,配置好環境變量,檢查 consul 是否可用:
[root@localhost ~]# consul Usage: consul [--version] [--help] <command> [<args>]Available commands are:agent Runs a Consul agentcatalog Interact with the catalogevent Fire a new eventexec Executes a command on Consul nodesforce-leave Forces a member of the cluster to enter the "left" stateinfo Provides debugging information for operators.join Tell Consul agent to join clusterkeygen Generates a new encryption keykeyring Manages gossip layer encryption keyskv Interact with the key-value storeleave Gracefully leaves the Consul cluster and shuts downlock Execute a command holding a lockmaint Controls node or service maintenance modemembers Lists the members of a Consul clustermonitor Stream logs from a Consul agentoperator Provides cluster-level tools for Consul operatorsreload Triggers the agent to reload configuration filesrtt Estimates network round trip time between nodessnapshot Saves, restores and inspects snapshots of Consul server statevalidate Validate config files/directoriesversion Prints the Consul versionwatch Watch for changes in Consul[root@localhost ~]#- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
如果出現上面這樣代表consul是沒問題的。
二、運行 Consul Agent
Consul安裝之后,代理必須運行。 代理可以在服務器或客戶端模式下運行。 每個數據中心都必須至少有一臺服務器,但推薦使用3臺或5臺服務器。 一個單一的服務器部署是非常不推薦的,因為在故障情況下數據丟失是不可避免的。?
所有其他代理以客戶端模式運行。 客戶端是一個非常輕量級的進程,它注冊服務,運行健康檢查,并將查詢轉發給服務器。 代理程序必須在集群中的每個節點上運行。
三、啟動 Agent
為了簡單起見,我們現在將以開發模式啟動Consul代理。 這種模式對于快速簡單地啟動單節點Consul環境非常有用。 它并不打算在生產中使用,因為它不會持續任何狀態。
[root@localhost consul]# consul agent -dev ==> Starting Consul agent... ==> Consul agent running!Version: 'v1.0.1'Node ID: '590309a6-71f6-6145-fe40-d2c5e203687f'Node name: 'localhost.localdomain'Datacenter: 'dc1' (Segment: '<all>')Server: true (Bootstrap: false)Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, DNS: 8600)Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false==> Log data will now stream in as it occurs:2017/11/25 15:15:54 [DEBUG] Using random ID "590309a6-71f6-6145-fe40-d2c5e203687f" as node ID2017/11/25 15:15:54 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:590309a6-71f6-6145-fe40-d2c5e203687f Address:127.0.0.1:8300}]2017/11/25 15:15:54 [INFO] serf: EventMemberJoin: localhost.localdomain.dc1 127.0.0.12017/11/25 15:15:54 [INFO] serf: EventMemberJoin: localhost.localdomain 127.0.0.12017/11/25 15:15:54 [INFO] agent: Started DNS server 127.0.0.1:8600 (udp)2017/11/25 15:15:54 [INFO] raft: Node at 127.0.0.1:8300 [Follower] entering Follower state (Leader: "")2017/11/25 15:15:54 [INFO] consul: Adding LAN server localhost.localdomain (Addr: tcp/127.0.0.1:8300) (DC: dc1)2017/11/25 15:15:54 [INFO] consul: Handled member-join event for server "localhost.localdomain.dc1" in area "wan"2017/11/25 15:15:54 [INFO] agent: Started DNS server 127.0.0.1:8600 (tcp)2017/11/25 15:15:54 [INFO] agent: Started HTTP server on 127.0.0.1:8500 (tcp)2017/11/25 15:15:54 [INFO] agent: started state syncer2017/11/25 15:15:54 [WARN] raft: Heartbeat timeout from "" reached, starting election2017/11/25 15:15:54 [INFO] raft: Node at 127.0.0.1:8300 [Candidate] entering Candidate state in term 22017/11/25 15:15:54 [DEBUG] raft: Votes needed: 12017/11/25 15:15:54 [DEBUG] raft: Vote granted from 590309a6-71f6-6145-fe40-d2c5e203687f in term 2. Tally: 12017/11/25 15:15:54 [INFO] raft: Election won. Tally: 12017/11/25 15:15:54 [INFO] raft: Node at 127.0.0.1:8300 [Leader] entering Leader state2017/11/25 15:15:54 [INFO] consul: cluster leadership acquired2017/11/25 15:15:54 [DEBUG] consul: Skipping self join check for "localhost.localdomain" since the cluster is too small2017/11/25 15:15:54 [INFO] consul: member 'localhost.localdomain' joined, marking health alive2017/11/25 15:15:54 [INFO] consul: New leader elected: localhost.localdomain2017/11/25 15:15:54 [DEBUG] Skipping remote check "serfHealth" since it is managed automatically2017/11/25 15:15:54 [INFO] agent: Synced node info2017/11/25 15:15:54 [DEBUG] agent: Node info in sync2017/11/25 15:15:57 [DEBUG] Skipping remote check "serfHealth" since it is managed automatically2017/11/25 15:15:57 [DEBUG] agent: Node info in sync2017/11/25 15:16:54 [DEBUG] consul: Skipping self join check for "localhost.localdomain" since the cluster is too small2017/11/25 15:17:51 [DEBUG] Skipping remote check "serfHealth" since it is managed automatically2017/11/25 15:17:51 [DEBUG] agent: Node info in sync2017/11/25 15:17:54 [DEBUG] manager: Rebalanced 1 servers, next active server is localhost.localdomain.dc1 (Addr: tcp/127.0.0.1:8300) (DC: dc1)2017/11/25 15:17:54 [DEBUG] consul: Skipping self join check for "localhost.localdomain" since the cluster is too small- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
如您所見,Consul代理已經啟動并輸出了一些日志數據。 從日志數據中,您可以看到我們的代理正在服務器模式下運行,并聲稱擁有集群領導權。 此外,當地成員已被標記為該集群的健康成員。
四、集群成員
在另一個終端運行consul members,可以看到Consul集群的成員。 應該只看到一個成員(你自己):
[root@localhost ~]# consul members Node Address Status Type Build Protocol DC Segment localhost.localdomain 127.0.0.1:8301 alive server 1.0.1 2 dc1 <all>- 1
- 2
- 3
輸出顯示了我們自己的節點,它正在運行的地址,運行狀況,在集群中的角色以及一些版本信息。 額外的元數據可以通過提供-detailed標志來查看。
[root@localhost ~]# consul members -detailed Node Address Status Tags localhost.localdomain 127.0.0.1:8301 alive build=1.0.1:9564c29,dc=dc1,id=590309a6-71f6-6145-fe40-d2c5e203687f,port=8300,raft_vsn=3,role=consul,segment=<all>,vsn=2,vsn_max=3,vsn_min=2,wan_join_port=8302- 1
- 2
- 3
?members命令的輸出基于gossip協議,并最終一致。 也就是說,在任何時候,當地代理所看到的可能與服務器上的狀態不完全一致。 要獲得完全一致,請使用HTTP API再將HTTP請求轉發給Consul服務器:
[root@localhost ~]# curl localhost:8500/v1/catalog/nodes [{"ID": "590309a6-71f6-6145-fe40-d2c5e203687f","Node": "localhost.localdomain","Address": "127.0.0.1","Datacenter": "dc1","TaggedAddresses": {"lan": "127.0.0.1","wan": "127.0.0.1"},"Meta": {"consul-network-segment": ""},"CreateIndex": 5,"ModifyIndex": 6} ]- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
除了HTTP API之外,還可以使用DNS接口查詢節點。 請注意,必須確保將DNS查找默認情況下指向在端口8600上運行的Consul代理的DNS服務器。 DNS條目的格式(如“Armons-MacBook-Air.node.consul”)將在后面詳細介紹。
[root@localhost ~]# dig @127.0.0.1 -p 8600 localhost.localdomain.node.consul ' ; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7 <<>> @127.0.0.1 -p 8600 localhost.localdomain.node.consul ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43915 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; WARNING: recursion requested but not available;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;localhost.localdomain.node.consul. IN A;; ANSWER SECTION: localhost.localdomain.node.consul. 0 IN A 127.0.0.1;; Query time: 0 msec ;; SERVER: 127.0.0.1#8600(127.0.0.1) ;; WHEN: 六 11月 25 15:39:49 CST 2017 ;; MSG SIZE rcvd: 78- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
五、停止 Agent
可以使用Ctrl-C(中斷信號)正常停止代理。 中斷代理之后,您應該看到它離開集群并關閉。?
通過優雅地離開,Consul通知其他集群成員該節點離開。 如果強行殺死了代理進程,則集群的其他成員將檢測到該節點失敗。 成員離開時,其服務和檢查將從目錄中刪除。 當一個成員失敗時,其健康被簡單地標記為關鍵,但不會從目錄中刪除。 Consul將自動嘗試重新連接到失敗的節點,使其能夠從特定的網絡條件恢復,而不再聯系離開的節點。?
此外,如果代理正在作為服務器運行,那么優雅的離開對于避免造成影響一致協議的潛在可用性中斷很重要。 有關如何安全地添加和刪除服務器的詳細信息,請參閱指南部分。
六、注冊服務
1、服務定義
服務可以通過提供服務定義或通過對HTTP API進行適當的調用來注冊。?
服務定義是注冊服務最常用的方式,所以我們將在這一步中使用這種方法。 我們將建立在上一步中介紹的代理配置。?
首先,為Consul配置創建一個目錄。 Consul將所有配置文件加載到配置目錄中,因此Unix系統上的一個通用約定是將目錄命名為/etc/consul.d(.d后綴意味著“該目錄包含一組配置文件”)。
- 1
接下來,我們將編寫一個服務定義配置文件。 假設我們有一個名為“web”的服務在端口80上運行。另外,我們給它一個標簽,我們可以使用它作為查詢服務的附加方式:
[root@localhost ~]# echo '{"service": {"name": "web", "tags": ["rails"], "port": 80}}' | sudo tee /etc/consul.d/web.json- 1
現在,重新啟動代理程序,提供配置目錄:
[root@localhost ~]# consul agent -dev -config-dir=/etc/consul.d ==> Starting Consul agent... ==> Consul agent running!Version: 'v1.0.1'Node ID: '94236f1c-2a29-85c5-b235-dd916485be5b'Node name: 'localhost.localdomain'Datacenter: 'dc1' (Segment: '<all>')Server: true (Bootstrap: false)Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, DNS: 8600)Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false==> Log data will now stream in as it occurs:2017/11/25 16:16:51 [DEBUG] Using random ID "94236f1c-2a29-85c5-b235-dd916485be5b" as node ID2017/11/25 16:16:51 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:94236f1c-2a29-85c5-b235-dd916485be5b Address:127.0.0.1:8300}]2017/11/25 16:16:51 [INFO] serf: EventMemberJoin: localhost.localdomain.dc1 127.0.0.12017/11/25 16:16:51 [INFO] serf: EventMemberJoin: localhost.localdomain 127.0.0.12017/11/25 16:16:51 [INFO] agent: Started DNS server 127.0.0.1:8600 (udp)2017/11/25 16:16:51 [INFO] raft: Node at 127.0.0.1:8300 [Follower] entering Follower state (Leader: "")2017/11/25 16:16:51 [INFO] consul: Adding LAN server localhost.localdomain (Addr: tcp/127.0.0.1:8300) (DC: dc1)2017/11/25 16:16:51 [INFO] consul: Handled member-join event for server "localhost.localdomain.dc1" in area "wan"2017/11/25 16:16:51 [INFO] agent: Started DNS server 127.0.0.1:8600 (tcp)2017/11/25 16:16:51 [INFO] agent: Started HTTP server on 127.0.0.1:8500 (tcp)2017/11/25 16:16:51 [INFO] agent: started state syncer2017/11/25 16:16:52 [WARN] raft: Heartbeat timeout from "" reached, starting election2017/11/25 16:16:52 [INFO] raft: Node at 127.0.0.1:8300 [Candidate] entering Candidate state in term 22017/11/25 16:16:52 [DEBUG] raft: Votes needed: 12017/11/25 16:16:52 [DEBUG] raft: Vote granted from 94236f1c-2a29-85c5-b235-dd916485be5b in term 2. Tally: 12017/11/25 16:16:52 [INFO] raft: Election won. Tally: 12017/11/25 16:16:52 [INFO] raft: Node at 127.0.0.1:8300 [Leader] entering Leader state2017/11/25 16:16:52 [INFO] consul: cluster leadership acquired2017/11/25 16:16:52 [DEBUG] consul: Skipping self join check for "localhost.localdomain" since the cluster is too small2017/11/25 16:16:52 [INFO] consul: member 'localhost.localdomain' joined, marking health alive2017/11/25 16:16:52 [INFO] consul: New leader elected: localhost.localdomain2017/11/25 16:16:52 [DEBUG] Skipping remote check "serfHealth" since it is managed automatically2017/11/25 16:16:52 [INFO] agent: Synced service "web"2017/11/25 16:16:52 [DEBUG] agent: Node info in sync2017/11/25 16:16:52 [DEBUG] agent: Service "web" in sync2017/11/25 16:16:52 [DEBUG] agent: Node info in sync2017/11/25 16:16:52 [DEBUG] Skipping remote check "serfHealth" since it is managed automatically2017/11/25 16:16:52 [DEBUG] agent: Service "web" in sync2017/11/25 16:16:52 [DEBUG] agent: Node info in sync- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
您會注意到它在輸出中“同步”了Web服務。 這意味著代理程序從配置文件加載了服務定義,并已成功將其注冊到服務目錄中。?
如果您想注冊多個服務,您可以在Consul配置目錄中創建多個服務定義文件。
2、查詢服務
一旦代理啟動并且服務同步,我們可以使用DNS或HTTP API來查詢服務。
DNS API
我們首先使用DNS API來查詢我們的服務。 對于DNS API,服務的DNS名稱是NAME.service.consul。 默認情況下,所有DNS名稱始終在consul命名空間中,盡管這是可配置的。 服務子域告訴Consul我們正在查詢服務,NAME是服務的名稱。?
對于我們注冊的Web服務,這些約定和設置會生成web.service.consul的完全限定的域名:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
正如你所看到的,一個A記錄返回了服務可用的節點的IP地址。 A記錄只能保存IP地址。?
您也可以使用DNS API來檢索整個地址/端口對作為SRV記錄:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
SRV記錄表示Web服務正在端口80上運行,并且存在于節點localhost.localdomain.node.dc1.consul.上。DNS使用該記錄的A記錄返回附加部分。?
最后,我們也可以使用DNS API來按標簽過濾服務。 基于標記的服務查詢的格式是TAG.NAME.service.consul。 在下面的例子中,我們向Consul詢問所有帶有“rails”標簽的web服務。 自從我們使用該標簽注冊我們的服務后,我們得到了成功的回應:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
HTTP API
除了DNS API之外,HTTP API還可以用來查詢服務:
[root@localhost ~]# curl http://localhost:8500/v1/catalog/service/web [{"ID": "94236f1c-2a29-85c5-b235-dd916485be5b","Node": "localhost.localdomain","Address": "127.0.0.1","Datacenter": "dc1","TaggedAddresses": {"lan": "127.0.0.1","wan": "127.0.0.1"},"NodeMeta": {"consul-network-segment": ""},"ServiceID": "web","ServiceName": "web","ServiceTags": ["rails"],"ServiceAddress": "","ServicePort": 80,"ServiceEnableTagOverride": false,"CreateIndex": 6,"ModifyIndex": 6} ]- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
目錄API提供了托管給定服務的所有節點。 正如我們稍后將看到的健康檢查一樣,您通常只需要查詢檢查通過的健康實例。 這是DNS正在做的事情。 這是一個查詢只查找健康的實例:
[root@localhost ~]# curl 'http://localhost:8500/v1/health/service/web?passing' [{"Node": {"ID": "94236f1c-2a29-85c5-b235-dd916485be5b","Node": "localhost.localdomain","Address": "127.0.0.1","Datacenter": "dc1","TaggedAddresses": {"lan": "127.0.0.1","wan": "127.0.0.1"},"Meta": {"consul-network-segment": ""},"CreateIndex": 5,"ModifyIndex": 6},"Service": {"ID": "web","Service": "web","Tags": ["rails"],"Address": "","Port": 80,"EnableTagOverride": false,"CreateIndex": 6,"ModifyIndex": 6},"Checks": [{"Node": "localhost.localdomain","CheckID": "serfHealth","Name": "Serf Health Status","Status": "passing","Notes": "","Output": "Agent alive and reachable","ServiceID": "","ServiceName": "","ServiceTags": [],"Definition": {},"CreateIndex": 5,"ModifyIndex": 5}]} ]- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
3、更新服務
服務定義可以通過更改配置文件并向代理發送SIGHUP來更新。 這使您可以更新服務,而不會出現任何停機或無法提供服務查詢的情況。?
或者,可以使用HTTP API動態地添加,刪除和修改服務。
七、Consul 集群
我們已經開始了我們的第一個代理,并注冊和查詢該代理的服務。 這顯示了使用Consul是多么的容易,但并沒有表明如何將其擴展到可擴展的生產級服務發現基礎設施。 在這一步中,我們將創建我們的第一個真正的集群與多個成員。?
當一個Consul代理啟動時,它不知道任何其他節點:它是一個孤立的集群。 要了解其他集群成員,代理必須加入現有集群。 要加入現有的集群,只需要知道一個現有的成員。 代理加入后,會與該成員通訊,并迅速發現集群中的其他成員。 Consul代理可以加入任何其他代理,而不僅僅是服務器模式下的代理。
1、啟動代理
在我們之前的例子中,我們使用了-dev標志來快速設置一個開發服務器。 但是,這不足以在集群環境中使用。 我們將從這里省略-dev標志,而是指定我們的集群標志。?
集群中的每個節點都必須具有唯一的名稱。 默認情況下,Consul使用機器的主機名,但我們將使用-node命令行選項手動覆蓋它。?
我們還將指定一個-bind:這是Consul偵聽的地址,它必須可以被集群中的所有其他節點訪問。 雖然綁定地址不是絕對必要的,但最好提供一個。 Consul將默認嘗試偵聽系統上的所有IPv4接口,但如果找到多個私有IP,將無法啟動錯誤。 由于生產服務器通常具有多個接口,因此指定一個綁定地址可確保您永遠不會將Consul綁定到錯誤的接口。?
第一個節點將作為我們在這個集群中唯一的服務器,我們用-server來指明這一點。?
-bootstrap-expect選項向Consul服務器提示我們期望加入的其他服務器節點的數量。 此選項的用途是延遲復制日志的引導,直到預期數量的服務器成功加入。?
我們已經將-enable_script_checks選項設置為true,以啟用可以執行外部腳本的運行狀況檢查。 這將在后面的例子中使用。 對于生產用途,您希望將ACL配置為與此配合使用,以控制注冊任意腳本的能力。?
最后,我們添加-config-dir選項,標記可以找到服務和檢查定義的位置。?
總而言之,這些設置產生一個這樣的consul代理命令:
- 1
現在,在另一個終端中,我們將連接到第二個節點。?
這次,我們將-bind設置為第二個節點的IP,并將-node設置為agent-two。 由于這個節點不會是Consul服務器,所以我們不提供-server。?
總而言之,這些設置產生一個這樣的consul代理命令:
- 1
此時,您有兩個Consul代理正在運行:一個服務器和一個客戶端。 兩個Consul代理人對彼此還是一無所知,都是他們自己的單節點集群的一部分。 您可以通過對每個代理運行consul members來驗證這一點,并注意到每個代理只能看到一個成員。
2、加入集群
現在,我們將通過在新終端中運行以下命令來告訴第一個代理加入第二個代理:
[root@localhost ~]# consul join 192.168.100.101 Successfully joined cluster by contacting 1 nodes.- 1
- 2
如果在虛擬機里面運行上面的命令提示下面的失敗的話,在每臺虛擬機上執行下這個命令:
[root@localhost ~]# consul join 192.168.100.101 Error joining address '192.168.100.101': Unexpected response code: 500 (1 error(s) occurred:* Failed to join 192.168.100.101: dial tcp 192.168.100.101:8301: getsockopt: no route to host) Failed to join any nodes.[root@localhost ~]# sudo iptables -F- 1
- 2
- 3
- 4
- 5
- 6
- 7
您應該在每個代理日志中看到一些日志輸出。 如果仔細閱讀,您會看到他們收到了加入信息。 如果你對每個代理執行consul members,你會看到兩個代理人現在彼此了解:
[root@localhost ~]# consul members Node Address Status Type Build Protocol DC Segment agent-one 192.168.100.101:8301 alive server 1.0.1 2 dc1 <all> agent-two 192.168.100.102:8301 alive client 1.0.1 2 dc1 <default>- 1
- 2
- 3
- 4
記住:要加入集群,Consul代理只需要了解一個現有的成員。 加入集群后,代理人互相傳播完整的會員信息。
3、在啟動時自動加入集群
理想情況下,每當新節點出現在您的數據中心時,它就會自動加入Consul集群,無需人工干預。 Consul通過啟用AWS,Google Cloud或Azure中的實例的自動發現功能,使用給定的標簽 key/value來促進自動加入。 要使用集成,請將retry_join_ec2,retry_join_gce或retry_join_azure嵌套對象添加到您的Consul配置文件。 這將允許新的節點加入集群,而不需要任何硬編碼的配置。 或者,您可以在啟動時使用-join選項或start_join設置以及其他已知Consul代理的硬編碼地址加入集群。
4、查詢節點
就像查詢服務一樣,Consul也有查詢節點的API。 您可以通過DNS或HTTP API執行此操作。?
對于DNS API,名稱的結構是NAME.node.consul或NAME.node.DATACENTER.consul。 如果數據中心被省略,Consul將僅搜索本地數據中心。?
例如,從“agent-one”中,我們可以查詢節點“agent-two”的地址:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
除了服務之外,查找節點的能力對于系統管理任務來說是非常有用的。 例如,知道要通過SSH連接的節點的地址與將節點作為Consul集群的一部分并查詢它一樣簡單。
5、離開集群
要離開集群,可以正常退出代理(使用Ctrl-C)或強制終止其中一個代理。 優雅地離開允許節點轉換到離開狀態; 否則,其他節點將檢測到它失敗。
八、健康檢查
現在我們已經看到了運行Consul,添加節點和服務以及查詢這些節點和服務的簡單性。 在本節中,我們將介紹為節點和服務添加健康檢查。 健康檢查是服務發現的關鍵組件,可以防止使用不健康的服務。?
此步驟建立在之前創建的Consul集群上。 此時,您應該運行一個雙節點集群。
1、檢查定義
與服務類似,可以通過提供檢查定義或通過對HTTP API進行適當的調用來注冊檢查。?
我們將使用檢查定義方法,因為就像服務一樣,定義是設置檢查最常用的方法。?
在第二個節點的Consul配置目錄中創建兩個定義文件:
- 1
- 2
第一個定義添加了一個名為“ping”的主機級別的檢查。 此檢查運行間隔30秒,調用ping -c1 google.com。 在基于腳本的運行狀況檢查上,檢查以與啟動Consul進程相同的用戶身份運行。 如果該命令以非零退出碼退出,則該節點將被標記為不健康。 這是任何基于腳本的健康檢查的約定。?
第二個命令修改名為web的服務,添加一個檢查,每隔10秒通過curl發送一個請求,以驗證Web服務器是否可訪問。 與主機級運行狀況檢查一樣,如果腳本以非零退出代碼退出,服務將被標記為不健康。?
現在,重新啟動第二個代理,用consul reload加載它,或者發送一個SIGHUP信號。 您應該看到以下日志行:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
前幾行表示代理已經同步了新的定義。 最后一行表明我們為Web服務添加的檢查是至關重要的。 這是因為我們實際上沒有運行Web服務器,所以curl測試失敗了!
2、檢查健康狀態
現在我們已經添加了一些簡單的檢查,我們可以使用HTTP API來檢查它們。 首先,我們可以使用這個命令查找任何失敗的檢查(注意,這可以在任一節點上運行):
[root@localhost etc]# curl http://localhost:8500/v1/health/state/critical [{"Node":"agent-two","CheckID":"service:web","Name":"Service 'web' check","Status":"critical","Notes":"","Output":"","ServiceID":"web","ServiceName":"web","ServiceTags":["rails"],"Definition":{},"CreateIndex":230,"ModifyIndex":262}]- 1
- 2
我們可以看到,只有一個檢查,我們的Web服務檢查,在危險(critical)狀態。?
另外,我們可以嘗試使用DNS查詢Web服務。 由于服務不健康,Consul不會返回任何結果:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
九、KV Data
Consul除了提供服務發現和綜合健康檢查之外,還提供一個易于使用的KV存儲。 這可以用來保存動態配置,協助服務協調,建立leader選舉,并使開發人員可以考慮構建的任何東西。
1、簡單使用
為了演示有多簡單,我們將操作K / V存儲中的幾個鍵。 有兩種方式與Consul KV存儲進行交互:通過HTTP API和Consul KV CLI。 以下示例顯示使用Consul KV CLI,因為它是最容易入門的。 對于更高級的集成,您可能需要使用Consul KV HTTP API。?
首先讓我們探索KV存儲。 我們可以向Consul詢問名為redis / config / minconns的路徑上的key的值:
- 1
- 2
正如你所看到的,我們沒有得到任何結果,這是合理的,因為KV存儲沒有數據。 接下來,我們可以insert或put 值到 KV 存儲中。
[root@localhost ~]# consul kv put redis/config/minconns 1 Success! Data written to: redis/config/minconns[root@localhost ~]# consul kv put redis/config/maxconns 25 Success! Data written to: redis/config/maxconns[root@localhost ~]# consul kv put -flags=42 redis/config/users/admin abcd1234 Success! Data written to: redis/config/users/admin- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
現在我們在存儲中有key,我們可以查詢單個 key 的 value:
[root@localhost ~]# consul kv get redis/config/minconns 1- 1
- 2
Consul保留有關使用-detailed標志檢索的字段的其他元數據:
[root@localhost ~]# consul kv get -detailed redis/config/minconns CreateIndex 517 Flags 0 Key redis/config/minconns LockIndex 0 ModifyIndex 517 Session - Value 1- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
對于“redis / config / users / admin”這個鍵,我們設置了一個標志值42。所有的鍵都支持設置一個64位的整數標志值。 這不是Consul在內部使用的,但客戶可以使用它為任何KV添加有意義的元數據。?
可以使用遞歸選項列出存儲的所有 key和 value。 結果將以字典順序返回:
- 1
- 2
- 3
- 4
要從Consul KV中刪除一個 key,發出“刪除” 命令:
[root@localhost ~]# consul kv delete redis/config/minconns Success! Deleted key: redis/config/minconns- 1
- 2
也可以使用遞歸選項刪除整個前綴:
[root@localhost ~]# consul kv delete -recurse redis Success! Deleted keys with prefix: redis- 1
- 2
要更新現有key的值,請在相同路徑上put一個值:
[root@localhost ~]# consul kv put foo bar Success! Data written to: foo[root@localhost ~]# consul kv get foo bar[root@localhost ~]# consul kv put foo zip Success! Data written to: foo[root@localhost ~]# consul kv get foo zip- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
Consul可以使用Check-And-Set操作提供原子鍵更新。 要執行CAS操作,請指定-cas選項:
[root@localhost ~]# consul kv get -detailed foo CreateIndex 710 Flags 0 Key foo LockIndex 0 ModifyIndex 716 Session - Value bar[root@localhost ~]# consul kv put -cas -modify-index=716 foo bar Success! Data written to: foo[root@localhost ~]# consul kv put -cas -modify-index=716 foo bar Error! Did not write to foo: CAS failed- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
在這種情況下,第一個CAS更新成功,因為索引是716。第二個操作失敗,因為索引不再是716。
十、Consul Web UI
Consul支持web ui界面。UI可用于查看所有服務和節點,查看所有運行狀況檢查及其當前狀態,以及讀取和設置鍵/值數據。 用戶界面自動支持多數據中心。?
要設置自帶的UI,請使用-ui參數啟動Consul代理:
- 1
UI可以在與HTTP API相同的端口上的/ui路徑中使用。 默認情況下,這是http://localhost:8500/ui。?
您可以在這里查看Consul Web UI的現場演示。
十一、參考文獻
Consul 官方入門指南
總結
以上是生活随笔為你收集整理的Consul 入门指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: consul 命令行参数
- 下一篇: “大话架构”阿里架构师分享的Java程序