繼 負載均衡 之 nginx+consul+consul template,我這次將使用2台虛擬機,來做一個簡單的雙機負載均衡試驗。
試驗目標:
1. 當參加負載均衡的子節點服務,有任何其中一個或多個停止工作,總服務還能正常工作;
2. 當兩台機子,其中有一台關機了,總服務還能正常工作;
3. 其中一台關機之后,重啟,能自動加入負載均衡;
3. 當兩台都關機了,總服務停止工作(如果還能工作,那就是見鬼了!)
試驗准備:
2台虛擬機:
192.168.40.128 (ubuntu 16.04)
192.168.40.129 (ubuntu 16.04)
試驗開始如下:
1. 兩台機子分別安裝keepalived
sudo apt-get install libssl-dev
sudo apt-get install openssl
sudo apt-get install libpopt-dev
sudo apt-get install keepalived
192.168.40.128 (ubuntu 16.04)配置為備用機:
sudo vim /etc/keepalived/keepalived.conf
內容:
vrrp_instance VI_1 { state BACKUP interface ens33 #ifconfig確定 virtual_router_id 51 #路由器標識,MASTER和BACKUP必須是一致的 priority 100 #定義優先級,數字越大,優先級越高,在同一個vrrp_instance下,MASTER的優先級必須大於BACKUP的優先級。這樣MASTER故障恢復后,就可以將VIP資源再次搶回來 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.40.100 # 虛擬ip } }
192.168.40.129 (ubuntu 16.04)配置為主機:
sudo vim /etc/keepalived/keepalived.conf
內容:
vrrp_instance VI_1 {
state MASTER
interface ens33 #ifconfig確定 virtual_router_id 51 #路由器標識,MASTER和BACKUP必須是一致的 priority 100 #定義優先級,數字越大,優先級越高,在同一個vrrp_instance下,MASTER的優先級必須大於BACKUP的優先級。這樣MASTER故障恢復后,就可以將VIP資源再次搶回來 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.40.100 # 虛擬ip } }
兩台機子共用一個虛擬IP 192.168.40.100, 在生產環境中應該是一個域名
分別開啟 keepalived
sudo service keepalived start
查看
sudo servicv keepalived status

2. 兩台機子都安裝nginx,這些我就不詳說了
3. 兩台機子都安裝consul,以及 consul-template, 也不詳說,具體看負載均衡 之 nginx+consul+consul template
4. 兩台機子分別配置3個試驗站點:
server { listen 8010; root /www/static-web/site1; index index.html; } server { listen 8020; root /www/static-web/site2; index index.html; } server { listen 8030; root /www/static-web/site3; index index.html; }
html的內容隨便寫點,能區別就好
試訪問一下:
192.168.40.128:8010
192.168.40.128:8020
192.168.40.128:8030
192.168.40.129:8010
192.168.40.129:8020
192.168.40.129:8030

這些我是將一個站點,放在兩台機子,每台機子布署3個站點,一共6個子節點服務來做負載均衡
5. 分別配置服務注冊文件:
{ "encrypt": "k4NEAxg594DeOEjIs/FYBw==", "services": [ { "id": "api4", "name": "MasterService", "tags": [ "ApiService" ], "address": "192.168.40.129", "port": 8010, "checks": [ { "id": "ApiServiceD_Check", "name": "ApiServiceD_Check", "http": "http://192.168.40.129:8010", "interval": "10s", "tls_skip_verify": false, "method": "GET", "timeout": "1s" } ] }, { "id": "api5", "name": "MasterService", "tags": [ "ApiService" ], "address": "192.168.40.129", "port": 8020, "checks": [ { "id": "ApiServiceE_Check", "name": "ApiServiceE_Check", "http": "http://192.168.40.129:8020", "interval": "10s", "tls_skip_verify": false, "method": "GET", "timeout": "1s" } ] }, { "id": "api6", "name": "MasterService", "tags": [ "ApiService" ], "address": "192.168.40.129", "port": 8030, "checks": [ { "id": "ApiServiceF_Check", "name": "ApiServiceF_Check", "http": "http://192.168.40.129:8030", "interval": "10s", "tls_skip_verify": false, "method": "GET", "timeout": "1s" } ] } ] }
配置consul-template模板:
upstream masterservice { {{range service "MasterService"}} server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}}server 127.0.0.1:65535; # force a 502{{end}} } server { listen 8088; location / { proxy_pass http://masterservice; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; } }
6. 192.168.40.128 執行:
consul agent -server -ui -bootstrap-expect=2 -data-dir=/tmp/consul -node=consul-1 -client=0.0.0.0 -bind=192.168.40.128 -datacenter=dc1 -config-dir=/consul/balanceload &
consul-template --consul-addr 192.168.40.128:8500 --template "/consul/template/nginx.ctmpl:/consul/template/vhost.conf:service nginx restart" --log-level=info &
192.168.40.128 執行:
consul agent -server -ui -bootstrap-expect=2 -data-dir=/tmp/consul -node=consul-2 -client=0.0.0.0 -bind=192.168.40.129 -datacenter=dc1 -config-dir=/consul/balanceload -join 192.168.40.128 &
consul-template --consul-addr 192.168.40.129:8500 --template "/consul/template/nginx.ctmpl:/consul/template/vhost.conf:service nginx restart" --log-level=info &
注意consul 服務注冊的一些問題

這里存儲着consul 主機,遠程機的注冊密鑰和運行快照,因為下次再次啟動consul時,之前的配置不會丟失
7. 檢查consul 成員
consul members

consul info

可以看到,兩台機的consul服務已經形成集群,129這台是follower, 128是leader
8. 現在訪問那個虛擬VIP,加上nginx模板配置的8088端口: 192.168.40.100:8088
一次次刷新:
nginx test on 128 i am 128:8010
nginx test on 128 i am 128:8020
nginx test on 128 i am 128:8030
nginx test on 129 i am 129:8010
nginx test on 129 i am 129:8020
nginx test on 129 i am 129:8030
可以看到, 192.168.40.100:8088, 輪詢的去訪問2台機6個站點
我們也可以看到模板文件生成的結果:
upstream masterservice { server 192.168.40.128:8010 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.128:8020 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.128:8030 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.129:8010 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.129:8020 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.129:8030 max_fails=3 fail_timeout=60 weight=1; } server { listen 8088; location / { proxy_pass http://masterservice; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; } }
9. 試關掉一個站點 192.168.40.128:8010
192.168.40.100:8088 正常工作,只是輪詢時少了 192.168.40.128:8010
模板生成的結果:
upstream masterservice { server 192.168.40.128:8020 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.128:8030 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.129:8010 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.129:8020 max_fails=3 fail_timeout=60 weight=1; server 192.168.40.129:8030 max_fails=3 fail_timeout=60 weight=1; } server { listen 8088; location / { proxy_pass http://masterservice; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; } }
10. 把 128 的 consul 服務關掉
129那邊得知128的consul 節點離開了,會將自己推選為leader
訪問一下http://192.168.40.100:8088/
還是能正常工作
nginx test on 129 i am 129:8010
nginx test on 129 i am 129:8020
nginx test on 129 i am 129:8030
只是再看不到128
11. 把128的consul服務開回來
這時,128和129並不能一起推選出leader。也就是說128並沒有加入集群。這時候需要 -rejoin 。表示重新加入集群。重新推選出了leader。
12.把128的機子關機
這時,129那邊一直報
找不到128,129也處於候選人狀態,這個consul服務掛掉了,也就是說只有2台服務器形成一個consul集群,其中一個意外掛掉了,只留下一個節點,它是無法再推送出leader。活着的那個節點,只能處於候選人狀態。
13.做到這里,終於明白 consul官網為何建議一個consul集群,至少要有3個服務節點。
那么使用consul來做雙機負載均衡和服務發現,是不行,必須至少要三機。於是我再安裝多一個虛擬機。192.168.40.130
安裝了跟前兩台一樣的軟件和相關配置。
訪問192.168.40.100:8088
可以看到負載均衡的成員多了130

3台機推送了130為leader

暴力地把130給關機了
看看129,128的反應

可以看這里報了很多消息
1. keepalived重新選舉 master
2. consul重新選舉 leader:consul-1 128那台成了新的老大
3. consul-template 自動更新nginx 配置,並重啟
再看看consul members:

130的consul是一個失敗狀態,這跟離開狀態是不一樣的,所以consul集群也是會不放棄地繼續呼叫130 回家。
這時訪問192.168.40.100:8088,會發現負載均衡的成員,只有6個。
14. 讓130回家
直接把130那台機子開機

consul又恢復了3個節點,leader依然是 consul-1
總結:至此,高可用集群搭建的研究告一段落了。中間踩地了不少坑,也有不少的疑惑,總之自己走過一遍是必須的。
如此,我們的網站服務器是可以無限擴展的。
