關於高可用負載均衡的探索

本文於3月22日晚由張新峯,杭州愛醫康架構師技術分享整理而成。本次分享介紹瞭如何使用負載均衡達到一個對用戶友好(穩定無感)、對運維友好(傻瓜高效)、對架構友好(追溯監控)的高可用狀態。

搜索微信號RancherLabs,添加Rancher小助手爲好友,可加入官方技術交流羣,實時參加下一次分享~


引言

我們今天要說的是一個老生常談的問題:負載均衡。有點運維經驗的人都對這個很瞭解了,可你的負載均衡有沒有完美呢?在微服務大行其道的今天,每個公司幾十上百個服務都很常見,更不用說多條產品線並存的公司了,這麼多服務如何在擴縮容的時候實現服務發現和高可用,每天頻繁升級更新的時候有沒有實現用戶無感知?當然每個人對於完美的定義不同,我們今天要說的是指對用戶友好(高可用無感)、對運維友好(高效傻瓜)、對架構友好(追溯監控)的完美狀態。

核心組件

  • Rancher 1.6

  • Traefik 1.5.3

  • dnsmasq

  • ab

必備知識

  • 瞭解Rancher的安裝部署和基本使用

  • 瞭解DNS相關的網絡基本常識

背景

目前公司有3大產品線,十多個小產品,再加上用於運營分析的內部服務和開發測試環境的各種系統和服務,有差不多上百個子域名。運維的職責之一就是要保證這麼多域名穩定準確地指向相應的服務器或服務。這些服務中大部分是Web服務,還有Spring Cloud微服務。不管是用戶通過瀏覽器訪問Web服務,還是微服務之間的相互調用,穩定性肯定是衡量服務的首要指標。尤其是在向DevOps看齊的敏捷型團隊,要想在每天頻繁發佈上線的時候也能保證服務的穩定,就必須使用負載均衡。

困境

先看看我們測試環境的一個產品線使用Rancher自帶的負載均衡時的效果 如果這個列表看着不是那麼眼花繚亂,請看下圖: 目前這個產品線部署了不到50個服務,如果這個界面看着也挺清爽,請再看看每次升級/編輯負載均衡規則的界面吧: 是不是徹底眼花繚亂了呢,這就是我之前每次維護負載均衡器的痛苦。 這裏並不是在詆譭Rancher負載均衡的不好,只是這個管理方式在服務較少的時候還是方便的,服務很多的時候就不是那麼方便了。

如果你想說誰讓你把這麼多服務放在一個負載均衡的,因爲這是我們探索負載均衡過程中的其中一個階段。

探索

我們最初的做法是每次新增一個Web服務,就先在Rancher中部署好服務,然後在Rancher負載均衡中增加一個規則,最後還要去DNS服務器中新增一個A記錄或者CNAME記錄,這樣用戶纔可以訪問這個新的服務。雖然只有3步,經常有服務變動的時候也很累,還能不能更簡便?

後來我們總結了生產環境不同服務使用不同二級域名但主域名都相同的規律,想到把所有有規律的相同分組(比如相同產品線)的域名泛解析到指定主機,只要在Rancher中將LB也調度到那個主機,後續需要在這個分組內新增Web服務就只需2步:1部署好服務,2在Rancher負載均衡中新增一個規則將想要的域名指向剛纔部署,不需要添加A記錄,用戶就可以訪問服務了。

這樣着實方便了一些,但是一段時間後,服務越來越多,域名也相應越來越多,就遇到了上面管理負載均衡器界面眼花繚亂的困擾。我就在想有沒有更簡便的方案可以把手動管理負載均衡這一步也省略呢?能否實現每次新增或編輯一個Web服務只需要部署好服務這一步就可以了呢?

後來Traefik進入了我的視野,他可以整合各種KV存儲解決方案和容器編排引擎,是實現自動負載均衡的絕佳選擇。Traefik還原生支持Rancher的API,可以自發現Rancher上部署的服務。Rancher社區應用商店也提供了Traefik應用模板,按照模板部署Traefik服務以後,所有Web服務只要添加幾個標籤就可以自動註冊到Traefik並且綁定好了制定的域名。再加上前面的經驗,只要泛域名解析到了Traefik服務所在的服務器IP,即可實現了僅僅只需一個部署操作,用戶就可以使用指定域名訪問服務了。

實操

實際操作前,必須要有一個搭建好的Rancher 1.6環境,我們下面只說Rancher的Agent主機需要以下幾個服務器用來做實驗,網絡規劃如下:

IP地址主機名設置標籤用途開放端口
10.0.1.10gatewaytraefik_lb=true
dns_node=true
部署Traefik,所有網站入口
部署DNS服務器,爲用戶提供域名解析
80網站默認端口
443如果需要https網站
8000Traefik管理面板
53/udpDNS服務端口
5380DNS管理控制檯
10.0.1.11node1work_node=true部署http服務走Rancher內網不需要直接在主機上開放端口
10.0.1.12node2work_node=true部署http服務走Rancher內網不需要直接在主機上開放端口
10.0.1.13node3test_node=true部署壓力測試工具不需要開放端口

說明一點: 如果是生產環境或者需要公司外部用戶訪問內部網站,就需要在你的公網域名所在的DNS中設置相關域名解析,不需要單獨部署DNS服務。 在公司內網部署一個獨立DNS服務器的好處就是對公司內網用戶友好,不用每個人記住枯燥的IP和端口了。還有一個好處就是可以實現域名攔截,比如公司內網開發測試環境想用一個花錢也搞不到的好域名,僅限內網,嘿嘿。。。

第一步,準備主機

將以上4臺主機分別添加到Rancher,主機名沒有要求。如果已經在Rancher集羣裏了,直接編輯主機按照上面網絡規劃分別添加標籤。注意主機已經有的標籤不要隨意修改或刪除,以免帶來未知的問題。 四個節點都添加好的主機界面截圖: 

第二步,部署DNS服務器

如果你公司內部已經有DNS服務器,請在內部DNS上設置相關域名解析,可以略過這一步。如果對網絡DNS瞭解不多,也請慎重操作,很容易引起你的電腦“無法上網”。
先添加一個應用,再添加服務,這裏介紹一個自帶Web管理界面的輕量級DNS服務器,鏡像是:jpillora/dnsmasq,端口映射添加53和5380端口,分別對應容器53/udp和8080/tcp端口。注意53端口不能修改,必須是UDP協議。5380端口是DNS管理控制檯,端口可以根據需要設置。如下圖: 

DNS服務啓動好以後,打開DNS管理控制檯http://10.0.1.10:5380,進行DNS配置: 最核心的一條泛解析配置address=/.aek.com/10.0.1.10可以把aek.com所有的子域名解析到10.0.1.10這個IP。

配置好的截圖如下: 

下一步在各個主機和用戶電腦上的設置DNS,將主DNS設置爲10.0.1.10。當然前提是用戶的電腦是可以ping通10.0.1.10這個IP。如果公司有DHCP服務器,將DHCP分配的主DNS設置爲10.0.1.10,DHCP管轄下的電腦重啓後都會應用這個主DNS了。 Windows設置DNS效果:

  

Linux修改DNS命令:

sed -i '1 i nameserver 10.0.1.10' /etc/resolv.conf

RancherOS修改DNS命令:

sudo ros c set rancher.network.dns.nameservers [10.0.1.10]sudo reboot

設置好以後,驗證DNS是否生效。打開CMD,ping aek.com或者隨便這個域名的子域名,看看解析是否都指向我們的gateway服務器10.0.1.10,如下圖:

第三步,部署Traefik

關於Rancher部署Traefik服務的詳細介紹,請查看Rancher官方教程 Rancher部署Traefik實現微服務的快速發現,這裏只簡單說一下。 在社區應用商店找到Traefik並部署,這裏我們演示簡單起見只需要修改Http Port端口爲80,Https Port如果用到的話就改成443,端口配置界面如下: 爲了高可用,一個重要的選項要留意,一定要啓用健康檢查:

 

其他選項暫時不需要修改,點擊啓動按鈕啓動一個traefik服務。 啓動以後發現443端口並沒有映射出來,估計是這個社區鏡像的Bug,如果需要https,就升級一下traefik服務,添加443端口映射即可。
打開網址http://10.0.1.10:8000就可以看到一個清爽的Traefik界面了。管理界面就兩個界面,一個Providers顯示註冊上來的Web服務,我們還沒有部署Web服務,所以現在是空的: 

還有一個界面Health顯示負載均衡的健康狀態,平均響應時間和狀態碼統計圖都在這裏。還有一個非常重要的統計信息就是實時HTTP錯誤列表,每次服務升級發佈上線的時候,留意這裏有沒有忽然出現一大堆錯誤,你的服務架構升級是否穩定,有沒有影響用戶體驗就體現在這裏了! 

至此,一個DNS服務,一個Traefik服務就部署好了,接下來我們就看看Traefik的神奇效果。

第四步,部署Web服務

Rancher的Traefik教程有一個細節需要更正,可能是教程裏面的traefik版本和最新版本不同,所以教程裏面說的關於域名的配置標籤traefik.domaintraefik.alias並不好用。看了Traefik官方文檔 Traefik配置Rancher後端 中的說明,經過我的實際驗證,在Rancher中實現自動註冊Web服務到Traefik需要添加以下3個標籤:

標籤用途
traefik.enable=true啓用traefik服務發現
traefik.port=80指定當前服務的內部端口爲80,根據實際情況修改
traefik.frontend.rule=Host:web.test.com指定當前服務的訪問域名爲web.test.com

比如我們想要使用域名http://traefik.aek.com直接訪問Traefik的管理面板,只需要升級Traefik服務添加如下3個標籤:

traefik.enable=truetraefik.port=8000
traefik.frontend.rule=Host:traefik.aek.com

這裏有個技巧,Rancher設計很人性化的地方,一次性複製下面3個標籤,在Rancher服務的標籤界面點擊“添加標籤”以後,直接粘貼,剛纔複製的3個標籤已經全部填好了,如下圖: Traefik服務升級好以後,刷新Traefik的控制檯,Providers裏面就會多了一組負載均衡。 這個時候你就可以打開http://traefik.aek.com直接訪問traefik的控制面板了。

接下來我們部署一個Web服務,看看自動註冊並使用DNS解析的效果,使用我寫的一個方便驗證負載均衡後端和服務端的Web鏡像zhangsean/hello-web已經發布到Docker Hub,容器內部暴露80端口,不需要添加端口映射,只需要添加以下3個標籤,我們啓動2個容器,以便看看有沒有負載均衡的效果:

traefik.enable=truetraefik.port=80
traefik.frontend.rule=Host:web.aek.com

部署界面截圖:

 hello-web服務啓動成功後,查看traefik控制檯,會發現多了一組負載均衡規則: 

這時候就可以打開網址 http://web.aek.com 訪問剛部署的hello-web服務了。多次刷新,會看到Server Name在兩個容器名之間輪換,說明2個服務後端都在提供服務了。 

順便說一下,很多業務後端服務需要記錄客戶端真實IP,後端應用通過HTTP請求頭 HTTP_X_FORWARDED_FOR 或 HTTP_X_REAL_IP即可獲取客戶端真實IP,區別是前者可能包含多層代理的IP。 關於獲取跨代理的客戶端真實IP的詳細講解,請參考:HTTP 請求頭中的 X-Forwarded-For,X-Real-IP

高可用驗證

我們現在通過壓力測試,驗證這種負載均衡的高可用效果。我們選擇老牌壓力測試工具ab,容器化的ab鏡像是jordi/ab,爲了避免單次壓力測試的不穩定情況,我們使用Rancher批量發起多組壓力測試。

我們首先測試在服務後端擴縮容的時候,服務的可用情況。 新建一個應用HA-Test,然後添加服務ab-web,鏡像指定jordi/ab,不需要映射端口,命令裏填寫測試命令-n 1000 -c 10 -l http://web.aek.com/使用10併發執行1000次請求測試。因爲頁面是活動的所以一定要加-l參數否則會看到很多失敗請求,其實是ab檢測到頁面返回長度不一致認爲請求失敗了。自動重啓選擇“從不(僅啓動一次)”,網絡類型選擇“主機”以便減少容器內部往來對壓力測試造成的影響,添加一個標籤test_node=true,調度規則也添加主機標籤限制必須包含test_node=true,這樣保證測試容器只會運行在node3上不會影響後端服務所在主機的性能。


新增ab-web服務:

 

網絡設置:

 

標籤設置:

 

調度規則:

 

啓動服務以後,進入服務詳情,看到服務是Started-Once,等待服務運行並自動停止,ab測試就完成了。查看服務日誌即可看到測試結果。 

測試結果:

 

現在想再測試一次,只需要手動啓動服務或者給這個服務擴容即可。多運行幾次壓測,把這幾個重要指標放到Excel中進行統計分析就可以知道服務的穩定性和性能了。

以上只是壓測的介紹,壓測時間才持續時間1秒鐘肯定不能說明什麼,我們通過調整-n參數來增加服務請求數,讓壓測持續一段時間,在此期間擴容服務,看看服務穩定性怎樣。

選擇ab-web服務,將其克隆,在新服務裏面把服務名改成ab-web-1w,在命令裏面把請求個數參數調整爲-n 10000,啓動壓測服務。等服務進入Running狀態後,把hello-web服務擴容到3個後端,確保hello-web擴容的後端啓動成功,並且在Traefik控制檯確認hello-web後端已經有3個server,這個時候也可以手動刷新 http://web.aek.com 看看Server Name是否出現第三個容器。這時候壓測應該還在進行彙總,回到ab-web-1w服務查看日誌,等待壓測結束。 可以看到沒有失敗請求,說明擴容期間負載均衡服務很穩定。 

我們再進行來驗證服務縮容的時候負載均衡是否穩定,方法同上,將ab-web-1w克隆成ab-web-1w-2,其他參數不需要修改,啓動服務,等待壓測服務Running,把hello-web服務縮容到2個,在traefik控制檯確認hello-web的後端只剩2個,查看壓測服務日誌,等待壓測結束,確認是否有失敗請求。 很慶幸,壓測結果顯示,沒有任何失敗請求! 

再來看看Traefik控制檯的健康狀態,除了無法請求favicon出現的404錯誤(Hello-web鏡像裏面沒有放favicon.ico文件),沒有其他錯誤。這也印證了Traefik服務的高可用。 

通過以上簡單的壓測,我們基本上驗證了Traefik在服務擴縮容的過程中任然能夠保持服務的穩定高可用。 再結合DNS泛解析,實現了對用戶友好(高可用:升級服務過程中用戶無感知)、對運維友好(部署簡單高效操作傻瓜方便)、對架構友好(監控服務升級過程中有無異常)的簡單高可用服務。

當然生產環境要比我們這個演示環境複雜的多,隨機的併發流量,不穩定的網絡等等因素也都在影響着負載均衡的高可用。 Traefik還提供了運行狀態API,可以整合到監控系統裏面實現更穩定持續的監控。Traefik自身也支持HA模式,避免Traefik單點故障。

我們公司在生產環境用阿里雲SLB做流量接入,後面接着Traefik的HA集羣做自動域名和服務發現的路由,再後端是各種Web服務,上線運行半年左右,一直很穩定。

以上就是今天的分享,如有不嚴謹的地方,請多指正!謝謝大家!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章