1、概述html
consul是google開源的一個使用go語言開發的服務發現、配置管理中心服務。內置了服務註冊與發現框 架、分佈一致性協議實現、健康檢查、Key/Value存儲、多數據中心方案,再也不須要依賴其餘工具(好比ZooKeeper等)。服務部署簡單,只有一個可運行的二進制的包。每一個節點都須要運行agent,他有兩種運行模式server和client。每一個數據中心官方建議須要3或5個server節點以保證數據安全,同時保證server-leader的選舉可以正確的進行。node
@clientpython
CLIENT表示consul的client模式,就是客戶端模式。是consul節點的一種模式,這種模式下,全部註冊到當前節點的服務會被轉發到SERVER,自己是不持久化這些信息。linux
@servergit
SERVER表示consul的server模式,代表這個consul是個server,這種模式下,功能和CLIENT都同樣,惟一不一樣的是,它會把全部的信息持久化的本地,這樣遇到故障,信息是能夠被保留的。github
@server-leaderweb
中間那個SERVER下面有LEADER的字眼,代表這個SERVER是它們的老大,它和其它SERVER不同的一點是,它須要負責同步註冊的信息給其它的SERVER,同時也要負責各個節點的健康監測。shell
@raftjson
server節點之間的數據一致性保證,一致性協議使用的是raft,而zookeeper用的paxos,etcd採用的也是raft。bootstrap
@服務發現協議
consul採用http和dns協議,etcd只支持http
@服務註冊
consul支持兩種方式實現服務註冊,一種是經過consul的服務註冊http API,由服務本身調用API實現註冊,另外一種方式是經過json個是的配置文件實現註冊,將須要註冊的服務以json格式的配置文件給出。consul官方建議使用第二種方式。
@服務發現
consul支持兩種方式實現服務發現,一種是經過http API來查詢有哪些服務,另一種是經過consul agent 自帶的DNS(8600端口),域名是以NAME.service.consul的形式給出,NAME即在定義的服務配置文件中,服務的名稱。DNS方式能夠經過check的方式檢查服務。
@服務間的通訊協議
Consul使用gossip協議管理成員關係、廣播消息到整個集羣,他有兩個gossip pool(LAN pool和WAN pool),LAN pool是同一個數據中心內部通訊的,WAN pool是多個數據中心通訊的,LAN pool有多個,WAN pool只有一個。
2、consul集羣搭建
1)安裝
首先去官網如今合適的consul包:https://www.consul.io/downloads.html
安裝直接下載zip包,解壓後只有一個可執行的文件consul,將consul添加到系統的環境變量裏面。
#unzip consul_1.2.3_linux_amd64.zip
#cp -a consul /usr/bin
#consul
Usage: consul [--version] [--help] <command> [<args>] Available commands are: agent Runs a Consul agent catalog Interact with the catalog connect Interact with Consul Connect event Fire a new event exec Executes a command on Consul nodes force-leave Forces a member of the cluster to enter the "left" state info Provides debugging information for operators. intention Interact with Connect service intentions join Tell Consul agent to join cluster keygen Generates a new encryption key keyring Manages gossip layer encryption keys kv Interact with the key-value store leave Gracefully leaves the Consul cluster and shuts down lock Execute a command holding a lock maint Controls node or service maintenance mode members Lists the members of a Consul cluster monitor Stream logs from a Consul agent operator Provides cluster-level tools for Consul operators reload Triggers the agent to reload configuration files rtt Estimates network round trip time between nodes snapshot Saves, restores and inspects snapshots of Consul server state validate Validate config files/directories version Prints the Consul version watch Watch for changes in Consul
輸入consul,出現上面的內容證實安裝成功。
2)啓動
consul必須啓動agent才能使用,有兩種啓動模式server和client,還有一個官方自帶的ui。server用與持久化服務信息,集羣官方建議3或5個節點。client只用與於server交互。ui能夠查看集羣狀況的。
server:
cn1:
#consul agent -bootstrap-expect 2 -server -data-dir /data/consul0 -node=cn1 -bind=192.168.1.202 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1
cn2:
#consul agent -server -data-dir /data/consul0 -node=cn2 -bind=192.168.1.201 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 -join 192.168.1.202
cn3:
#consul agent -server -data-dir /data/consul0 -node=cn3 -bind=192.168.1.200 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 -join 192.168.1.202
參數解釋:
-bootstrap-expect:集羣指望的節點數,只有節點數量達到這個值纔會選舉leader。
-server: 運行在server模式
-data-dir:指定數據目錄,其餘的節點對於這個目錄必須有讀的權限
-node:指定節點的名稱
-bind:爲該節點綁定一個地址
-config-dir:指定配置文件,定義服務的,默認全部一.json結尾的文件都會讀
-enable-script-checks=true:設置檢查服務爲可用
-datacenter: 數據中心沒名稱,
-join:加入到已有的集羣中
client:
#consul agent -data-dir /data/consul0 -node=cn4 -bind=192.168.1.199 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 -join 192.168.1.202
client節點能夠有多個,本身根據服務指定便可。
ui:
#consul agent -ui -data-dir /data/consul0 -node=cn4 -bind=192.168.1.198 -client 192.168.1.198 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 -join 192.168.1.202
-ui:使用自帶的ui,
-ui-dir:指定ui的目錄,使用本身定義的ui
-client:指定web ui、的監聽地址,默認127.0.0.1只能本機訪問。
集羣建立完成後:
使用一些經常使用的命令檢查集羣的狀態:
#consul info
能夠在raft:stat看到此節點的狀態是Fllower或者leader
#consul members
Node Address Status Type Build Protocol DC Segment
cn1 192.168.1.202:8301 alive server 1.0.2 2 dc1 <all>
cn2 192.168.1.201:8301 alive server 1.0.2 2 dc1 <all>
cn3 192.168.1.200:8301 alive client 1.0.2 2 dc1 <default>
新加入一個節點有幾種方式;
一、這種方式,重啓後不會自動加入集羣
#consul join 192.168.1.202
二、#在啓動的時候使用-join指定一個集羣
#consul agent -ui -data-dir /data/consul0 -node=cn4 -bind=192.168.1.198 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 -join 192.168.1.202
三、使用-startjoin或-rejoin
#consul agent -ui -data-dir /data/consul0 -node=cn4 -bind=192.168.1.198 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 -rejoin
訪問ui:
http://192.168.1.198:8500/ui
端口:
8300:consul agent服務relplaction、rpc(client-server)
8301:lan gossip
8302:wan gossip
8500:http api端口
8600:DNS服務端口
3)服務註冊
採用的是配置文件的方式,(官方推薦)首先建立一個目錄用於存放定義服務的配置文件
#mkdir /etc/consul.d/
啓動服務的時候要使用-config-dir 參數指定。
下面給出一個服務定義:
#cat web.json
{ "service":{ "name":"web", "tags":[ "rails" ], "port":80, "check":{ "name":"ping", "script":"curl -s localhost:80", "interval":"3s" } } }
若是這樣啓動consul後,會發現consul的日誌裏面一直報錯,由於咱們沒有啓動80端口的服務,下面給出我寫的一個go程序:
#cat web.go
package main import ( "io"
"log"
"net/http"
"strconv"
"fmt" ) var iCnt int = 0; func helloHandler(w http.ResponseWriter, r*http.request) { iCnt++; str :="Hell eorld ! friend("+ strconv.Itoa(iCnt)+")" io.WriteString(w,str) fmt.Println(str) } func main(){ ht :=http.HanderFunc(helloHandler) if ht != nil { http.Handle("/hello",ht) } err := http.ListenAndServe(":80",nil) if err != nil{ log.Fatal("ListenAndserve:",err.Error()) } }
#須要一個goalong的環境:
#go build -o web web.go
#./web
此時就能夠在沒有運行web服務的機器上面執行DNS查詢:
# dig @127.0.0.1 -p 8600 web.service.consul SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 80 cn2.node.dc1.consul.
web.service.consul. 0 IN SRV 1 1 80 cn3.node.dc1.consul.
;; ADDITIONAL SECTION:
cn2.node.dc1.consul. 0 IN A 192.168.1.201
cn2.node.dc1.consul. 0 IN TXT "consul-network-segment="
cn3.node.dc1.consul. 0 IN A 192.168.1.200
cn3.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 17 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: 四 1月 04 14:39:32 CST 2018
;; MSG SIZE rcvd: 229
能夠看到服務已經註冊到集羣裏面了。
使用dns查詢,默認域名格式NAME.service.consul,NAME就是web.json裏面定義的service的name。能夠本身指定域和端口:-domain、-dns-port 53
爲了方便使用consul集羣的註冊使用,因此寫了一個三節點client的註冊腳本,方便統一註冊服務和管理。還利用到了nfs,將服務文件共享到集羣。
#!/usr/bin/env python #encoding: utf8 #decription: registered a service to consul
from subprocess import call import sys hosts = {"b1":"10.10.1.01:8500","b2":"10.10.7.1:8500","b3":"10.10.8.21:8500"} def consul_relaod(): if (len(sys.argv) != 2) or sys.argv[1] == '-h': print(("Usage: {0} [option] :{1} ,if you wang update all of them,you must use 'all'").format(sys.argv[0],hosts.keys())) sys.exit() elif(sys.argv[1] == 'all'): for i in hosts.keys(): call(("consul reload -http-addr {}").format(hosts[i]),shell=True) else: call(("consul reload -http-addr {}").format(hosts[sys.argv[1]]),shell=True) if __name__ == '__main__': consul_relaod()
hosts是client節點列表。能夠只註冊其中的一個節點,輸入hosts中對應的key,也能夠輸入all,註冊到全部節點;nfs共享的是/etc/consul.d目錄。
4)健康檢查
check使用來作服務的健康檢查的,能夠擁有多個,也能夠不使用支持多種方式檢查。check必須是script或者TTL類型,若是是TTL類型則ttl變量必須被提供。script是consul主動去檢查服務的健康情況,ttl是服務主動向consul報告本身的情況。新版本的consul不在使用script來表示,使用args,若是是https服務的健康檢查,可使用args這種腳本的方式實現,由於consul默認不支持https的健康檢查。
script check:
"check": {
"args": ["/data/scripts/kubeadm-ha-0.sh",""],
"interval": "10s"
}
http check:
{
"check": {
"id": "api",
"name": "HTTP API 500",
"http": "http://loclhost:500/health",
"interval": "10s",
"timeout": "1s"
}
}
tcp check:
{
"check": {
"id": "ssh",
"name": "ssh TCP 26622",
"tcp": "localhost:26622",
"interval": "10s",
"timeout": "1s"
}
}
ttl check:
{
"check": {
"id": "web-app",
"name": "Web APP status",
"notes": "Web APP does a curl internally every 10 seconds",
"ttl": "30s"
}
}
3、更新consul版本爲最新版本1.2.3.
版本更新特性:
https://github.com/hashicorp/consul/blob/v1.2.3/CHANGELOG.md
FEATURES:
agent: New Cloud Auto-join provider: Kubernetes (K8S) [GH-4635]
http: Added support for "Authorization: Bearer" head in addition to the X-Consul-Token header. [GH-4483]
dns: Added a way to specify SRV weights for each service instance to allow weighted DNS load-balancing. [GH-4198]
dns: Include EDNS-ECS options in EDNS responses where appropriate: see RFC 7871 [GH-4647]
IMPROVEMENTS:
ui: Switch to fullscreen layout for lists and detail, left aligned forms [GH-4435]
connect: TLS certificate readiness now performs x509 certificate verification to determine whether the cert is usable. [GH-4540]
ui: The syntax highlighting/code editor is now on by default [GH-4651]
ui: Fallback to showing Node.Address if Service.Address is not set [GH-4579]
ui較以前有很大改變: