背景及簡介
官網(wǎng)地址: https://www.consul.io/
下載地址: https://releases.hashicorp.com/consul/1.3.1/
consul是google開源的一個使用go語言開發(fā)的服務(wù)發(fā)現(xiàn)养涮、配置管理中心服務(wù)葵硕。內(nèi)置了服務(wù)注冊與發(fā)現(xiàn)框 架、分布一致性協(xié)議實現(xiàn)贯吓、健康檢查懈凹、Key/Value存儲、多數(shù)據(jù)中心方案悄谐,不再需要依賴其他工具介评。服務(wù)部署簡單,只有一個可運行的二進(jìn)制的包爬舰。每個節(jié)點都需要運行agent们陆,他有兩種運行模式server和client。每個數(shù)據(jù)中心官方建議需要3或5個server節(jié)點以保證數(shù)據(jù)安全情屹,同時保證server-leader的選舉能夠正確的進(jìn)行坪仇。與consul類似的工具還有很多幾個:ZooKeeper, etcd
- 名詞概念
- client: CLIENT表示consul的client模式垃你,就是客戶端模式椅文。是consul節(jié)點的一種模式,這種模式下惜颇,所有注冊到當(dāng)前節(jié)點的服務(wù)會被轉(zhuǎn)發(fā)到SERVER皆刺,本身是不持久化這些信息。
- server: SERVER表示consul的server模式凌摄,表明這個consul是個server羡蛾,這種模式下,功能和CLIENT都一樣锨亏,唯一不同的是林说,它會把所有的信息持久化的本地煎殷,這樣遇到故障,信息是可以被保留的腿箩。
- server-leader: 中間那個SERVER下面有LEADER的字眼,表明這個SERVER是它們的老大劣摇,它和其它SERVER不一樣的一點是珠移,它需要負(fù)責(zé)同步注冊的信息給其它的SERVER,同時也要負(fù)責(zé)各個節(jié)點的健康監(jiān)測末融。
- raft: server節(jié)點之間的數(shù)據(jù)一致性保證钧惧,一致性協(xié)議使用的是raft,而zookeeper用的paxos勾习,etcd采用的也是taft浓瞪。
- 服務(wù)發(fā)現(xiàn)協(xié)議: consul采用http和dns協(xié)議,etcd只支持http
- 服務(wù)注冊: consul支持兩種方式實現(xiàn)服務(wù)注冊巧婶,一種是通過consul的服務(wù)注冊http API乾颁,由服務(wù)自己調(diào)用API實現(xiàn)注冊,另一種方式是通過json個是的配置文件實現(xiàn)注冊艺栈,將需要注冊的服務(wù)以json格式的配置文件給出英岭。consul官方建議使用第二種方式。
- 服務(wù)發(fā)現(xiàn): consul支持兩種方式實現(xiàn)服務(wù)發(fā)現(xiàn)湿右,一種是通過http API來查詢有哪些服務(wù)诅妹,另外一種是通過consul agent 自帶的DNS(8600端口),域名是以NAME.service.consul的形式給出毅人,NAME即在定義的服務(wù)配置文件中吭狡,服務(wù)的名稱。DNS方式可以通過check的方式檢查服務(wù)丈莺。
- 服務(wù)間的通信協(xié)議: Consul使用gossip協(xié)議管理成員關(guān)系划煮、廣播消息到整個集群,他有兩個gossip pool(LAN pool和WAN pool)场刑,LAN pool是同一個數(shù)據(jù)中心內(nèi)部通信的般此,WAN pool是多個數(shù)據(jù)中心通信的,LAN pool有多個牵现,WAN pool只有一個铐懊。
- LAN Gossip——它包含所有位于同一個局域網(wǎng)或者數(shù)據(jù)中心的所有節(jié)點。
- WAN Gossip——它只包含Server瞎疼。這些server主要分布在不同的數(shù)據(jù)中心并且通常通過因特網(wǎng)或者廣域網(wǎng)通信科乎。
- RPC——遠(yuǎn)程過程調(diào)用。這是一個允許client請求server的請求/響應(yīng)機(jī)制贼急。
簡單來說就是:client相當(dāng)于我們平時說的LB,負(fù)責(zé)將請求轉(zhuǎn)發(fā)到Server,Server中有一個leader,負(fù)責(zé)Server集群的同步和監(jiān)測茅茂,這個server-leader在不指定的情況下回隨機(jī)推舉出一個捏萍,當(dāng)然也可以手動指定。這個在ACL配置的時候需要保證Server-leader是同一個空闲。
單機(jī)安裝consul
下載consul
$ sudo wget https://releases.hashicorp.com/consul/1.3.1/consul_1.3.1_linux_amd64.zip
$ sudo unzip consul_1.3.1_linux_amd64.zip
$ sudo mv consul /usr/bin/
$ consul --version
Consul v1.3.1
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
啟動consul
$ sudo mkdir /data/app/consul
$ sudo chown `whoami`. /data/app/consul/
$ sudo nohup /usr/bin/consul agent -server -data-dir=/data/app/consul -bootstrap -ui -advertise=10.208.1.10 -client=10.208.1.10 > /data/app/consul/consul.log 2>&1 &
$ tail -f /data/app/consul/consul.log
2019/01/24 20:16:10 [INFO] consul: Adding LAN server azr-sal1002 (Addr: tcp/10.208.1.10:8300) (DC: dc1)
2019/01/24 20:16:10 [WARN] agent/proxy: running as root, will not start managed proxies
2019/01/24 20:16:10 [INFO] agent: Started DNS server 127.0.0.1:8600 (udp)
2019/01/24 20:16:10 [INFO] agent: Started DNS server 127.0.0.1:8600 (tcp)
2019/01/24 20:16:10 [INFO] agent: Started HTTP server on 127.0.0.1:8500 (tcp)
2019/01/24 20:16:10 [INFO] agent: started state syncer
2019/01/24 20:16:17 [ERR] agent: failed to sync remote state: No cluster leader
2019/01/24 20:16:18 [WARN] raft: Heartbeat timeout from "" reached, starting election
2019/01/24 20:16:18 [INFO] raft: Node at 10.208.1.10:8300 [Candidate] entering Candidate state in term 3
2019/01/24 20:16:18 [INFO] raft: Election won. Tally: 1
2019/01/24 20:16:18 [INFO] raft: Node at 10.208.1.10:8300 [Leader] entering Leader state
2019/01/24 20:16:18 [INFO] consul: cluster leadership acquired
2019/01/24 20:16:18 [INFO] consul: New leader elected: azr-sal1002
2019/01/24 20:16:18 [INFO] agent: Synced node info
==> Newer Consul version available: 1.4.1 (currently running: 1.3.1)
訪問ui
image.png
參數(shù)解釋
命令行參數(shù)
-bind:為該節(jié)點綁定一個地址
-enable-script-checks=true:設(shè)置檢查服務(wù)為可用
-join:加入到已有的集群中
-server 表示當(dāng)前使用的server模式
-node:指定當(dāng)前節(jié)點在集群中的名稱
-config-file - 要加載的配置文件
-config-dir:指定配置文件令杈,定義服務(wù)的,默認(rèn)所有以.json結(jié)尾的文件都會讀
-datacenter: 數(shù)據(jù)中心沒名稱碴倾,不設(shè)置的話默認(rèn)為dc
-client: 客戶端模式
-ui: 使用consul自帶的ui界面
-data-dir consul存儲數(shù)據(jù)的目錄
-bootstrap:用來控制一個server是否在bootstrap模式逗噩,在一個datacenter中只能有一個server處于bootstrap模式,當(dāng)一個server處于bootstrap模式時跌榔,可以自己選舉為raft leader异雁。
-bootstrap-expect:在一個datacenter中期望提供的server節(jié)點數(shù)目,當(dāng)該值提供的時候僧须,consul一直等到達(dá)到指定sever數(shù)目的時候才會引導(dǎo)整個集群加派,該標(biāo)記不能和bootstrap公用
這兩個參數(shù)十分重要扣甲, 二選一但绕,如果兩個參數(shù)不使用的話芒率,會出現(xiàn)就算你使用join將agent加入了集群仍然會報
2018/10/14 15:40:00 [ERR] agent: failed to sync remote state: No cluster leader
配置文件參數(shù)
ui: 相當(dāng)于-ui 命令行標(biāo)志。
acl_token:agent會使用這個token和consul server進(jìn)行請求
acl_ttl:控制TTL的cache驱闷,默認(rèn)是30s
addresses:一個嵌套對象耻台,可以設(shè)置以下key:dns、http空另、rpc
advertise_addr:等同于-advertise
bootstrap:等同于-bootstrap
bootstrap_expect:等同于-bootstrap-expect
bind_addr:等同于-bind
ca_file:提供CA文件路徑盆耽,用來檢查客戶端或者服務(wù)端的鏈接
cert_file:必須和key_file一起
check_update_interval:
client_addr:等同于-client
datacenter:等同于-dc
data_dir:等同于-data-dir
disable_anonymous_signature:在進(jìn)行更新檢查時禁止匿名簽名
enable_debug:開啟debug模式
enable_syslog:等同于-syslog
encrypt:等同于-encrypt
key_file:提供私鑰的路徑
leave_on_terminate:默認(rèn)是false,如果為true扼菠,當(dāng)agent收到一個TERM信號的時候摄杂,它會發(fā)送leave信息到集群中的其他節(jié)點上。
log_level:等同于-log-level node_name:等同于-node
ports:這是一個嵌套對象循榆,可以設(shè)置以下key:dns(dns地址:8600)析恢、http(http api地址:8500)、rpc(rpc:8400)秧饮、serf_lan(lan port:8301)映挂、serf_wan(wan port:8302)、server(server rpc:8300)
protocol:等同于-protocol
rejoin_after_leave:等同于-rejoin
retry_join:等同于-retry-join
retry_interval:等同于-retry-interval
server:等同于-server
syslog_facility:當(dāng)enable_syslog被提供后盗尸,該參數(shù)控制哪個級別的信息被發(fā)送柑船,默認(rèn)Local0
ui_dir:等同于-ui-dir
集群搭建(單機(jī))
因為沒有資源,只能在一臺機(jī)器上裝偽集群,如果是三臺服務(wù)器來做的話, 不需要寫json配置文件,直接用命令行啟動就可以
# 創(chuàng)建節(jié)點數(shù)據(jù)目錄
$ mkdir -pv /data/app/consul/{node1,node2,node3}
mkdir: created directory ‘/data/app/consul/node1’
mkdir: created directory ‘/data/app/consul/node2’
mkdir: created directory ‘/data/app/consul/node3’
節(jié)點1配置
$ vim /data/app/consul/node1/basic.json
{
"datacenter": "dc1",
"data_dir": "/data/app/consul/node1",
"log_level": "INFO",
"server": true,
"node_name": "node1",
"ui": true,
"bind_addr": "10.208.1.10",
"client_addr": "10.208.1.10",
"advertise_addr": "10.208.1.10",
"bootstrap_expect": 3,
"ports":{
"http": 8500,
"dns": 8600,
"server": 8300,
"serf_lan": 8301,
"serf_wan": 8302
}
}
$ nohup /usr/bin/consul agent -config-file=/data/app/consul/node1/basic.json > /data/app/consul/node1/consul.log 2>&1 &
$ tail -100f /data/app/consul/node1/consul.log
節(jié)點2配置
$ vim /data/app/consul/node2/basic.json
{
"datacenter": "dc1",
"data_dir": "/data/app/consul/node2",
"log_level": "INFO",
"server": true,
"node_name": "node2",
"bind_addr": "10.208.1.10",
"client_addr": "10.208.1.10",
"advertise_addr": "10.208.1.10",
"ports":{
"http": 8510,
"dns": 8610,
"server": 8310,
"serf_lan": 8311,
"serf_wan": 8312
}
}
$ nohup /usr/bin/consul agent -config-file=/data/app/consul/node2/basic.json -retry-join=10.208.1.10:8301 > /data/app/consul/node2/consul.log 2>&1 &
$ tail -100f /data/app/consul/node2/consul.log
節(jié)點3配置
$ vim /data/app/consul/node3/basic.json
{
"datacenter": "dc1",
"data_dir": "/data/app/consul/node3",
"log_level": "INFO",
"server": true,
"node_name": "node3",
"bind_addr": "10.208.1.10",
"client_addr": "10.208.1.10",
"advertise_addr": "10.208.1.10",
"ports":{
"http": 8520,
"dns": 8620,
"server": 8320,
"serf_lan": 8321,
"serf_wan": 8322
}
}
$ nohup /usr/bin/consul agent -config-file=/data/app/consul/node3/basic.json -retry-join=10.208.1.10:8301 > /data/app/consul/node3/consul.log 2>&1 &
$ tail -100f /data/app/consul/node3/consul.log
查看節(jié)點1日志變化
2019/01/24 22:48:58 [INFO] serf: EventMemberJoin: node2.dc1 10.208.1.10
2019/01/24 22:49:59 [INFO] serf: EventMemberJoin: node3.dc1 10.208.1.10
...
2019/01/24 22:49:59 [INFO] consul: Found expected number of peers, attempting bootstrap: 10.208.1.10:8320,10.208.1.10:8300,10.208.1.10:8310
2019/01/24 22:49:59 [INFO] consul: Handled member-join event for server "node3.dc1" in area "wan"
2019/01/24 22:50:05 [WARN] raft: Heartbeat timeout from "" reached, starting election
2019/01/24 22:50:05 [INFO] raft: Node at 10.208.1.10:8300 [Candidate] entering Candidate state in term 2
2019/01/24 22:50:05 [INFO] raft: Election won. Tally: 2
2019/01/24 22:50:05 [INFO] raft: Node at 10.208.1.10:8300 [Leader] entering Leader state
2019/01/24 22:50:05 [INFO] raft: Added peer faa05ada-4e06-6d5a-f35b-286c57826231, starting replication
2019/01/24 22:50:05 [INFO] raft: Added peer be2837bd-3b87-07f9-a776-863ed5966ffb, starting replication
2019/01/24 22:50:05 [INFO] consul: cluster leadership acquired
2019/01/24 22:50:05 [INFO] consul: New leader elected: node1
2019/01/24 22:50:05 [WARN] raft: AppendEntries to {Voter be2837bd-3b87-07f9-a776-863ed5966ffb 10.208.1.10:8310} rejected, sending older logs (next: 1)
2019/01/24 22:50:05 [INFO] raft: pipelining replication to peer {Voter be2837bd-3b87-07f9-a776-863ed5966ffb 10.208.1.10:8310}
2019/01/24 22:50:05 [INFO] consul: member 'node1' joined, marking health alive
2019/01/24 22:50:05 [INFO] consul: member 'node2' joined, marking health alive
2019/01/24 22:50:05 [INFO] agent: Synced node info
2019/01/24 22:50:05 [INFO] consul: member 'node3' joined, marking health alive
2019/01/24 22:50:06 [WARN] raft: AppendEntries to {Voter faa05ada-4e06-6d5a-f35b-286c57826231 10.208.1.10:8320} rejected, sending older logs (next: 1)
2019/01/24 22:50:07 [INFO] raft: pipelining replication to peer {Voter faa05ada-4e06-6d5a-f35b-286c57826231 10.208.1.10:8320}
訪問UI
image (1).png
查看集群信息
$ /usr/bin/consul members -http-addr=10.208.1.10:8500
Node Address Status Type Build Protocol DC Segment
node1 10.208.1.10:8301 alive server 1.3.1 2 dc1 <all>
node2 10.208.1.10:8311 alive server 1.3.1 2 dc1 <all>
node3 10.208.1.10:8321 alive server 1.3.1 2 dc1 <all>
$ /usr/bin/consul info -http-addr=10.208.1.10:8500
agent:
check_monitors = 0
check_ttls = 0
checks = 0
services = 0
build:
prerelease =
revision = f2b13f30
version = 1.3.1
consul:
bootstrap = false
known_datacenters = 1
leader = true
leader_addr = 10.208.1.10:8300
server = true
raft:
applied_index = 80
commit_index = 80
fsm_pending = 0
last_contact = 0
last_log_index = 80
last_log_term = 2
last_snapshot_index = 0
last_snapshot_term = 0
latest_configuration = [{Suffrage:Voter ID:faa05ada-4e06-6d5a-f35b-286c57826231 Address:10.208.1.10:8320} {Suffrage:Voter ID:5aee898c-ead4-f844-0d70-37ee7d9e9fb3
Address:10.208.1.10:8300} {Suffrage:Voter ID:be2837bd-3b87-07f9-a776-863ed5966ffb Address:10.208.1.10:8310}]
latest_configuration_index = 1
num_peers = 2
protocol_version = 3
protocol_version_max = 3
protocol_version_min = 0
snapshot_version_max = 1
snapshot_version_min = 0
state = Leader
term = 2
runtime:
arch = amd64
cpu_count = 4
goroutines = 104
max_procs = 4
os = linux
version = go1.11.1
serf_lan:
coordinate_resets = 0
encrypted = false
event_queue = 0
event_time = 2
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 3
members = 3
query_queue = 0
query_time = 1
serf_wan:
coordinate_resets = 0
encrypted = false
event_queue = 0
event_time = 1
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 5
members = 3
query_queue = 0
query_time = 1