Consul集羣部署

在「Consul入門」一文中咱們對Consul的基本知識點和單節點部署作了一些介紹,今天咱們來說講Consul集羣的部署方法。
html

Consul架構說明

圖片

上圖是官網提供的一個事例系統圖,圖中的Server是consul服務端高可用集羣,Client是consul客戶端。consul客戶端不保存數據,客戶端將接收到的請求轉發給響應的Server端。Server之間經過局域網或廣域網通訊實現數據一致性。每一個Server或Client都是一個consul agent。node

Consul集羣間使用了GOSSIP協議通訊和raft一致性算法。上面這張圖涉及到了不少術語:python

  • Agent——agent是一直運行在Consul集羣中每一個成員上的守護進程。經過運行consul agent來啓動。agent能夠運行在client或者server模式。指定節點做爲client或者server是很是簡單的,除非有其餘agent實例。全部的agent都能運行DNS或者HTTP接口,並負責運行時檢查和保持服務同步。linux

  • Client——一個Client是一個轉發全部RPC到server的代理。這個client是相對無狀態的。client惟一執行的後臺活動是加入LAN gossip池。這有一個最低的資源開銷而且僅消耗少許的網絡帶寬。web

  • Server——一個server是一個有一組擴展功能的代理,這些功能包括參與Raft選舉,維護集羣狀態,響應RPC查詢,與其餘數據中心交互WAN gossip和轉發查詢給leader或者遠程數據中心。算法

  • DataCenter——雖然數據中心的定義是顯而易見的,可是有一些細微的細節必須考慮。例如,在EC2中,多個可用區域被認爲組成一個數據中心。咱們定義數據中心爲一個私有的,低延遲和高帶寬的一個網絡環境。這不包括訪問公共網絡,可是對於咱們而言,同一個EC2中的多個可用區域能夠被認爲是一個數據中心的一部分。json

  • Consensus——一致性,使用Consensus來代表就leader選舉和事務的順序達成一致。爲了以容錯方式達成一致,通常有超過半數一致則能夠認爲總體一致。Consul使用Raft實現一致性,進行leader選舉,在consul中的使用bootstrap時,能夠進行自選,其餘server加入進來後bootstrap就能夠取消。bootstrap

  • Gossip——Consul創建在Serf的基礎之上,它提供了一個用於多播目的的完整的gossip協議。Serf提供成員關係,故障檢測和事件廣播。Serf是去中心化的服務發現和編制的解決方案,節點失敗偵測與發現,具備容錯、輕量、高可用的特色。vim

  • LAN Gossip——它包含全部位於同一個局域網或者數據中心的全部節點。api

  • WAN Gossip——它只包含Server。這些server主要分佈在不一樣的數據中心而且一般經過因特網或者廣域網通訊。

  • RPC——遠程過程調用。這是一個容許client請求server的請求/響應機制。

在每一個數據中心,client和server是混合的。通常建議有3-5臺server。這是基於有故障狀況下的可用性和性能之間的權衡結果,由於越多的機器加入達成共識越慢。然而,並不限制client的數量,它們能夠很容易的擴展到數千或者數萬臺。

同一個數據中心的全部節點都必須加入gossip協議。這意味着gossip協議包含一個給定數據中心的全部節點。這服務於幾個目的:第一,不須要在client上配置server地址。發現都是自動完成的。第二,檢測節點故障的工做不是放在server上,而是分佈式的。這是的故障檢測相比心跳機制有更高的可擴展性。第三:它用來做爲一個消息層來通知事件,好比leader選舉發生時。

每一個數據中心的server都是Raft節點集合的一部分。這意味着它們一塊兒工做並選出一個leader,一個有額外工做的server。leader負責處理全部的查詢和事務。做爲一致性協議的一部分,事務也必須被複制到全部其餘的節點。由於這一要求,當一個非leader得server收到一個RPC請求時,它將請求轉發給集羣leader。

server節點也做爲WAN gossip Pool的一部分。這個Pool不一樣於LAN Pool,由於它是爲了優化互聯網更高的延遲,而且它只包含其餘Consul server節點。這個Pool的目的是爲了容許數據中心可以以low-touch的方式發現彼此。這使得一個新的數據中心能夠很容易的加入現存的WAN gossip。由於server都運行在這個pool中,它也支持跨數據中心請求。當一個server收到來自另外一個數據中心的請求時,它隨即轉發給正確數據中想一個server。該server再轉發給本地leader。

這使得數據中心之間只有一個很低的耦合,可是因爲故障檢測,鏈接緩存和複用,跨數據中心的請求都是相對快速和可靠的。

構建Consul集羣

環境準備

  • 系統環境

主機名 IP地址 Consul角色
dev-master-01 192.168.2.210 Server
dev-node-01 192.168.2.211 Server
dev-node-02 192.168.2.212 Server
dev-node-03 192.168.2.213 Client
  • 創建相應的數據和配置目錄

$ mkdir -p /opt/consul/web
$ mkdir -p /opt/consul/data
$ mkdir -p /opt/consul/conf
$ mkdir -p /opt/consul/run/
  • 下載Web-UI(可選)

Consul提供了用於狀態監控Web服務器,將Web UI工具下載到-ui-dir指定的目錄,便可以建立可視化的管理頁面。Consul 0.8.2版本已經自帶了,不用在單獨下載。

$ wget https://releases.hashicorp.com/consul/0.8.1/consul_0.8.1_web_ui.zip
$ unzip consul_0.8.1_web_ui.zip -d /opt/consul/web/

以上幾項操做在全部節點上都要進行。

安裝Consul

Consul安裝很是簡單,若是你尚未安裝好Consul,可先參考「Consul入門」一文。

Conusl命令行

consul是隻有一個命令行應用,就是consul命令。consul命令能夠包含agent、members等參數進行使用,下面咱們介紹下經常使用的幾個命令:

經過consul -h可看到consul所支持的全部子命令。

$ consul -h
usage: consul [--version] [--help] <command> [<args>]

Available commands are:
   agent          Runs a Consul agent
   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.
   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

簡單說下幾個經常使用指令的用途:

  • agent指令是consul的核心,它運行agent來維護成員的重要信息、運行檢查、服務宣佈、查詢處理等等。

  • event命令提供了一種機制,用來fire自定義的用戶事件,這些事件對consul來講是不透明的,但它們能夠用來構建自動部署、重啓服務或者其餘行動的腳本。

  • exec指令提供了一種遠程執行機制,好比你要在全部的機器上執行uptime命令,遠程執行的工做經過job來指定,存儲在KV中。agent使用event系統能夠快速的知道有新的job產生,消息是經過gossip協議來傳遞的,所以消息傳遞是最佳的,可是並不保證命令的執行。事件經過gossip來驅動,遠程執行依賴KV存儲系統(就像消息代理同樣)。

  • force-leave能夠強制consul集羣中的成員進入left狀態(空閒狀態),記住,即便一個成員處於活躍狀態,它仍舊能夠再次加入集羣中,這個方法的真實目的是強制移除failed的節點。若是failed的節點仍是網絡的一部分,則consul會週期性的從新連接failed的節點,若是通過一段時間後(默認是72小時),consul則會宣佈中止嘗試連接failed的節點。force-leave指令能夠快速的把failed節點轉換到left狀態。

  • info指令提供了各類操做時能夠用到的debug信息,對於client和server,info有返回不一樣的子系統信息,目前有如下幾個KV信息:agent(提供agent信息),consul(提供consul庫的信息),raft(提供raft庫的信息),serf_lan(提供LAN gossip pool),serf_wan(提供WAN gossip pool)。

  • join指令告訴consul agent加入一個已經存在的集羣中,一個新的consul agent必須加入一個已經有至少一個成員的集羣中,這樣它才能加入已經存在的集羣中,若是你不加入一個已經存在的集羣,則agent是它自身集羣的一部分,其餘agent則能夠加入進來。agent能夠加入其餘agent屢次。若是你想加入多個集羣,則能夠寫多個地址,consul會加入全部的地址。

  • keygen指令生成加密的密鑰,能夠用在consul agent通信加密。

  • leave指令觸發一個優雅的離開動做並關閉agent,節點離開後不會嘗試從新加入集羣中。運行在server狀態的節點,節點會被優雅的刪除,這是很嚴重的,在某些狀況下一個不優雅的離開會影響到集羣的可用性。

  • members指令輸出consul agent目前所知道的全部的成員以及它們的狀態,節點的狀態只有alive、left、failed三種狀態。

  • monitor指令用來連接運行的agent,並顯示日誌。monitor會顯示最近的日誌,並持續的顯示日誌流,不會自動退出,除非你手動或者遠程agent本身退出。

  • reload指令能夠從新加載agent的配置文件。SIGHUP指令在從新加載配置文件時使用,任何從新加載的錯誤都會寫在agent的log文件中,並不會打印到屏幕。

  • version指令用做打印consul的版本

  • watch指令提供了一個機制,用來監視實際數據視圖的改變(節點列表、成員服務、KV),若是沒有指定進程,當前值會被dump出來。

Consul Agent配置說明

在部署Consul集羣時,主要用到的是agent指令。這裏重點講一下agent指令的參數,agent有各類各樣的配置項能夠在命令行或者配置文件進行定義,全部的配置項都是可選擇的。存在相同配置定義時,後面定義的配置會合並前面定義的配置,但大多數狀況下合併的意思是後面定義的配置會覆蓋前面定義的配置。

  • 命令行參數

  1. -advertise:通知展示地址用來改變咱們給集羣中的其餘節點展示的地址,通常狀況下-bind地址就是展示地址

  2. -bootstrap:用來控制一個server是否在bootstrap模式,在一個datacenter中只能有一個server處於bootstrap模式,當一個server處於bootstrap模式時,能夠本身選舉爲raft leader。

  3. -bootstrap-expect:在一個datacenter中指望提供的server節點數目,當該值提供的時候,consul一直等到達到指定sever數目的時候纔會引導整個集羣,該標記不能和bootstrap公用。

  4. -bind:該地址用來在集羣內部的通信,集羣內的全部節點到地址都必須是可達的,默認是0.0.0.0。

  5. -client:consul綁定在哪一個client地址上,這個地址提供HTTP、DNS、RPC等服務,默認是127.0.0.1。

  6. -config-file:明確的指定要加載哪一個配置文件

  7. -config-dir:配置文件目錄,裏面全部以.json結尾的文件都會被加載

  8. -data-dir:提供一個目錄用來存放agent的狀態,全部的agent都須要該目錄,該目錄必須是穩定的,系統重啓後都繼續存在。

  9. -dc:該標記控制agent的datacenter的名稱,默認是dc1。

  10. -encrypt:指定secret key,使consul在通信時進行加密,key能夠經過consul keygen生成,同一個集羣中的節點必須使用相同的key。

  11. -join:加入一個已經啓動的agent的ip地址,能夠屢次指定多個agent的地址。若是consul不能加入任何指定的地址中,則agent會啓動失敗。默認agent啓動時不會加入任何節點。

  12. -retry-join:和join相似,可是容許你在第一次失敗後進行嘗試。

  13. -retry-interval:兩次join之間的時間間隔,默認是30s。

  14. -retry-max:嘗試重複join的次數,默認是0,也就是無限次嘗試。

  15. -log-level:consul agent啓動後顯示的日誌信息級別。默認是info,可選:trace、debug、info、warn、err。

  16. -node:節點在集羣中的名稱,在一個集羣中必須是惟一的,默認是該節點的主機名。

  17. -protocol:consul使用的協議版本。

  18. -rejoin:使consul忽略先前的離開,在再次啓動後仍舊嘗試加入集羣中。

  19. -server:定義agent運行在server模式,每一個集羣至少有一個server,建議每一個集羣的server不要超過5個。

  20. -syslog:開啓系統日誌功能,只在linux/osx上生效。

  21. -ui-dir:提供存放web ui資源的路徑,該目錄必須是可讀的。

  22. -pid-file:提供一個路徑來存放pid文件,可使用該文件進行SIGINT/SIGHUP(關閉/更新)agent。

更多參數說明可參考:https://www.consul.io/docs/agent/options.html

  • 配置文件

除了命令行參數外,配置也能夠寫入文件中。配置文件是json格式的,很容易編寫。配置文件不只被用來設置agent的啓動,也能夠用來提供健康檢測和服務發現的定義。

配置文件詳細參數說明:

  1. acl_datacenter:只用於server,指定的datacenter的權威ACL信息,全部的servers和datacenter必須贊成ACL datacenter

  2. acl_default_policy:默認是allow。

  3. acl_token:agent會使用這個token和consul server進行請求。

  4. acl_ttl:控制TTL的cache,默認是30s。

  5. addresses:一個嵌套對象,能夠設置如下key:dns、http、rpc。

  6. advertise_addr:等同於-advertise。

  7. bootstrap:等同於-bootstrap。

  8. bootstrap_expect:等同於-bootstrap-expect。

  9. bind_addr:等同於-bind。

  10. ca_file:提供CA文件路徑,用來檢查客戶端或者服務端的連接。

  11. cert_file:必須和key_file一塊兒。

  12. client_addr:等同於-client。

  13. datacenter:等同於-dc。

  14. data_dir:等同於-data-dir。

  15. disable_anonymous_signature:在進行更新檢查時禁止匿名簽名。

  16. disable_remote_exec:禁止支持遠程執行,設置爲true,agent會忽視全部進入的遠程執行請求。

  17. disable_update_check:禁止自動檢查安全公告和新版本信息。

  18. dns_config:是一個嵌套對象,能夠設置如下參數:allow_stale、max_stale、node_ttl 、service_ttl、enable_truncate。

  19. domain:默認狀況下consul在進行DNS查詢時查詢的是consul域,能夠經過該參數進行修改。

  20. enable_debug:開啓debug模式。

  21. enable_syslog:等同於-syslog。

  22. encrypt:等同於-encrypt。

  23. key_file:提供私鑰的路徑。

  24. leave_on_terminate:默認是false,若是爲true,當agent收到一個TERM信號的時候,它會發送leave信息到集羣中的其餘節點上。

  25. log_level:等同於-log-level。

  26. node_name:等同於-node。

  27. ports:這是一個嵌套對象,能夠設置如下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)。

  28. protocol:等同於-protocol。

  29. rejoin_after_leave:等同於-rejoin。

  30. retry_join:等同於-retry-join。

  31. retry_interval:等同於-retry-interval。

  32. server:等同於-server。

  33. server_name:會覆蓋TLS CA的node_name,能夠用來確認CA name和hostname相匹配。

  34. skip_leave_on_interrupt:和leave_on_terminate比較相似,不過隻影響當前句柄。

  35. start_join:一個字符數組提供的節點地址會在啓動時被加入。

  36. syslog_facility:當enable_syslog被提供後,該參數控制哪一個級別的信息被髮送,默認Local0。

  37. ui_dir:等同於-ui-dir。

  38. verify_incoming:默認false,若是爲true,則全部進入連接都須要使用TLS,須要客戶端使用ca_file提供ca文件。只用於consul server端,由於client歷來沒有進入的連接。

  39. verify_outgoing:默認false,若是爲true,則全部出去連接都須要使用TLS,須要服務端使用ca_file提供ca文件,consul server和client都須要使用,由於二者都有出去的連接。

  40. watches:watch一個詳細名單。

以啓動agent爲例:

# 建立配置文件
$ vim /opt/consul/conf/server.json

{
  "datacenter": "dc1",
  "data_dir": "/opt/consul/data",
  "log_level": "INFO",
  "node_name": "consul-server01",
  "server": true,
  "bootstrap_expect": 1,
  "bind_addr": "192.168.2.210",
  "client_addr": "192.168.2.210",
  "ui_dir": "/opt/consul/web",
  "retry_join": ["192.168.2.210","192.168.2.211","192.168.2.212"],
  "retry_interval": "30s",
  "enable_debug": false,
  "rejoin_after_leave": true,
  "start_join": ["192.168.2.210","192.168.2.211","192.168.2.212"],
  "enable_syslog": true,
  "syslog_facility": "local0"
}

# consul從配置目錄加載配置
$ consul agent -config-dir /opt/consul/conf/
# consul從配置文件加載配置
$ consul agent -config-file=server.json

Consul經常使用端口說明

  1. dns - The DNS server, -1 to disable. Default 8600.

  2. http - The HTTP API, -1 to disable. Default 8500.

  3. https - The HTTPS API, -1 to disable. Default -1 (disabled).

  4. rpc - The CLI RPC endpoint. Default 8400.

  5. serf_lan - The Serf LAN port. Default 8301.

  6. serf_wan - The Serf WAN port. Default 8302.

  7. server - Server RPC address. Default 8300.

部署集羣

部署Server端

這裏咱們一共要部署三個Server端,具體以下:

  • 在dev-master-01上部署

$ consul agent -server -bootstrap -syslog \
    -ui-dir=/opt/consul/web \
    -data-dir=/opt/consul/data \
    -config-dir=/opt/consul/conf \
    -pid-file=/opt/consul/run/consul.pid \
    -client=192.168.2.210 \
    -bind=192.168.2.210 \
    -node=consul-server01 \
    -disable-host-node-id

小提示:

  1. -bootstrap通常只在集羣初始化時使用一次。

  2. 最新版本是內置了Web的,直接使用-ui參數啓用就好了。

  • 在dev-node-01上部署

$ consul agent -server -syslog \
    -ui \
    -data-dir=/opt/consul/data \
    -config-dir=/opt/consul/conf \
    -pid-file=/opt/consul/run/consul.pid \
    -client=192.168.2.211 \
    -bind=192.168.2.211 \
    -node=consul-server02 \
    -disable-host-node-id
  • 在dev-node-02上部署

$ consul agent -server -syslog \
    -ui \
    -data-dir=/opt/consul/data \
    -config-dir=/opt/consul/conf \
    -pid-file=/opt/consul/run/consul.pid \
    -client=192.168.2.212 \
    -bind=192.168.2.212 \
    -node=consul-server03 \
    -disable-host-node-id

到此咱們已經啓動了三個Consul Server,這三個Consul Server如今還對彼此沒有任何感知。它們都爲單節點的集羣,每一個集羣都僅包含一個成員。運行consul members來驗證下。

因爲啓動Agent時綁定了IP地址,因此下面須要顯示指定IP地址。默認鏈接地址是127.0.0.1:8500

# dev-master-01
$ consul members --http-addr 192.168.2.210:8500
Node             Address             Status  Type    Build  Protocol  DC
consul-server01  192.168.2.210:8301  alive   server  0.8.1  2         dc1

# dev-node-01
$ consul members --http-addr 192.168.2.211:8500
Node             Address             Status  Type    Build  Protocol  DC
consul-server02  192.168.2.211:8301  alive   server  0.8.1  2         dc1

# dev-node-02
$ consul members --http-addr 192.168.2.212:8500
Node             Address             Status  Type    Build  Protocol  DC
consul-server03  192.168.2.212:8301  alive   server  0.8.1  2         dc1
  • 加入集羣

Consul發現機制

  • 當一個Consul代理啓動後,它並不知道其它節點的存在,它是一個孤立的單節點集羣。

  • 若是想感知到其它節點的存在,它必須加入到一個現存的集羣。

  • 要加入到一個現存的集羣,它只用加入集羣中任意一個現存的成員。

  • 當加入一個現存的成員後,會經過成員間的通信很快發現集羣中的其它成員。

  • 一個Consul代理能夠加入任意一個代理,而不只僅是服務節點。

爲了讓三個Server間能互相感知,這裏就要讓其它二個Server加入同一個集羣中。

a) Server02加入Server01

$ consul join --http-addr 192.168.2.211:8500 192.168.2.210

個人環境是三臺連接克隆的虛擬機,會報以下錯:

* Failed to join 192.168.2.210: Member 'consul-server01' has conflicting node ID 'b76ff298-accd-05ff-8c64-5d79d866dfa9' with this agent's ID

大體的意思是uuid衝突了,默認狀況下Consul將使用Consul數據目錄下node-id文件中的id,多是虛擬機緣由我三臺node-id竟然是同樣的。

解決方法有兩種:

一是在啓動agent的時候加入-disable-host-node-id參數,禁止生成node-id。相似這樣:

$ consul agent -server -bootstrap -syslog \
    -ui \
    -data-dir=/opt/consul/data \
    -config-dir=/opt/consul/conf \
    -pid-file=/opt/consul/run/consul.pid \
    -client=192.168.2.210 \
    -bind=192.168.2.210 \
    -node=consul-server01 \
    -disable-host-node-id

二是能夠用-node-id生成一個新的node-id,相似這樣:

$ consul agent -server -bootstrap -syslog \
    -ui-dir=/opt/consul/web \
    -data-dir=/opt/consul/data \
    -config-dir=/opt/consul/conf \
    -pid-file=/opt/consul/run/consul.pid \
    -client=192.168.2.210 \
    -bind=192.168.2.210 \
    -node=consul-server01 \
    -node-id=$(uuidgen | awk '{print tolower($0)}')

再次加入集羣:

$ consul join --http-addr 192.168.2.211:8500 192.168.2.210
Successfully joined cluster by contacting 1 nodes.

b) Server03加入Server01

$ consul join --http-addr 192.168.2.212:8500 192.168.2.210
Successfully joined cluster by contacting 1 nodes.

成功加入Server01節點後,從Server01上日誌能夠看出leader已選取出來:

...
    2017/05/10 13:54:37 [INFO] consul: cluster leadership acquired
    2017/05/10 13:54:37 [INFO] consul: New leader elected: consul-server01
    2017/05/10 13:54:37 [INFO] consul: member 'consul-server01' joined, marking health alive
...

此時在dev-master-01節點上查當作員狀態,彼此都能互識。

# dev-master-01
$ consul members --http-addr 192.168.2.210:8500
Node             Address             Status  Type    Build  Protocol  DC
consul-server01  192.168.2.210:8301  alive   server  0.8.1  2         dc1
consul-server02  192.168.2.211:8301  alive   server  0.8.1  2         dc1
consul-server03  192.168.2.212:8301  alive   server  0.8.1  2         dc1

經過HTTP API方式查詢,在三個節點上任意一個節點執行:

# 查詢集羣leader
$ curl 192.168.2.210:8500/v1/status/leader
"192.168.2.210:8300"

# 查詢集羣成員
$ curl 192.168.2.210:8500/v1/status/peers
["192.168.2.210:8300","192.168.2.211:8300","192.168.2.212:8300"]

經過DNS方式來查詢節點信息

查詢結構爲NAME.node.consulNAME.node.DATACENTER.consul。以查詢consul-server01爲例:

$ dig @192.168.2.210 -p 8600 consul-server01.node.consul

;; QUESTION SECTION:
;consul-server01.node.consul.    IN    A

;; ANSWER SECTION:
consul-server01.node.consul. 0    IN    A    192.168.2.210

;; Query time: 1 msec
;; SERVER: 192.168.2.210#8600(192.168.2.210)
;; WHEN: Wed May 10 16:54:08 CST 2017
;; MSG SIZE  rcvd: 61

$ dig  @192.168.2.210 -p 8600 consul-server01.node.dc1.consul

;; QUESTION SECTION:
;consul-server01.node.dc1.consul. IN    A

;; ANSWER SECTION:
consul-server01.node.dc1.consul. 0 IN    A    192.168.2.210

;; Query time: 0 msec
;; SERVER: 192.168.2.210#8600(192.168.2.210)
;; WHEN: Wed May 10 16:55:50 CST 2017
;; MSG SIZE  rcvd: 65

注意:

  • 若是有多個成員,也只用加入一個節點,其它節點會在這個節點加入集羣后經過成員間的通信相互發現。

  • 確保全部節點TCP或UDP的8301是開放的,節點間的通信得依賴這個端口,不然沒法加入。

  • 確保全部節點TCP的8300是開放的,由於Client向Server的RPC得依賴這個端口,不打開沒法同步。

部署Client端

該節點是Client角色,因此咱們不指定它啓動爲服務器模式。

# 在dev-node-03上部署
$ consul agent -syslog \
    -data-dir=/opt/consul/data \
    -config-dir=/opt/consul/conf \
    -pid-file=/opt/consul/run/consul.pid \
    -client=192.168.2.213 \
    -bind=192.168.2.213 \
    -join=192.168.2.210 \
    -node=consul-client01 \
    -disable-host-node-id

這裏啓動的時候就會自動加入一個已有集羣,由於啓動時加入了-join參數,該參數能夠自動加入一個已知Consul集羣。啓動Server角色的Agent的也是能夠自動加入的,上面手動加入是爲了更好的說明整個過程。

# 查詢集羣成員
$ consul members --http-addr 192.168.2.210:8500
Node             Address             Status  Type    Build  Protocol  DC
consul-client01  192.168.2.213:8301  alive   client  0.8.1  2         dc1
consul-server01  192.168.2.210:8301  alive   server  0.8.1  2         dc1
consul-server02  192.168.2.211:8301  alive   server  0.8.1  2         dc1
consul-server03  192.168.2.212:8301  alive   server  0.8.1  2         dc1
服務註冊

consul進行服務註冊提供了兩種方式(HTTP API以及配置文件指定),在這裏咱們使用配置文件的方式:

在dev-master-01上的consul配置目錄下創建一個服務文件:

$ vim /opt/consul/conf/web.json
{"service": {"name": "web", "tags": ["master"], "port": 8080,
"check": {"http": "http://127.0.0.1:8080", "interval": "10s"}}}

這個服務文件的大意是:註冊了一個名稱是web,運行在8080端口的服務。而且義了一個健康檢查。

經過consul reload進行熱註冊

$ consul reload --http-addr=192.168.2.210:8500
Configuration reload triggered

此時consul會不斷的進行報錯,由於這裏進行了健康檢查。

$ tail -f  /var/log/consul/consul.log
May 11 11:45:36 dev-master-01 consul[11226]: agent: http request failed 'http://127.0.0.1:8080': Get http://127.0.0.1:8080: dial tcp 127.0.0.1:8080: getsockopt: connection refused

用Python啓動一個SimpleHTTPServer進行驗證。

$ python -m SimpleHTTPServer 8080
Serving HTTP on 0.0.0.0 port 8080 ...

再次檢查consul日誌,一切正常。

$ tail -f  /var/log/consul/consul.log
May 11 11:50:57 dev-master-01 consul[11226]: agent: Synced check 'service:web'

注:這裏日誌是啓用了Syslog的狀況,因此日誌位置在/var/log/consul/consul.log。在沒有啓用Syslog的狀況下,默認會直接輸出到終端的。有關Syslog日誌啓用方法本文後面會講。

服務發現

服務發現也能夠經過HTTP API和DNS兩種方式進行,全部查詢都在Consul Client角色的機器上進行,以驗證Client的正常工做狀況。這裏以DNS查詢方式爲例:

$ dig @192.168.2.213 -p 8600 web.service.consul SRV

;; QUESTION SECTION:
;web.service.consul.        IN    SRV

;; ANSWER SECTION:
web.service.consul.    0    IN    SRV    1 1 8080 consul-server01.node.dc1.consul.

;; ADDITIONAL SECTION:
consul-server01.node.dc1.consul. 0 IN    A    192.168.2.210

停掉剛纔啓動的web服務,再次查詢就沒有的web服務了。

$ ps uax|grep python
root     12764  0.4  0.6  41120 13136 pts/0    S+   12:04   0:00 python -m SimpleHTTPServer 8080
$ kill 12764
$ dig @192.168.2.213 -p 8600 web.service.consul SRV
 ;; QUESTION SECTION:
 ;web.service.consul.        IN    SRV

 ;; AUTHORITY SECTION:
 consul.            0    IN    SOA    ns.consul. postmaster.consul. 1494475592 3600 600 86400 0

最後在Consul Web界面看一下成果

圖片

脫離集羣

可使用Ctrl-C來平滑退出,也能夠強行Kill退出。區別是主動告知其它節點本身的離開,和被其它節點標記爲失效。這裏要注意,在集羣中平滑退出是很重要的。

一些技巧

給Consul建立Systemd服務

Consul默認是在前臺運行的,爲了方便管理咱們建立一個Systemd服務。

這裏以建立一個Consul Server端爲例:

  • 建立一個用於啓動Consul的專有用戶

$ useradd -M -s /sbin/nologin consul
$ chown -R consul.consul /opt/consul/
  • 建立配置文件

這個配置文件裏面內容是啓動Consul Agent的參數。

$ vim /etc/default/consul
CONSUL_FLAGS="-server -bootstrap -syslog -ui -data-dir=/opt/consul/data -config-dir=/opt/consul/conf -pid-file=/opt/consul/run/consul.pid -client=192.168.2.210 -bind=192.168.2.210 -node=consul-server01 -disable-host-node-id"
  • 建立Systemd配置文件

$ vim /etc/systemd/system/consul.service

[Unit]
Description=Consul service discovery agent
Requires=network-online.target
After=network-online.target

[Service]
User=consul
Group=consul
EnvironmentFile=-/etc/default/consul
Environment=GOMAXPROCS=2
Restart=on-failure
ExecStartPre=[ -f "/opt/consul/run/consul.pid" ] && /usr/bin/rm -f /opt/consul/run/consul.pid
ExecStartPre=/usr/local/bin/consul configtest -config-dir=/opt/consul/conf
ExecStart=/usr/local/bin/consul agent $CONSUL_FLAGS
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGTERM
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target

這時Kill用的SIGTERM信號,由於SIGTERM信號在集羣環境下能夠避免leader重選。SIGINT和SIGTERM的區別:

  1. SIGINT與字符ctrl+c關聯,SIGTERM沒有任何控制字符關聯。

  2. SIGINT只能結束前臺進程,SIGTERM則不是。

  3. SIGTERM能夠被阻塞、處理和忽略。KILL命令的默認不帶參數發送的信號就是SIGTERM,SIGTERM可讓程序優雅的退出。

  • 啓動Consul

$ systemctl start consul.service
  • 驗證是否啓動成功

$ systemctl status  consul.service
● consul.service - Consul service discovery agent
   Loaded: loaded (/etc/systemd/system/consul.service; disabled; vendor preset: enabled)
   Active: active (running) since Thu 2017-05-11 10:50:14 CST; 4s ago
  Process: 8894 ExecStartPre=/usr/local/bin/consul configtest -config-dir=/opt/consul/conf (code=exited, status=0/SUCCESS)
 Main PID: 8902 (consul)
    Tasks: 9
   Memory: 4.7M
      CPU: 154ms
   CGroup: /system.slice/consul.service
           └─8902 /usr/local/bin/consul agent -server -bootstrap -syslog -ui -data-dir=/opt/consul/data -config-dir=/opt/consul/conf -pid-file=/opt/consul/run/consul.pid -client=192.168.2.210 -bind=192.168.2.210 -node=consul-server01 -disable-host-node-id

May 11 10:50:14 dev-master-01 consul[8902]:       Cluster Addr: 192.168.2.210 (LAN: 8301, WAN: 8302)
May 11 10:50:14 dev-master-01 consul[8902]:     Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false
May 11 10:50:14 dev-master-01 consul[8902]:              Atlas: <disabled>
May 11 10:50:14 dev-master-01 consul[8902]: ==> Log data will now stream in as it occurs:
May 11 10:50:14 dev-master-01 consul[8902]:     2017/05/11 10:50:14 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:192.168.2.210:8300 Address:192.168.2.210:8300}]
May 11 10:50:14 dev-master-01 consul[8902]:     2017/05/11 10:50:14 [INFO] raft: Node at 192.168.2.210:8300 [Follower] entering Follower state (Leader: "")
May 11 10:50:14 dev-master-01 consul[8902]:     2017/05/11 10:50:14 [INFO] serf: EventMemberJoin: consul-server01 192.168.2.210
May 11 10:50:14 dev-master-01 consul[8902]:     2017/05/11 10:50:14 [INFO] consul: Adding LAN server consul-server01 (Addr: tcp/192.168.2.210:8300) (DC: dc1)
May 11 10:50:14 dev-master-01 consul[8902]:     2017/05/11 10:50:14 [INFO] serf: EventMemberJoin: consul-server01.dc1 192.168.2.210
May 11 10:50:14 dev-master-01 consul[8902]:     2017/05/11 10:50:14 [INFO] consul: Handled member-join event for server "consul-server01.dc1" in area "wan"

給Consul配置Syslog日誌

Consul默認是把日誌輸出到前臺,爲了方便管理咱們用Syslog將日誌管理起來。

  • 建立日誌存放目錄並賦權

$ mkdir -p /var/log/consul/
$ chown -R syslog.syslog /var/log/consul/
  • 啓用系統日誌

# 建立日誌配置文件
$ cat >/etc/rsyslog.d/consul.conf <<EOF
local0.* /var/log/consul/consul.log
EOF

# 修改默認配置文件中的如下內容
$ vim /etc/rsyslog.d/50-default.conf

# 變動前
*.*;auth,authpriv.none          -/var/log/syslog

# 變動後
*.*;auth,authpriv.none,local0.none          -/var/log/syslog

# 重啓rsyslog讓配置生效。
$ systemctl restart rsyslog

# 建立日誌輪循規則
$ cat >/etc/logrotate.d/consul <<EOF
/var/log/consul/*log {
missingok
compress
notifempty
daily
rotate 5
create 0600 root root
}
EOF
  • 配置Consul

若是要在consul agent中啓用Syslog日誌,必定要在啓動時加入-syslog參數。相似這樣:

$ consul agent -server -bootstrap -syslog -ui -data-dir=/opt/consul/data -config-dir=/opt/consul/conf -pid-file=/opt/consul/run/consul.pid -client=192.168.2.210 -bind=192.168.2.210 -node=consul-server01 -disable-host-node-id
  • 確認Syslog日誌生效

重啓服務後,就會在相應目錄看到日誌。

$ tail -f  /var/log/consul/consul.log
May 11 11:06:05 dev-master-01 consul[9891]: serf: Failed to re-join any previously known node
May 11 11:06:05 dev-master-01 consul[9891]: consul: Handled member-join event for server "consul-server01.dc1" in area "wan"
May 11 11:06:12 dev-master-01 consul[9891]: agent: failed to sync remote state: No cluster leader
May 11 11:06:13 dev-master-01 consul[9891]: raft: Heartbeat timeout from "" reached, starting election
May 11 11:06:13 dev-master-01 consul[9891]: raft: Node at 192.168.2.210:8300 [Candidate] entering Candidate state in term 4
May 11 11:06:13 dev-master-01 consul[9891]: raft: Election won. Tally: 1
May 11 11:06:13 dev-master-01 consul[9891]: raft: Node at 192.168.2.210:8300 [Leader] entering Leader state
May 11 11:06:13 dev-master-01 consul[9891]: consul: cluster leadership acquired
May 11 11:06:13 dev-master-01 consul[9891]: consul: New leader elected: consul-server01
May 11 11:06:14 dev-master-01 consul[9891]: agent: Synced node i
相關文章
相關標籤/搜索