由于keepalived的應用場景有限,比如它的核心協定vrrp隻能工作在區域網路内,不能工作在區域網路外(網間、廣域網),而且在網絡不受自己控制時基本不能用,除非設定好的vip是供區域網路使用。是以特别是在雲計算環境中,使用雲主機(例如阿裡雲ecs等)就不能用keepalived,是以隻能尋找一個可替代keepalived的解決方案來替代它。consul作為服務注冊、服務發現的最佳選擇,無疑可以很好的替代keepalived。
前文是用的keepalived提供一個vip為上層應用提供通路入口,本文是将keepalived替換成consul,利用consul的dns interface為上層應用提供redis(master)的ip。
前提條件:需要一個可用的consul叢集,可以利用consul叢集本身和配置檔案注冊服務,也可以用一台單獨的主機注冊,還可以用http api向consul注冊。
為了擷取redis(master)的ip而不是redis(slave)的ip,可以用腳本檢查實作,與keepalived腳本中相似,隻是傳回值将1設定成2,因為consul中傳回值0是沒問題(passed),1是警告(warning),2是嚴重(critical)。
下面是用一台單獨的主機注冊的例子。
json配置檔案如下:
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
49
<code>{</code>
<code> </code><code>"services"</code><code>: [</code>
<code> </code><code>{</code>
<code> </code><code>"id"</code><code>: </code><code>"redisnode1"</code><code>,</code>
<code> </code><code>"name"</code><code>: </code><code>"redis"</code><code>,</code>
<code> </code><code>"tags"</code><code>: [</code>
<code> </code><code>"master"</code>
<code> </code><code>],</code>
<code> </code><code>"address"</code><code>: </code><code>"192.168.1.241"</code><code>,</code>
<code> </code><code>"port"</code><code>: 6379,</code>
<code> </code><code>"checks"</code><code>: [</code>
<code> </code><code>{</code>
<code> </code><code>"script"</code><code>: </code><code>"/usr/local/sbin/redis-cli -h 192.168.1.241 -p 6379 info | grep role:master || exit 2"</code><code>,</code>
<code> </code><code>"interval"</code><code>: </code><code>"5s"</code>
<code> </code><code>}</code>
<code> </code><code>]</code>
<code> </code><code>},</code>
<code> </code><code>"id"</code><code>: </code><code>"redisnode2"</code><code>,</code>
<code> </code><code>"address"</code><code>: </code><code>"192.168.1.242"</code><code>,</code>
<code> </code><code>"script"</code><code>: </code><code>"/usr/local/sbin/redis-cli -h 192.168.1.242 -p 6379 info | grep role:master || exit 2"</code><code>,</code>
<code> </code><code>"id"</code><code>: </code><code>"redisnode3"</code><code>,</code>
<code> </code><code>"address"</code><code>: </code><code>"192.168.1.243"</code><code>,</code>
<code> </code><code>"script"</code><code>: </code><code>"/usr/local/sbin/redis-cli -h 192.168.1.243 -p 6379 info | grep role:master || exit 2"</code><code>,</code>
<code> </code><code>}</code>
<code> </code><code>]</code>
<code>}</code>
注冊是利用consul agent作為client運作注冊的,假設consul叢集中某台server的位址是192.168.1.245。
50
51
52
53
<code>mkdir</code> <code>-p </code><code>/usr/local/consul/data</code> <code>/usr/local/consul/config</code>
<code>cat</code> <code>></code><code>/usr/local/consul/config/rediscluster</code><code>.json<<eof</code>
<code>eof</code>
<code>/bin/consul</code> <code>agent -advertise=$(</code><code>ifconfig</code> <code>$(route -n | </code><code>awk</code> <code>'/^0.0.0.0/ && /ug/ {print $nf}'</code><code>) | </code><code>grep</code> <code>inet | </code><code>egrep</code> <code>-</code><code>v</code> <code>"(inet6|127.0.0.1)"</code> <code>| </code><code>cut</code> <code>-d </code><code>":"</code> <code>-f2 | </code><code>cut</code> <code>-d </code><code>" "</code> <code>-f1) -bind=$(</code><code>ifconfig</code> <code>$(route -n | </code><code>awk</code> <code>'/^0.0.0.0/ && /ug/ {print $nf}'</code><code>) | </code><code>grep</code> <code>inet | </code><code>egrep</code> <code>-</code><code>v</code> <code>"(inet6|127.0.0.1)"</code> <code>| </code><code>cut</code> <code>-d </code><code>":"</code> <code>-f2 | </code><code>cut</code> <code>-d </code><code>" "</code> <code>-f1) -data-</code><code>dir</code><code>=</code><code>/usr/local/consul/data</code> <code>-config-</code><code>dir</code><code>=</code><code>/usr/local/consul/config</code> <code>-</code><code>join</code> <code>192.168.1.245</code>
需要背景運作時可以添加nohup thiscommandline >/path/to/logfile 2>&1 &
注意:在consul json配置檔案中,每個consul agent的service id都不能重複,name是強制要求的,必須要有,如果id省略,則跟name相同,其他的都是可選的,可有可無。但為了能夠使用某條服務資訊,就必須要有ip和port,當然port可以在應用中指定。check最好要有,否則當出現問題時不能從consul中取消注冊。
注意:上述指令行中使用的是與預設網關同網段ip(公網ip位址),要求此位址與consul叢集位址之間能互相通路。在啟動consul agent之前可以下面兩行指令中的一行确定是否滿足此條件:
<code>consul info -rpc-addr=192.168.1.245:8400 </code>
<code>consul members -rpc-addr=192.168.1.245:8400</code>
在consul agent啟動後,此時redis的資訊就會在consul中展示出來,包括ui、dns interface和http api中都能查詢到。使用redis的應用應該将dns指向consul叢集的dns位址,這樣才能查詢到redis服務對應的ip。
例如用redis-cli測試一下redis叢集。
注意:可能存在的問題。如果redis master發生故障,原先的slave會變成新的master,dns緩存可能不會重新整理,這個在發生故障處理時需要注意清空上層應用的dns緩存。
tag:redis叢集,redis高可用,redis-sentinel,consul api,redis主從複制
--end--