簡介
這個章節(jié)中的內(nèi)容包含一系列運維高級指南,包括高級網(wǎng)絡(luò)配置、安全設(shè)置、中斷恢復(fù)、監(jiān)控和故障排除。
Consul集群監(jiān)控和指標
用戶在設(shè)置完數(shù)據(jù)中心之后,需要確保部署正常并建立基準指標。本指南將從兩大部分介紹幾種類型的指標:Consul健康指標和服務(wù)器健康指標。
Consul健康指標:
- 事務(wù)時間(Transaction Timing)
- 領(lǐng)導(dǎo)者變更(Leadership Changes)
- 自動駕駛(Autopilot)
- 垃圾回收(Garbage Collection)
服務(wù)器健康指標:
- 文件描述符(File Descriptors)
- CPU使用率(CPU Usage)
- 網(wǎng)絡(luò)活動(Network Activity)
- 磁盤活動(Disk Activity)
- 內(nèi)存使用情況(Memory Usage)
對于每個指標,我們會闡述其重要性所在,也會確定指標數(shù)值,判定健康及不健康狀態(tài)。
首先,我們需要了解三種收集指標的方法:SIGUSR1、HTTP API、telemetry。在開始閱讀本指南前,建議用戶已經(jīng)配置了ACL。
如何收集指標
總共有三種收集指標的方案。第一個,也是最簡單的方法是使用SIGUSR1一次性轉(zhuǎn)儲當(dāng)前測量值;第二種方法是使用HTTP API獲得類似的一次性轉(zhuǎn)儲;第三種方法(也是最常用于長期監(jiān)視的一種方法)是在Consul配置文件中啟用telemetry。
本地使用
為了獲得當(dāng)前指標的一次性轉(zhuǎn)儲,我們可以將SIGUSR1信號發(fā)送到Consul進程。
kill -USR1 <process_id>
輸出內(nèi)容將發(fā)送到系統(tǒng)日志,例如/var/log/messages或journald。如果用戶正在通過Consul監(jiān)聽器監(jiān)控終端中的Consul流程,會在輸出中看到指標信息。
盡管這是快速了解單個Consul代理運行狀況的最簡單方法,但隨時間變化查看指標情況更有意義。
API GET請求
接下來,我們使用HTTP API快速收集指標:
curl http://127.0.0.1:8500/v1/agent/metrics
在生產(chǎn)中,用戶會使用ACL令牌設(shè)置憑據(jù)并啟用TLS以進行安全通信。一旦配置了ACL,就需要在請求中傳遞令牌。
curl --header "X-Consul-Token: <YOUR_ACL_TOKEN>" \
https://127.0.0.1:8500/v1/agent/metrics
這是一種快速收集指標的好方法,除此之外還可以將其添加到腳本中,或者與支持HTTP抓取數(shù)據(jù)的監(jiān)控代理(例如Prometheus)一起使用,做到數(shù)據(jù)可視化。
啟用telemetry
最后,我們可以配置Consul將遙測數(shù)據(jù)發(fā)送到遠程監(jiān)控系統(tǒng)。這樣,用戶就可以在時間維度上監(jiān)控代理的運行狀態(tài),發(fā)現(xiàn)指標趨勢,并為將來的需求提前進行計劃。為此,用戶需要監(jiān)控代理程序和一個控制臺。
Consul支持以下遙測(telemetry)代理:
- Circonus
- DataDog(通過
dogstatsd) - StatsD(通過
statsd、statsite、telegraf等)
如果用戶使用的是StatsD,則還需要兼容的數(shù)據(jù)庫和服務(wù)器,例如Grafana、Chronograf或Prometheus。
用戶可以在配置文件(例如server.hcl)中配置遙測(telemetry),客戶端或服務(wù)端都支持遙測。通常,用戶至少要在所有服務(wù)端上啟用它(無論有表決權(quán)或無表決權(quán)),這樣可以監(jiān)控整個數(shù)據(jù)中心的運行狀況。
將遙測發(fā)送到DataDog的server.hcl示例片段如下:
telemetry {
dogstatsd_addr = "localhost:8125"
disable_hostname = true
}
在現(xiàn)有數(shù)據(jù)中心上啟用遙測時,需要重新加載Consul進程。這可以通過consul reload或kill -HUP <process_id>來完成,建議從非領(lǐng)導(dǎo)者開始,一次重裝一臺機器。
Consul健康指標
Consul健康指標顯示有關(guān)Consul數(shù)據(jù)中心的信息。它們包括鍵值存儲(key value store),事務(wù)(transaction),raft協(xié)議,領(lǐng)導(dǎo)者變更(leadership changes),自動駕駛調(diào)整(autopilot tuning)和垃圾收集(garbage collection)的性能指標。
事務(wù)時間(Transaction Timing)
以下指標表示完成各個部分寫入操作所花費的時間(包括Consul KV和Consul服務(wù)器Raft)。通常,這些值應(yīng)保持大致一致,且每個值均不超過幾毫秒。
| 指標名 | 描述 |
|---|---|
| consul.kvs.apply | 完成KV Store更新所需的時間 |
| consul.txn.apply | 完成事務(wù)操作所需的時間 |
| consul.raft.apply | 周期時間內(nèi)發(fā)生的Raft事務(wù)數(shù) |
| consul.raft.commitTime | 提交一條Raft日志到領(lǐng)導(dǎo)者上所需的時間 |
Consul服務(wù)器的負載異?;蚍?wù)器本身出現(xiàn)問題會造成時間值發(fā)生突變。 具體來說,如果這些指標中的任何一個指標,偏離上一個小時內(nèi)的基線超過50%,則表明存在問題,以下是事務(wù)健康指標的示例:
'consul.raft.apply': Count: 1 Sum: 1.000 LastUpdated: 2018-11-16 10:55:03.673805766 -0600 CST m=+97598.238246167
'consul.raft.commitTime': Count: 1 Sum: 0.017 LastUpdated: 2018-11-16 10:55:03.673840104 -0600 CST m=+97598.238280505
領(lǐng)導(dǎo)者變更(Leadership Changes)
在健康的環(huán)境中,Consul數(shù)據(jù)中心應(yīng)具有穩(wěn)定的領(lǐng)導(dǎo)者。 除非用戶手動更改領(lǐng)導(dǎo)者(比如將服務(wù)器從群集中移出),否則不應(yīng)進行任何領(lǐng)導(dǎo)者更改。 如果發(fā)生意外選舉或領(lǐng)導(dǎo)者變更,則應(yīng)調(diào)查Consul服務(wù)器之間是否存在網(wǎng)絡(luò)問題,另一個可能的原因是Consul服務(wù)器無法跟上事務(wù)負載。
注意:下列度量標準來自跟隨者節(jié)點(follower nodes),而非領(lǐng)導(dǎo)者(leader):
| 指標名 | 描述 |
|---|---|
| consul.raft.leader.lastContact | 測量領(lǐng)導(dǎo)者最后一次連接到追隨者確認領(lǐng)導(dǎo)者租期(leader lease)的時間 |
| consul.raft.state.candidate | 當(dāng)Consul服務(wù)器發(fā)起一次選舉時累加 |
| consul.raft.state.leader | 當(dāng)Consul服務(wù)器變成領(lǐng)導(dǎo)者時累加 |
如果candidate或leader指標大于0或者lastContact指標大于200ms,則應(yīng)排除上述可能的原因之一,這是領(lǐng)導(dǎo)者健康指標的示例:
'consul.raft.leader.lastContact': Count: 4 Min: 10.000 Mean: 31.000 Max: 50.000 Stddev: 17.088 Sum: 124.000 LastUpdated: 2018-12-17 22:06:08.872973122 +0000 UTC m=+3553.639379498
'consul.raft.state.leader': Count: 1 Sum: 1.000 LastUpdated: 2018-12-17 22:05:49.104580236 +0000 UTC m=+3533.870986584
'consul.raft.state.candidate': Count: 1 Sum: 1.000 LastUpdated: 2018-12-17 22:05:49.097186444 +0000 UTC m=+3533.863592815
自動駕駛(Autopilot)
有兩個自動駕駛指標也可以告知Consul數(shù)據(jù)中心的運行狀況。
| 指標名 | 描述 |
|---|---|
| consul.autopilot.healthy | 跟蹤本地服務(wù)器群集的整體運行狀況 |
| consul.autopilot.failure_tolerance | 跟蹤本地服務(wù)器群集可能丟失的表決服務(wù)器數(shù)量 |
consul.autopilot.healthy指標為布爾值,1表示健康,0表示不健康。返回值為0時應(yīng)該發(fā)出警報,下面是運行狀況良好的數(shù)據(jù)中心的示例:
[2018-12-17 13:03:40 -0500 EST][G] 'consul.autopilot.healthy': 1.000
consul.autopilot.failure_tolerance指標表示數(shù)據(jù)中心在進入不健康狀態(tài)前可能會丟失多少個Consul服務(wù)器,返回值為0時應(yīng)該發(fā)出警報,以便采取積極措施來保證數(shù)據(jù)中心正常運行。
垃圾回收(Garbage Collection)
垃圾回收暫停是一個STW事件,所有運行時線程都將被阻塞,直到GC完成。在健康的環(huán)境中,這些暫停僅應(yīng)持續(xù)幾納秒。如果內(nèi)存使用率很高,則Go運行時可能會頻繁啟動GC進程,以至于減慢Consul的速度。用戶可能會觀察到領(lǐng)導(dǎo)人選舉變得更頻繁,寫入時間也會變長。
| 指標名 | 描述 |
|---|---|
| consul.runtime.total_gc_pause_ns | 自Consul啟動以來,垃圾收集STW暫停消耗的時間 |
如果返回值大于2s/min,則需要調(diào)查具體原因,如果每分鐘超過5秒,則應(yīng)任務(wù)數(shù)據(jù)中心處于緊急狀態(tài),下面是健康的GC暫停時間示例:
'consul.runtime.total_gc_pause_ns': 136603664.000
注意,total_gc_pause_ns是一個累積計數(shù)器,因此,為了計算速率(例如每分鐘的GC時間),需要使用諸如non_negative_difference之類的函數(shù)。
服務(wù)器健康指標
服務(wù)器指標提供有關(guān)數(shù)據(jù)中心運行狀況的信息,包括文件描述符、CPU使用率、網(wǎng)絡(luò)活動、磁盤活動和內(nèi)存使用情況。
文件描述符(File Descriptors)
大多數(shù)Consul操作都需要文件描述符句柄,包括接收來自另一臺主機的連接,在服務(wù)器之間發(fā)送數(shù)據(jù)以及將快照寫入磁盤。如果Consul用完了句柄,它將停止接受連接。
| 指標名 | 描述 |
|---|---|
| linux_sysctl_fs.file-nr | 在主機上所有進程中使用的文件句柄數(shù) |
| linux_sysctl_fs.file-max | 可用文件句柄的總數(shù) |
默認情況下,進程和內(nèi)核的限制是保守的,用戶可能希望將限制增加到默認值以外。如果linux_sysctl_fs.file-nr值超過linux_sysctl_fs.file-max的80%,則應(yīng)增加文件句柄,以下是文件句柄指標的示例:
linux_sysctl_fs, host=statsbox, file-nr=768i, file-max=96763i
CPU使用率(CPU Usage)
Consul無論是服務(wù)端或客戶端都不是CPU密集型服務(wù),CPU使用率過高表示一次性執(zhí)行了太多操作。
| 指標名 | 描述 |
|---|---|
| cpu.user_cpu | 用戶進程(例如Vault或Consul)使用CPU的百分比 |
| cpu.iowait_cpu | 等待I/O任務(wù)花費的CPU時間百分比 |
如果cpu.iowait_cpu大于10%,對Consul來說是比較嚴重的問題,表明Consul正在等待將數(shù)據(jù)寫入磁盤,有可能是Raft將快照寫入磁盤的頻率過于頻繁,以下是運行狀況良好的CPU指標的示例:
cpu, cpu=cpu-total, usage_idle=99.298, usage_user=0.400, usage_system=0.300, usage_iowait=0, usage_steal=0
網(wǎng)絡(luò)活動(Network Activity)
網(wǎng)絡(luò)活動應(yīng)大體保持一致,Consul網(wǎng)絡(luò)流量突然激增可能是由于客戶端(例如Vault)配置錯誤而導(dǎo)致請求過多,大多數(shù)代理會針對每個網(wǎng)絡(luò)接口報告單獨的指標,因此用戶需要確保正在監(jiān)視正確的指標。
| 指標名 | 描述 |
|---|---|
| net.bytes_recv | 每個網(wǎng)絡(luò)接口上收到的字節(jié) |
| net.bytes_sent | 每個網(wǎng)絡(luò)接口上傳輸?shù)淖止?jié) |
網(wǎng)絡(luò)指標突然增加,與基線之間的偏差大于50%,表示有太多請求未得到處理,以下是網(wǎng)絡(luò)活動指標的示例:
net, interface=enp0s5, bytes_sent=6183357i, bytes_recv=262313256i
注意:網(wǎng)絡(luò)指標是累積計數(shù)器,因此如果計算速率(例如字節(jié)/秒),用戶需要應(yīng)用諸如non_negative_difference之類的函數(shù)。
磁盤活動(Disk Activity)
通常情況下,因為Consul將所有內(nèi)容保留在內(nèi)存中,磁盤活動較少。如果Consul主機正在將大量數(shù)據(jù)寫入磁盤,則意味著Consul可能有較重的寫入負載,因此經(jīng)常將Raft快照頻繁寫入磁盤。也有可能在生產(chǎn)中意外啟用了調(diào)試/跟蹤(debug/trace)日志記錄,這可能會影響性能。
| 指標名 | 描述 |
|---|---|
| diskio.read_bytes | 從塊設(shè)備讀取的字節(jié) |
| diskio.write_bytes | 寫入塊設(shè)備的字節(jié) |
| diskio.read_time | 讀取磁盤花費的時間,單位是毫秒 |
| diskio.write_time | 寫入磁盤花費的時間,單位為毫秒 |
磁盤度量指標突然發(fā)生較大變化,與基準偏差大于50%或與基準的偏差大于3個標準偏差,表示Consul的磁盤I/O過多。磁盤I/O過多會導(dǎo)致系統(tǒng)其余部分變慢或不可用,因為內(nèi)核會花費所有時間等待I/O完成。以下是磁盤活動指標的示例:
diskio, name=sda5, read_bytes=522298368i, write_bytes=1726865408i, read_time=7248i, write_time=133364i
內(nèi)存使用情況(Memory Usage)
如前所述,Consul將其所有數(shù)據(jù)(KV存儲,目錄(catalog)等)均保留在內(nèi)存中。如果Consul消耗了所有可用內(nèi)存,系統(tǒng)將崩潰。用戶應(yīng)該監(jiān)控可用內(nèi)存,確保某些內(nèi)存可用于其他系統(tǒng)進程,并且交換使用率(swap usage)應(yīng)保持在0%,以獲得最佳性能。
| 指標名 | 描述 |
|---|---|
| consul.runtime.alloc_bytes | Consul進程分配的內(nèi)存字節(jié)數(shù) |
| consul.runtime.sys_bytes | 從操作系統(tǒng)獲取的內(nèi)存字節(jié)數(shù) |
| mem.total | 服務(wù)器上可用的內(nèi)存總量 |
| mem.used_percent | 正在使用的內(nèi)存百分比 |
| swap.used_percent | 正在使用的交換空間百分比 |
如果sys_bytes超過total_bytes的90%,mem.used_percent超過90%或swap.used_percent大于0,則表明Consul服務(wù)器的內(nèi)存不足。如果滿足以下三個條件任一,則應(yīng)增加Consul可用的內(nèi)存,以下是內(nèi)存使用情況指標的示例:
'consul.runtime.alloc_bytes': 11199928.000
'consul.runtime.sys_bytes': 24627448.000
mem, used_percent=31.492, total=1036312576i
swap, used_percent=1.343
使用Telegraf監(jiān)控Consul
Consul提供了一系列各式各樣的指標,運維人員可以通過它們衡量集群的運行狀況和穩(wěn)定性,診斷或者預(yù)測潛在的問題?,F(xiàn)實場景中,有許多監(jiān)控工具可供參考,在這篇指南中,我們將結(jié)合使用Telegraf_plugin和Consul支持的StatsD協(xié)議。
用戶可以閱讀telemetry文檔,了解Consul可用指標的完整列表。
在本指南中,用戶可以看到:
- 配置Telegraf收集
StatsD和主機級別指標; - 配置Consul將指標發(fā)送到
Telegraf; - 可視化指標示例;
- 了解重要指標進行匯總并發(fā)出警報。
安裝Telegraf
Telegraf的安裝依賴用戶的操作系統(tǒng),我們建議用戶遵循官方的Telegraf安裝文檔。
配置Telegraf
Telegraf充當(dāng)StatsD代理,可以收集Consul所在運行機器的其他指標。Telegraf本身附帶了各種各樣的輸入(input)插件,可以收集很多數(shù)據(jù)源。
我們將啟用一些最常用的輸入插件來監(jiān)控CPU,內(nèi)存,磁盤I/O,網(wǎng)絡(luò)和進程狀態(tài),它們對于調(diào)試Consul群集問題很有幫助。
telegraf.conf文件以全局選項(global options)開頭:
[agent]
interval = "10s"
flush_interval = "10s"
omit_hostname = false
我們默認將收集間隔時間設(shè)置為10秒,并要求Telegraf在每個指標中包含一個主機(host)標簽。
如上所述,Telegraf還允許用戶在度量標準上設(shè)置其他標簽。這里,我們將為服務(wù)器角色和數(shù)據(jù)中心名稱添加了標簽,之后我們可以在Grafana中使用這些標簽來過濾查詢(例如,創(chuàng)建僅顯示具有consul-server角色的服務(wù)器或us-east-1數(shù)據(jù)中心中的服務(wù)器的儀表板)。
[global_tags]
role = "consul-server"
datacenter = "us-east-1"
接下來,我們在8125端口上使用UDP設(shè)置StatsD監(jiān)聽器,傳輸?shù)男畔馕?code>DogStatsD-compatible標簽:
[[inputs.statsd]]
protocol = "udp"
service_address = ":8125"
delete_gauges = true
delete_counters = true
delete_sets = true
delete_timings = true
percentiles = [90]
metric_separator = "_"
parse_data_dog_tags = true
allowed_pending_messages = 10000
percentile_limit = 1000
現(xiàn)在,我們可以為CPU,內(nèi)存,網(wǎng)絡(luò)I/O和磁盤I/O等配置輸入,它們中的大多數(shù)不需要任何配置,這里需要確保inputs.net中的interfaces名稱與在ifconfig中看到的interfaces名稱匹配:
[[inputs.cpu]]
percpu = true
totalcpu = true
collect_cpu_time = false
[[inputs.disk]]
# mount_points = ["/"]
# ignore_fs = ["tmpfs", "devtmpfs"]
[[inputs.diskio]]
# devices = ["sda", "sdb"]
# skip_serial_number = false
[[inputs.kernel]]
# no configuration
[[inputs.linux_sysctl_fs]]
# no configuration
[[inputs.mem]]
# no configuration
[[inputs.net]]
interfaces = ["enp0s*"]
[[inputs.netstat]]
# no configuration
[[inputs.processes]]
# no configuration
[[inputs.swap]]
# no configuration
[[inputs.system]]
# no configuration
另一個實用的插件是procstat插件,它可以報告用戶選擇的進程的指標:
[[inputs.procstat]]
pattern = "(consul)"
Telegraf還有一個插件,該插件使用Consul API查詢數(shù)據(jù),監(jiān)控Consul代理的運行狀況:
[[inputs.consul]]
address = "localhost:8500"
scheme = "http"
Consul的Telegraf配置
Consul將遙測數(shù)據(jù)發(fā)送到Telegraf,就像在代理配置中添加遙測部分一樣簡單:
{
"telemetry": {
"dogstatsd_addr": "localhost:8125",
"disable_hostname": true
}
}
如上所述,我們只需要指定兩個選項。dogstatsd_addr指定StatsD守護程序的主機名和端口號。
這里注意,我們指定了DogStatsD格式,而不是默認的StatsD,這樣Consul在發(fā)送指標時會攜帶標簽。Grafana可以使用標簽來過濾儀表板上的數(shù)據(jù)(例如,僅顯示role=consul-server的數(shù)據(jù)。)Telegraf與DogStatsD格式兼容,并且允許我們添加自己的標簽。
第二個選項告訴Consul不要在發(fā)送到StatsD的指標中插入主機名,因為主機名將作為標簽發(fā)送。如果沒有此選項,單個度量指標consul.raft.apply將成為多個度量指標:
consul.server1.raft.apply
consul.server2.raft.apply
consul.server3.raft.apply
如果用戶使用其他代理(例如Circonus、Statsite或Plain StatsD),則可能需要更改此配置。
Consul Telegraf指標可視化
用戶可以使用Grafana或Chronograf之類的工具對Telegraf中的數(shù)據(jù)進行可視化,這是Grafana儀表盤示例:

多數(shù)據(jù)中心間的ACL復(fù)制
用戶可以配置令牌、策略和角色跨多個數(shù)據(jù)中心工作。ACL復(fù)制有以下幾個好處:
- 它支持在多個數(shù)據(jù)中心之間對
節(jié)點和服務(wù)進行身份驗證; - 從數(shù)據(jù)中心可以為在主數(shù)據(jù)中心中創(chuàng)建的所有ACL組件提供故障轉(zhuǎn)移;
- 共享策略減少運維人員的冗余操作。
先決條件
在開始本章節(jié)之前,每個數(shù)據(jù)中心都需要啟用ACL,使用ACL增強Consul安全性章節(jié)中已經(jīng)詳細講述了配置過程,本章節(jié)會覆蓋其未涵蓋的Consul代理的ACL復(fù)制配置。此外,WAN Gossip通信是必須的。
簡介
在本指南中,用戶將配置ACL復(fù)制,其中包含以下過程:
- 在主數(shù)據(jù)中心中的所有Consul代理上設(shè)置
primary_datacenter參數(shù); - 創(chuàng)建復(fù)制令牌;
- 在從數(shù)據(jù)中心中的所有Consul代理上配置
primary_datacenter參數(shù); - 在從數(shù)據(jù)中心中的服務(wù)器上啟用令牌復(fù)制;
- 將復(fù)制令牌應(yīng)用于從數(shù)據(jù)中心中的所有服務(wù)器。
配置主數(shù)據(jù)中心
注意,如果主數(shù)據(jù)中心使用默認數(shù)據(jù)中心名稱dc1,則必須在從數(shù)據(jù)中心上設(shè)置一個不同的數(shù)據(jù)中心名稱。否則,兩個數(shù)據(jù)中心都將被命名為dc1,發(fā)生沖突。
Consul服務(wù)端和客戶端
即使默認情況下主數(shù)據(jù)中心已經(jīng)啟用了,用戶需要在所有服務(wù)端和客戶端都顯式設(shè)置primary_datacenter參數(shù),代理配置如下所示:
{
"datacenter": "primary_dc",
"primary_datacenter": "primary_dc",
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"enable_token_persistence": true
}
}
primary_datacenter參數(shù)設(shè)置主數(shù)據(jù)中心具有所有ACL信息權(quán)限??蛻舳艘餐瑯有枰渲?,以便它們將API請求轉(zhuǎn)發(fā)到服務(wù)端,最后,啟動代理:
$ consul agent -config-file=server.json
需要在所有代理上都重復(fù)配置,如果用戶是首次配置ACL,還需要完成引導(dǎo)(bootstrap)過程。
創(chuàng)建ACL管理的復(fù)制令牌
接下來,需要創(chuàng)建擁有如下權(quán)限的復(fù)制令牌,用于管理ACL:
-
acl=“write”:允許用戶復(fù)制令牌; -
operator =“ write”:用于復(fù)制代理默認(proxy-default)配置,并在從數(shù)據(jù)中心啟用CA證書簽名; -
service_prefix, policy = "read" and intentions = "read":用于復(fù)制服務(wù)默認(service-default)配置、CA和intention。
acl = "write"
operator = "write"
service_prefix "" {
policy = "read"
intentions = "read"
}
現(xiàn)在,已經(jīng)定義好了ACL規(guī)則,使用這些規(guī)則創(chuàng)建一個策略:
$ consul acl policy create -name replication -rules @replication-policy.hcl
ID: 240f1d01-6517-78d3-ec32-1d237f92ab58
Name: replication
Description: Datacenters:
Rules: acl = "write"
operator = "write"
service_prefix "" { policy = "read" intentions = "read" }
最后,使用新創(chuàng)建的策略來創(chuàng)建復(fù)制令牌:
$ consul acl token create -description "replication token" -policy-name replication
AccessorID: 67d55dc1-b667-1835-42ab-64658d64a2ff
SecretID: fc48e84d-3f4d-3646-4b6a-2bff7c4aaffb
Description: replication token
Local: false
Create Time: 2019-05-09 18:34:23.288392523 +0000 UTC
Policies:
240f1d01-6517-78d3-ec32-1d237f92ab58 - replication
在從數(shù)據(jù)中心啟用ACL復(fù)制
一旦配置了主數(shù)據(jù)中心并創(chuàng)建了復(fù)制令牌,用戶就可以設(shè)置從數(shù)據(jù)中心了。
配置服務(wù)端
用戶需要將所有服務(wù)器上的primary_datacenter參數(shù)設(shè)置為主數(shù)據(jù)中心的名稱,并將enable_token_replication設(shè)置為true:
{
"datacenter": "dc_secondary",
"primary_datacenter": "primary_dc",
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"enable_token_persistence": true,
"enable_token_replication": true
}
}
啟動代理:
$ consul agent -config-file=server.json
對所有服務(wù)端機器重復(fù)執(zhí)行上述過程。
將復(fù)制令牌應(yīng)用于服務(wù)端
使用命令行指令,將復(fù)制令牌應(yīng)用于所有服務(wù)器:
$ consul acl set-agent-token replication <token>
ACL token "replication" set successfully
在所有服務(wù)端機器上重復(fù)此過程,如果首次配置ACL,還需要設(shè)置代理令牌。
配置客戶端
用戶需要將所有服務(wù)器上的primary_datacenter參數(shù)設(shè)置為主數(shù)據(jù)中心的名稱,并將enable_token_replication設(shè)置為true:
{
"datacenter": "dc_secondary",
"primary_datacenter": "primary_dc",
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"enable_token_persistence": true,
"enable_token_replication": true
}
}
啟動代理:
$ consul agent -config-file=server.json
對所有客戶端機器重復(fù)執(zhí)行上述過程。
檢查復(fù)制
如果用戶已經(jīng)設(shè)置了ACL復(fù)制,可以使用HTTP API來檢查數(shù)據(jù)中心的配置:
$ curl http://localhost:8500/v1/acl/replication?pretty
{
"Enabled":true,
"Running":true,
"SourceDatacenter":"primary_dc",
"ReplicationType":"tokens",
"ReplicatedIndex":19,
"ReplicatedTokenIndex":22,
"LastSuccess":"2019-05-09T18:54:09Z",
"LastError":"0001-01-01T00:00:00Z"
}
注意:ReplicationType應(yīng)為令牌,這意味著令牌、策略和角色正在復(fù)制。
添加&刪除服務(wù)器
Consul的設(shè)計原則是要求運維人員盡少去操作,但是對Consul集群的任何更改都必須謹慎處理。為了更好地理解原因,閱讀consensus協(xié)議將很有用。 簡而言之,Consul服務(wù)器執(zhí)行領(lǐng)導(dǎo)者選舉和復(fù)制,在處理更改時,服務(wù)器數(shù)量必須大于(N/2)+ 1。這意味著如果有3個服務(wù)器節(jié)點,則至少必須有2個可用。
通常,如果要同時添加和刪除節(jié)點,最好先添加新節(jié)點,然后再刪除舊節(jié)點。
在本章節(jié)中,我們將介紹添加和刪除服務(wù)器的不同方法。
手動添加一臺新服務(wù)器
手動添加新服務(wù)器通常很簡單,請使用-server標志啟動新代理。此時,服務(wù)器不屬于任何一個集群,并且會發(fā)出類似以下內(nèi)容的信息:
$ consul agent -server
[WARN] raft: EnableSingleNode disabled, and no known peers. Aborting election.
這意味著它與其他節(jié)點互不通信,也沒有配置為自行選舉。這是符合預(yù)期的,現(xiàn)在我們可以使用join命令將節(jié)點添加到現(xiàn)有集群中。對于一臺新服務(wù)器,我們可以將它加入任何現(xiàn)有集群:
$ consul join <Existing Node Address>
Successfully joined cluster by contacting 1 nodes.
需要注意的是,可以指定任何節(jié)點(包括非服務(wù)端機器)加入集群,通常,此方法適用于測試,但不建議用于生產(chǎn)部署。對于生產(chǎn)集群,用戶可能需要使用代理配置項來添加其他服務(wù)器。
添加具有代理配置的服務(wù)器
在生產(chǎn)環(huán)境中,應(yīng)使用代理配置選項retry_join參數(shù)。retry_join可用作命令行標志,或配置在代理配置文件中,使用Consul命令行指令如下:
$ consul agent -retry-join=52.10.110.11 -retry-join=52.10.110.12 -retry-join=52.10.100.13
配置文件內(nèi)容如下:
{
"bootstrap": false,
"bootstrap_expect": 3,
"server": true,
"retry_join": ["52.10.110.11", "52.10.110.12", "52.10.100.13"]
}
retry_join將確保如果服務(wù)器由于任何原因(包括重新啟動節(jié)點)而失去與群集的連接,則它可以在返回時重新加入。除了使用靜態(tài)IP外,它對于其他發(fā)現(xiàn)機制(例如基于云元數(shù)據(jù)的自加入)也很有用。 服務(wù)端和客戶端都可以使用此方法。
服務(wù)器調(diào)度
為確保Consul服務(wù)器能正確加入群集,應(yīng)監(jiān)控服務(wù)器調(diào)度。Gossip協(xié)議用于正確發(fā)現(xiàn)集群中的所有節(jié)點,加入節(jié)點后,集群領(lǐng)導(dǎo)者會記錄以下內(nèi)容:
[INFO] raft: Added peer 127.0.0.2:8300, starting replication
這意味著Raft(底層共識協(xié)議)已經(jīng)添加了節(jié)點并開始復(fù)制狀態(tài),由于現(xiàn)有群集狀態(tài)可能已經(jīng)遙遙領(lǐng)先,因此新節(jié)點需要一些時間才能同步完信息。 要了解詳細信息,可以在領(lǐng)導(dǎo)者服務(wù)器上運行info指令:
$ consul info
...
raft:
applied_index = 47244
commit_index = 47244
fsm_pending = 0
last_log_index = 47244
last_log_term = 21
last_snapshot_index = 40966
last_snapshot_term = 20
num_peers = 4
state = Leader
term = 21
...
這會提供有關(guān)Raft的各種信息,特別是last_log_index參數(shù)顯示磁盤上的最后一個日志??梢栽谛路?wù)器上運行info命令,查看數(shù)據(jù)同步的進度。最終,新的服務(wù)器同步進度會被趕上。
最好一次添加一臺服務(wù)器,使數(shù)據(jù)可以來得及同步。這樣可以避免現(xiàn)有服務(wù)器出現(xiàn)故障時,新增的服務(wù)器同步時發(fā)生數(shù)據(jù)丟失。
手動刪除一臺服務(wù)器
刪除服務(wù)器必須需要小心,以免造成服務(wù)不可用。對于有N個服務(wù)器的群集,至少需要(N/2)+ 1個可用,群集才能正常運行。參考下表,如果用戶有3臺服務(wù)器,其中1臺出現(xiàn)故障,則再刪除任何一臺服務(wù)器將導(dǎo)致集群不可用。
| 服務(wù)器 | 仲裁個數(shù) | 容錯能力 |
|---|---|---|
| 1 | 1 | 0 |
| 2 | 2 | 0 |
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
| 6 | 4 | 2 |
| 7 | 4 | 3 |
為避免這種情況,有必要先將新服務(wù)器添加到群集中,以增加群集的故障容忍度,然后再刪除舊服務(wù)器。 即使所有3個節(jié)點都在工作,刪除1個節(jié)點也會使群集處于崩潰狀態(tài)。
當(dāng)用戶驗證好現(xiàn)有的服務(wù)器運行狀況良好,就可以刪除服務(wù)器節(jié)點了,操作過程很簡單,僅需向服務(wù)器發(fā)送leave指令即可。
$ consul leave
服務(wù)器下線日志如下:
...
[INFO] consul: server starting leave
...
[INFO] raft: Removed ourself, transitioning to follower
...
領(lǐng)導(dǎo)者還會輸出各類日志,包括:
...
[INFO] consul: member 'node-10-0-1-8' left, deregistering
[INFO] raft: Removed peer 10.0.1.8:8300, stopping replication
...
此時,節(jié)點已經(jīng)從集群中正常刪除,并會關(guān)閉。
在服務(wù)端上啟用consul leave會減少仲裁機器個數(shù)。即使集群最初使用bootstrap_expect設(shè)置仲裁機器個數(shù),后續(xù)也可以執(zhí)行consul leave命令減少仲裁機器個數(shù),最后仲裁個數(shù)可以只剩一個,這時可以繼續(xù)提交寫入請求,但是比起之前仲裁機器個數(shù)多的時候,可能會丟失一些寫入請求。
在刪除錯加入集群的服務(wù)后,需要清除客戶端和服務(wù)器節(jié)點上數(shù)據(jù)目錄上(-data-dir)的內(nèi)容,這些刪除服務(wù)器的方法假定服務(wù)器本身是正常的,如果群集由于仲裁丟失或數(shù)據(jù)損壞而沒有領(lǐng)導(dǎo)者,則應(yīng)計劃執(zhí)行中斷恢復(fù)(outage recovery)。
手動強制刪除服務(wù)器
在某些情況下,可能無法正常刪除服務(wù)器。例如,如果服務(wù)器發(fā)生故障,無法發(fā)出下線請求。 相反,群集將檢測到故障,并且還將連續(xù)重試復(fù)制。
如果服務(wù)器可以恢復(fù),則最好先使其恢復(fù)聯(lián)機,然后優(yōu)雅地下線。但是,如果不能正常下線,則可以使用force-leave命令強制刪除服務(wù)器。
$ consul force-leave <node>
自動駕駛系統(tǒng)(Autopilot)
自動駕駛(Autopilot)系統(tǒng)可以對Consul服務(wù)器進行自動、操作友好的管理,其中包括清理死服務(wù)器,監(jiān)控Raft群集狀態(tài)以及穩(wěn)定地引入服務(wù)器,這個功能在Consul 0.8.0中引入。
使用自動駕駛系統(tǒng)時(清理死服務(wù)器功能除外),必須將所有服務(wù)器上Consul代理配置中的raft_protocol參數(shù)配置為3或更高。在Consul 0.8版本中,此配置項默認為2;在Consul 1.0中,默認值為3。其它更多信息可以參考Consul 1.0中有關(guān)Raft協(xié)議版本升級部分。
在本章節(jié),用戶將看到Consul如何跟蹤服務(wù)器的穩(wěn)定性,如何調(diào)整參數(shù),還將了解一下自動駕駛系統(tǒng)的其他細節(jié):
- 服務(wù)器保持穩(wěn)定狀態(tài)
- 清理死服務(wù)器
- 區(qū)域冗余(僅適用于Consul企業(yè)版)
- 自動升級(僅適用于Consul企業(yè)版)
注意,我們使用的示例是基于Consul1.7版本的,默認情況下,我們是啟用自動駕駛功能的,Consul企業(yè)版的功能我們此處也不做詳細介紹。
默認配置
最初引導(dǎo)數(shù)據(jù)中心時,領(lǐng)導(dǎo)者會加載代理機器的自動駕駛系統(tǒng)配置。由于自動駕駛功能默認是開啟的,我們僅需在有必要的時候修改配置禁用它們。
所有Consul服務(wù)器都應(yīng)打開自動駕駛功能,以確保發(fā)生故障時,服務(wù)器之間狀態(tài)保持一致性。 此外,必須啟用自動駕駛才能使用其下的任何子功能,子功能本身可以獨立配置。
用戶可以使用Consul命令行指令或/v1/operator/autopilot端點檢查默認值:
- 命令行指令
$ consul operator autopilot get-config
CleanupDeadServers = true
LastContactThreshold = 200ms
MaxTrailingLogs = 250
MinQuorum = 0
ServerStabilizationTime = 10s
RedundancyZoneTag = ""
DisableUpgradeMigration = false
UpgradeVersionTag = ""
- 使用API調(diào)用
$ curl http://127.0.0.1:8500/v1/operator/autopilot/configuration
{
"CleanupDeadServers": true,
"LastContactThreshold": "200ms",
"MaxTrailingLogs": 250,
"MinQuorum": 0,
"ServerStabilizationTime": "10s",
"RedundancyZoneTag": "",
"DisableUpgradeMigration": false,
"UpgradeVersionTag": "",
"CreateIndex": 5,
"ModifyIndex": 5
}
服務(wù)器健康檢查
在領(lǐng)導(dǎo)者內(nèi)部運行健康狀態(tài)檢查來跟蹤服務(wù)器的穩(wěn)定性,如果滿足以下所有條件,則表示服務(wù)器運行狀況良好:
- 健康狀態(tài)為
Alive; - 自上次與當(dāng)前領(lǐng)導(dǎo)者聯(lián)系的時間低于
LastContactThreshold(默認200ms); - 最新的
Raft任期(term)與領(lǐng)導(dǎo)人的任期匹配; - 領(lǐng)導(dǎo)者落后的
Raft日志數(shù)目不超過MaxTrailingLogs(默認250);
可以通過/v1/operator/autopilot/health端點查看這些健康檢查的狀態(tài),其中頂層的Healthy字段表示數(shù)據(jù)中心的整體狀態(tài):
$ curl localhost:8500/v1/operator/autopilot/health | jq .
{
"Healthy": true,
"FailureTolerance": 1,
"Servers": [
{
# ...
"Name": "server-dc1-1",
"Address": "10.20.10.11:8300",
"SerfStatus": "alive",
"Version": "1.7.2",
"Leader": false,
# ...
"Healthy": true,
"Voter": true,
# ...
},
{
# ...
"Name": "server-2",
"Address": "10.20.10.12:8300",
"SerfStatus": "alive",
"Version": "1.7.2",
"Leader": false,
# ...
"Healthy": true,
"Voter": true,
# ...
},
{
# ...
"Name": "server-3",
"Address": "10.20.10.13:8300",
"SerfStatus": "alive",
"Version": "1.7.2",
"Leader": false,
# ...
"Healthy": true,
"Voter": false,
# ...
}
]
}
服務(wù)器穩(wěn)定時間
將新服務(wù)器添加到數(shù)據(jù)中心后,會先經(jīng)歷一段時間的等待期,在這段時間內(nèi)它必須處于健康狀態(tài)并保持穩(wěn)定,然后才能晉升為有表決權(quán)的成員,這個由ServerStabilizationTime參數(shù)定義,默認情況為10秒。
如果用戶需要配置不同的時間來使節(jié)點準備就緒,例如,在啟動時進行了一些額外的VM檢查,這可能會影響節(jié)點資源的可用性,此時可以調(diào)整參數(shù)并為其分配不同的準備時長。
$ consul operator autopilot set-config -server-stabilization-time=15s
Configuration updated!
使用get-config命令檢查配置項:
$ consul operator autopilot get-config
CleanupDeadServers = true
LastContactThreshold = 200ms
MaxTrailingLogs = 250
MinQuorum = 0
ServerStabilizationTime = 15s
RedundancyZoneTag = ""
DisableUpgradeMigration = false
UpgradeVersionTag = ""
清理死服務(wù)器
如果禁用了自動駕駛,系統(tǒng)需要72個小時才能自動恢復(fù)死服務(wù)器,或者需要運維人員編寫腳本來強制刪除機器。此時如果另一臺服務(wù)器發(fā)生故障,即使故障的Consul服務(wù)器已被自動更換,也可能會危及仲裁。當(dāng)替換的Consul服務(wù)器上線后,自動駕駛系統(tǒng)可以通過快速刪除發(fā)生故障的服務(wù)器來幫助防止此類中斷。服務(wù)器在清理過程中被刪除后會進入left狀態(tài)。
啟用自動駕駛的死服務(wù)器清理功能后,系統(tǒng)將定期清理死服務(wù)器并將其從Raft設(shè)備集中刪除,以防止它們干擾法定人數(shù)和領(lǐng)導(dǎo)者選舉。每當(dāng)將新服務(wù)器成功添加到數(shù)據(jù)中心時,清理過程也會自動觸發(fā)。
我們建議用戶啟用該功能,以避免在Consul管理中引入手動操作,以確保有故障的節(jié)點不會在Raft池中保留太長時間而無需手動刪除。將故障節(jié)點移除工作委派給外部工具,或者在環(huán)境中,可以使用consul operator命令禁用死服務(wù)器清理功能:
$ consul operator autopilot set-config -cleanup-dead-servers=false
Configuration updated!
使用get-config命令檢查配置項:
$ consul operator autopilot get-config
CleanupDeadServers = false
LastContactThreshold = 200ms
MaxTrailingLogs = 250
MinQuorum = 0
ServerStabilizationTime = 10s
RedundancyZoneTag = ""
DisableUpgradeMigration = false
UpgradeVersionTag = ""
中斷恢復(fù)
在發(fā)生服務(wù)中斷時,不要過于驚慌,這是很關(guān)鍵的一步。
根據(jù)用戶的部署配置,有可能僅一臺機器發(fā)生故障就使整個集群不可用。這時需要運維人員操作干預(yù),但是過程很簡單。
本章節(jié)概述了,由于群集中大多數(shù)服務(wù)器節(jié)點丟失后,Consul從中斷中恢復(fù)的過程。 中斷類型有幾種,具體取決于服務(wù)器節(jié)點的數(shù)量和發(fā)生故障的服務(wù)器節(jié)點的數(shù)量。我們將概述如何從以下場景恢復(fù)服務(wù):
- 單服務(wù)器群集發(fā)生故障:此時僅有一臺Consul服務(wù)器,并發(fā)生故障;
- 多服務(wù)器群集單臺服務(wù)器發(fā)生故障:Consul群集中有三臺或更多服務(wù)器,僅有一臺服務(wù)器發(fā)生故障;
- 多服務(wù)器群集多臺服務(wù)器發(fā)生故障:Consul群集中有三臺或更多服務(wù)器,有多臺服務(wù)器發(fā)生故障,這種情況可能是最嚴重的,因為它可能導(dǎo)致數(shù)據(jù)丟失。
單服務(wù)器群集發(fā)生故障
如果只有一臺服務(wù)器,但該服務(wù)器發(fā)生了故障,只需重新啟動它即可,單個服務(wù)器配置需要-bootstrap或-bootstrap-expect = 1標志:
$ consul agent -bootstrap-expect=1
如果無法恢復(fù)服務(wù)器,則需要新啟動一臺服務(wù)器。單服務(wù)器群集容易出現(xiàn)不可恢復(fù)的服務(wù)器故障,且沒有數(shù)據(jù)備份,由于沒有將數(shù)據(jù)復(fù)制到任何其他服務(wù)器,因此數(shù)據(jù)丟失難以避免,所以我們不建議部署單服務(wù)器集群。
升級Raft協(xié)議
將服務(wù)器的-raft-protocol參數(shù)版本從2升級到3后,服務(wù)器將不再允許添加運行較舊版本的服務(wù)器。
在單服務(wù)器群集方案中,重新啟動服務(wù)器可能會導(dǎo)致服務(wù)器無法選舉自己作為領(lǐng)導(dǎo)者,從而群集無法使用。要想服務(wù)從故障恢復(fù),可以打開Consul服務(wù)器的-data-dir目錄,其下有一個raft/子目錄,在raft/目錄中創(chuàng)建一個raft/peers.json文件。
對于Raft協(xié)議版本為3或更高版本,應(yīng)將其格式化為JSON數(shù)組,其中包含Consul服務(wù)器的節(jié)點ID,地址:端口和選舉權(quán)信息,如下所示:
[{ "id": "<node-id>", "address": "<node-ip>:8300", "non_voter": false }]
請確保node-id和node-ip配置正確,最后,重新啟動Consul服務(wù)器。
多服務(wù)器群集單臺服務(wù)器發(fā)生故障
如果發(fā)生故障的服務(wù)器是可恢復(fù)的,最好的選擇是使用相同IP地址加入集群,使其恢復(fù)聯(lián)機狀態(tài)。同樣,如果用戶需要重建新的Consul服務(wù)器以替換發(fā)生故障的節(jié)點,則可能希望立即執(zhí)行此操作。注意,重建的服務(wù)器必須與故障服務(wù)器具有相同的IP地址。同樣,一旦該服務(wù)器聯(lián)機并重新加入,群集將重新返回到完全正常的狀態(tài)。
$ consul agent -bootstrap-expect=3 -bind=192.172.2.4 -auto-rejoin=192.172.2.3
這兩種策略都可能需要很長時間才能重建故障服務(wù)器。如果這不切實際,或者無法選擇使用相同IP構(gòu)建新服務(wù)器時,需要刪除發(fā)生故障的服務(wù)器。通常,如果故障服務(wù)器仍然是集群的成員,則可以使用consul force-leave命令刪除該服務(wù)器。
$ consul force-leave <node.name.consul>
如果consul force-leave無法刪除服務(wù)器,則有另外兩種方法可以刪除它,具體取決于Consul的版本:
- 對于
Consul 0.7或更高版本,如果集群中有領(lǐng)導(dǎo)者,則可以使用consul operator命令立即刪除過時的節(jié)點服務(wù)器,而不會造成停機; - 對于
0.7之前的Consul版本,用戶可以使用其他服務(wù)器上的raft/peers.json恢復(fù)文件手動刪除過時的節(jié)點服務(wù)器。 執(zhí)行此過程Consul需要停機。
在Consul 0.7或更高版本中,可以使用consul operator命令檢查Raft配置:
$ consul operator raft list-peers
Node ID Address State Voter RaftProtocol
alice 10.0.1.8:8300 10.0.1.8:8300 follower true 3
bob 10.0.1.6:8300 10.0.1.6:8300 leader true 3
carol 10.0.1.7:8300 10.0.1.7:8300 follower true 3
多服務(wù)器群集多臺服務(wù)器發(fā)生故障
如果有多臺服務(wù)器發(fā)生故障,導(dǎo)致仲裁丟失或者完全中斷,則可以使用群集中其余服務(wù)器上的數(shù)據(jù)進行部分恢復(fù)(partial recovery)。在這種情況下,可能會因為多個服務(wù)器丟失而導(dǎo)致數(shù)據(jù)丟失,因此有關(guān)所提交內(nèi)容的信息可能不完整。 恢復(fù)過程中隱式(implicitly)提交了所有Raft日志條目,因此也可能提交在故障之前未提交的數(shù)據(jù)。
有關(guān)恢復(fù)過程的詳細信息,請參考以下有關(guān)使用peers.json恢復(fù)文件手動恢復(fù)的部分。用戶只需在raft/peers.json恢復(fù)文件中添加幸存的服務(wù)器即可,一旦所有服務(wù)器都使用相同的raft/peers.json配置重新啟動,集群就可以選舉領(lǐng)導(dǎo)者。
之后用戶引入任何新服務(wù)器都可以使用完全干凈的數(shù)據(jù)目錄來更新數(shù)據(jù),并使用Consul的join指令加入集群。
$ consul agent -join=192.172.2.3
在某些極端情況下,可以通過唯一存活的服務(wù)器,使用它的raft/peers.json文件恢復(fù)集群。
Consul 0.7之前的版本,使用raft/peers.json并不能從所有類型的中斷中恢復(fù)。在Consul 0.7及其更高的版本中,raft/peers.json恢復(fù)文件是最終文件,并且在攝取數(shù)據(jù)后會打上快照,因此可以確保從用戶配置的環(huán)境開始開始。這會隱式提交所有Raft日志條目,因此僅應(yīng)用于從中斷中恢復(fù),但當(dāng)集群中有數(shù)據(jù)可用時,它允許在任何場景實現(xiàn)恢復(fù)。
使用peers.json文件手動恢復(fù)
首先,先要關(guān)閉所有幸存的服務(wù)器,用戶可以嘗試優(yōu)雅地關(guān)閉機器,但大多數(shù)情況下這個會不起作用。如果在關(guān)閉服務(wù)器時發(fā)生錯誤不用擔(dān)心,此時群集處于非正常狀態(tài),這屬于正常情況。
在Consul 0.7及更高版本中,peers.json文件默認不存在,僅在執(zhí)行恢復(fù)時使用。Consul啟動時會提取此文件,然后將其刪除。Consul 0.7還使用自動創(chuàng)建的新的raft/peers.info文件,以避免在升級后首次啟動時提取raft/peers.json文件,確保將raft/peers.info文件放置在正確的位置以供操作。
使用raft/peers.json進行恢復(fù)操作時,可能會導(dǎo)致未提交的Raft日志條目被隱式提交,因此,要確保僅在發(fā)生中斷(且無其他選項可用于恢復(fù)丟失的服務(wù)器)后才使用此命令
下一步是打開Consul服務(wù)器的-data-dir目錄,在該目錄中,有一個raft/子目錄,我們在里面創(chuàng)建raft/peers.json文件,文件格式與Raft版本協(xié)議匹配。
對于Raft協(xié)議版本為2及更早的版本,應(yīng)將其格式化為JSON數(shù)組,其中包含集群中每個Consul服務(wù)器的地址和端口,如下所示:
["10.1.0.1:8300", "10.1.0.2:8300", "10.1.0.3:8300"]
對于Raft協(xié)議版本為3及更高的版本,此文件的格式也為JSON數(shù)組,其中包含集群中每個Consul服務(wù)器的節(jié)點ID、地址:端口和選舉權(quán)信息,如下所示:
[
{
"id": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
"address": "10.1.0.1:8300",
"non_voter": false
},
{
"id": "8b6dda82-3103-11e7-93ae-92361f002671",
"address": "10.1.0.2:8300",
"non_voter": false
},
{
"id": "97e17742-3103-11e7-93ae-92361f002671",
"address": "10.1.0.3:8300",
"non_voter": false
}
]
- id(字符串,必要字段):指定服務(wù)器節(jié)點ID,如果它是自動生成的,可以在服務(wù)器啟動時在日志中找到它,也可以在服務(wù)器的數(shù)據(jù)目錄中的
node-id文件中找到它; - address(字符串,必要字段):指定服務(wù)器的端口和IP,端口用于集群的RPC通信;
- non_voter(布爾類型,非必要字段):控制服務(wù)器是否具有選舉權(quán),默認為
false。
只需為所有服務(wù)器創(chuàng)建該配置項即可,用戶必須確認未包含在此處的服務(wù)器確實發(fā)生了故障,并且以后也不會重新加入群集了,確保其他所有服務(wù)器節(jié)點上的配置文件均相同。
此時,用戶可以重新啟動其他所有服務(wù)器,在Consul 0.7及更高版本中,用戶會看到它們接收恢復(fù)文件:
...
2016/08/16 14:39:20 [INFO] consul: found peers.json file,recovering Raft configuration...
2016/08/16 14:39:20 [INFO] consul.fsm:snapshot created in 12.484μs
2016/08/16 14:39:20 [INFO] snapshot: Creating newsnapshot at /tmp/peers/raft/snapshots/2-5-1471383560779.tmp
2016/08/16 14:39:20 [INFO] consul: deleted peers.json file after successful recovery
2016/08/16 14:39:20 [INFO] raft: Restored from snapshot 2-5-1471383560779
2016/08/16 14:39:20 [INFO] raft: Initial configuration (index=1): [{Suffrage:VoterID:10.212.15.121:8300 Address:10.212.15.121:8300}] ...
對任何正常離開集群的服務(wù)器執(zhí)行join命令都可以使它們重新加入集群:
$ consul join <Node Address> Successfully joined cluster by contacting
1 nodes.
gossip協(xié)議將負責(zé)發(fā)現(xiàn)服務(wù)器節(jié)點,所有存在的都會加入集群中,此時,集群重新進入可操作狀態(tài),某些節(jié)點會打印下列日志確認領(lǐng)導(dǎo)者信息:
[INFO] consul: cluster leadership acquired
在Consul 0.7及更高版本中,可以使用consul operator命令檢查Raft配置:
$ consul operator raft list-peers
Node ID Address State Voter RaftProtocol
alice 10.0.1.8:8300 10.0.1.8:8300 follower true 3
bob 10.0.1.6:8300 10.0.1.6:8300 leader true 3
carol 10.0.1.7:8300 10.0.1.7:8300 follower true 3
故障排除
故障排除是任何開發(fā)人員的一項基本技能,Consul提供了多種工具來幫助用戶查看日志消息,驗證配置文件,檢查服務(wù)目錄以及進行其他調(diào)試。
故障排除步驟
在開始之前,用戶應(yīng)考慮遵循預(yù)定的故障排除工作流程,好的工作流程可以幫助用戶集中精力來發(fā)現(xiàn)和解決問題,我們推薦使用以下流程解決問題:
- 收集資料
- 驗證有效性
- 一次解決一個問題
- 提出假設(shè)并進行驗證
- 重復(fù)整個流程
Consul和其他工具會生成日志文件,狀態(tài)消息,進程列表,數(shù)據(jù)反饋和其他有用的信息,用戶可以在收集數(shù)據(jù)時使用它們,在本章節(jié)中,我們將介紹這些工具。
驗證有效性的方法很重要,因為Consul位于其他高度復(fù)雜系統(tǒng)的中心。確保核心系統(tǒng)、網(wǎng)絡(luò)和服務(wù)是正常工作的,可以幫助用戶縮小問題范圍,并防止用戶花時間對錯誤的問題進行故障排除。如果不確定某個組件是如何工作的,或者不確定它是否正常運行,需要把它先列出來,或者花些時間驗證其是否正常運行。
由于Consul是高度可配置的,因此用戶會發(fā)現(xiàn)如果一次解決一個問題會比較容易,驗證成功的操作,然后繼續(xù)進行下一個問題。有必要的話,用戶可以構(gòu)建一個較小的系統(tǒng),在其中測試不確定的配置項或功能,在驗證成功之后,再將這些更改集成到主系統(tǒng)中。
基于假設(shè)去測試可以幫助用戶專注于所選的某一個問題,用戶需要記下什么問題可能導(dǎo)致該問題以及解決方案,然后觀察數(shù)據(jù)并采取行動,看下理論是否正確,問題是否可以解決。
用戶可能需要重復(fù)此過程中的某些或全部步驟,以找出問題所在,通過遵循一致的解決問題流程,可以高效解決問題。
Consul專用工具
介紹完故障排除流程之后,我們可以看一些定位Consul問題的專用工具,這些工具可以幫助用戶收集數(shù)據(jù),驗證系統(tǒng)運行狀態(tài)。
注意,下面提到的每個Consul命令都可以在有權(quán)訪問Consul代理的節(jié)點上運行。
查看Consul架構(gòu)
在與團隊中的其他成員或技術(shù)支持人員交流時,查看有關(guān)Consul體系結(jié)構(gòu)的一些詳細信息很有幫助,其中包括:
- 如何查詢Consul?(DNS、HTTP)
- Consul Web控制臺頁面是否可以查詢?
- 用戶使用什么系統(tǒng)啟動微服務(wù)?(
systemd、kubernetes、upstart、Nomad等)
members指令
consul members指令會列出連接到當(dāng)前代理的Consul群集中的其他服務(wù)器和代理:
$ consul members
Node Address Status Type Build Protocol DC Segment
laptop 127.0.0.1:8301 alive server 1.4.0 2 dc1 <all>
list-peers指令
如果用戶需要除members指令提供的信息之外的詳細信息,可以嘗試使用list-peers指令,這個指令會提供一些集群的底層信息,其中包括領(lǐng)導(dǎo)者狀態(tài)、投票狀態(tài)和Raft協(xié)議版本:
$ consul operator raft list-peers
Node ID Address State Voter RaftProtocol
laptop abc-def-g12 127.0.0.1:8300 leader true 3
monitor指令
consul monitor指令會顯示Consul代理的日志,使用其他參數(shù)可以更改日志級別,比如-log-level debug或者-log-level trace都會打印大量日志:
$ consul monitor
2019/01/25 17:48:33 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:abcdef Address:127.0.0.1:8300}]
2019/01/25 17:48:33 [INFO] raft: Node at 127.0.0.1:8300 [Follower] entering Follower state (Leader: "")
2019/01/25 17:48:33 [INFO] serf: EventMemberJoin: laptop.dc1 127.0.0.1
2019/01/25 17:48:33 [INFO] serf: EventMemberJoin: laptop 127.0.0.1
2019/01/25 17:48:33 [INFO] consul: Adding LAN server laptop (Addr: tcp/127.0.0.1:8300) (DC: dc1)
2019/01/25 17:48:33 [INFO] consul: Handled member-join event for server "laptop.dc1" in area "wan"
2019/01/25 17:48:33 [ERR] agent: Failed decoding service file "services/.DS_Store": invalid character '\x00' looking for beginning of value
2019/01/25 17:48:33 [INFO] agent: Started DNS server 127.0.0.1:8600 (tcp)
2019/01/25 17:48:33 [INFO] agent: Started DNS server 127.0.0.1:8600 (udp)
2019/01/25 17:48:33 [INFO] agent: Started HTTP server on 127.0.0.1:8500 (tcp)
2019/01/25 17:48:33 [INFO] agent: Started gRPC server on 127.0.0.1:8502 (tcp)
validate指令
consul validate指令可以作用于單個Consul配置文件,更多的是在整個配置文件目錄上運行,它會分析配置文件的基本語法和邏輯正確性:
consul validate /etc/consul.d/counting.json
* invalid config key serrrvice
debug指令
在節(jié)點上運行consul debug指令,它會在當(dāng)前目錄下記錄下兩分鐘內(nèi)的系統(tǒng)指標、日志、概要分析數(shù)據(jù)和其他數(shù)據(jù),所有內(nèi)容均以純文本格式寫入壓縮文檔,因此請勿在未加密的通道上傳輸此數(shù)據(jù),用戶可以將其提供給技術(shù)支持人員,幫助調(diào)試Consul群集:
$ consul debug
==> Starting debugger and capturing static information...
Agent Version: '1.4.0'
Interval: '30s'
Duration: '2m0s'
Output: 'consul-debug-1548721978.tar.gz'
Capture: 'metrics, logs, pprof, host, agent, cluster'
==> Beginning capture interval 2019-01-28 16:32:58.56142 -0800 PST (0)
解壓縮:
$ tar xvfz consul-debug-1548721978.tar.gz
顯示內(nèi)容:
$ tree consul-debug-1548721978
健康檢查
健康檢查是Consul集群非常重要的一個部分,啟用之后,不健康的服務(wù)將不會被發(fā)現(xiàn)。查看初識健康狀態(tài)最簡單的方法訪問Consul Web控制臺頁面,地址是http://localhost:8500/ui。點擊特定服務(wù),比如counting服務(wù),可以看見這個服務(wù)在每個節(jié)點上的狀態(tài),包括健康檢查的輸出信息。
或者,用戶也可以使用HTTP API查看整個目錄或特定服務(wù),/v1/agent/services端點將返回所有注冊在目錄中服務(wù)的列表:
$ curl "http://127.0.0.1:8500/v1/agent/services"
可以在查詢字符串上增加過濾器,僅查詢通過健康檢查的服務(wù):
$ curl 'http://localhost:8500/v1/health/service/counting?passing'
[
{
"Node": {
"ID": "da8eb9d3-...",
"Node": "laptop",
"Address": "127.0.0.1",
"Datacenter": "dc1",
},
"Checks": [
{
"Node": "laptop",
"Output": "Agent alive and reachable"
},
{
"Node": "laptop",
"Name": "Service 'counting' check",
"Status": "passing",
"Output": "HTTP GET http://localhost:9003/health: 200 OK Output: Hello, you've hit /health\n",
"ServiceName": "counting"
}
]
}
]
健康檢查還有一個很重要的方面是,服務(wù)不僅要當(dāng)下健康,更要保持健康狀態(tài),如果某個服務(wù)在健康與不健康狀態(tài)之間波動,我們稱之為flapping。這可能是由于服務(wù)本身的問題造成的(內(nèi)部崩潰),這需要檢查服務(wù)本身,或運行進程的進程啟動器,比如systemd。
這里還要考慮使用合適的健康檢查方式,推薦使用內(nèi)置的健康檢查工具(如TCP或HTTP),而不是使用外置的Shell腳本。
外部工具
Consul的設(shè)計是建立在現(xiàn)有網(wǎng)絡(luò)生態(tài)協(xié)議之中的,這意味著用戶可以使用現(xiàn)有工具來收集數(shù)據(jù),驗證哪些服務(wù)正在運行以及調(diào)試Consul周邊的網(wǎng)絡(luò),應(yīng)用程序和安全上下文。
ps指令
Consul服務(wù)發(fā)現(xiàn)依賴于現(xiàn)有的進程啟動工具,例如systemd、upstart或init.d。如果選擇使用這些工具,可以參考其文檔編寫配置文件、啟動、停止、重新啟動腳本以及監(jiān)控由這些工具啟動的進程的輸出。
ps是Unix系統(tǒng)上的常用工具,運行它可以驗證服務(wù)進程是否按預(yù)期運行:
$ ps | grep counting
79846 ttys001 0:00.07 ./counting-service
或者可以考慮在操作系統(tǒng)中單獨安裝pstree,它會顯示正在運行的父子進程和它們的層次結(jié)構(gòu)。
$ pstree
| | \-+= 74259 geoffrey -zsh
| | \--= 79846 geoffrey ./counting-service
dig指令
如果Consul使用DNS協(xié)議,則可以使用標準DNS工具,Consul默認情況下在8600端口上運行,而不是DNS默認端口53。
dig工具是一個命令行應(yīng)用程序,可與各種DNS記錄進行交互。我們可以使用@127.0.0.1加上-p 8600參數(shù)和Consul服務(wù)器的IP地址查詢詳細的DNS記錄。
在此示例中,我們找到了counting服務(wù)的IP地址:
$ dig @127.0.0.1 -p 8600 counting.service.consul
; <<>> DiG 9.10.6 <<>> @127.0.0.1 -p 8600 counting.service.consul ... ;;
ANSWER SECTION: counting.service.consul. 0 IN A 192.168.0.35
Consul還可以通過SRV(服務(wù))參數(shù)提供其他信息,在dig命令中添加SRV參數(shù)查看counting服務(wù)所使用的端口號(下面顯示為9003):
$ dig @127.0.0.1 -p 8600 counting.service.consul SRV
;; ANSWER SECTION: counting.service.consul. 0 IN SRV 1 1 9003
Machine.local.node.dc1.consul.
;; ADDITIONAL SECTION: Machine.local.node.dc1.consul. 0 IN A
192.168.0.35
如果用戶已經(jīng)配置了DNS轉(zhuǎn)發(fā)將系統(tǒng)DNS與Consul集成,則可以省略IP地址和端口號。但是,用戶在進行調(diào)試時經(jīng)常需要進行專門的設(shè)置,用來驗證與Consul代理的直接通信是否按預(yù)期進行。
curl指令
curl命令看起來很簡單,但它在調(diào)試Web服務(wù),或者發(fā)現(xiàn)HTTP協(xié)議相關(guān)的問題時極其有用,用戶可以使用curl命令查詢健康檢查端點驗證服務(wù)是否處于連接,可以使用IP地址,也可以使用localhost,如果用戶配置了DNS轉(zhuǎn)發(fā),則可以使用Consul綁定的域名與服務(wù)進行通信,例如http://counting.service.consul:
$ curl http://localhost:9003/health
Hello, you've hit /health
ping指令
ping命令也是一個簡單的工具,用于驗證與主機的網(wǎng)絡(luò)連接(如果它可以響應(yīng)ping請求),使用IP地址驗證一個節(jié)點是否可以與另一節(jié)點通信。ping命令對于查看節(jié)點之間的延遲情況以及它們之間數(shù)據(jù)包傳輸?shù)目煽啃砸卜浅S杏谩?/p>
$ ping 10.0.1.14
PING 10.0.1.14 (10.0.1.14): 56 data bytes
64 bytes from 10.0.1.14: icmp_seq=0 ttl=64 time=0.065 ms
64 bytes from 10.0.1.14: icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from 10.0.1.14: icmp_seq=2 ttl=64 time=0.060 ms
^C
--- 10.0.1.14 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.060/0.064/0.068/0.003 ms