原創 2018-03-23 張新峰 RancherLabs
本文於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主機需要以下幾個服務器用來做實驗,網絡規划如下:
說明一點: 如果是生產環境或者需要公司外部用戶訪問內部網站,就需要在你的公網域名所在的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.domain和traefik.alias並不好用。看了Traefik官方文檔「Traefik配置Rancher后端」中的說明,經過我的實際驗證,在Rancher中實現自動注冊Web服務到Traefik需要添加以下3個標簽:
比如我們想要使用域名http://traefik.aek.com直接訪問Traefik的管理面板,只需要升級Traefik服務添加如下3個標簽:
traefik.enable=true
traefik.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=true
traefik.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服務,上線運行半年左右,一直很穩定。
以上就是今天的分享,如有不嚴謹的地方,請多指正!謝謝大家!
Q&A環節
Q1:請問多個服務用了同一個host標簽,traefik會怎么選擇轉到哪個服務?
A1:服務的容器運行在哪些主機上是Rancher的調度服務所負責的,和Traefik無關。Traefik鏈接的是服務,這個服務的容器不管在哪些主機上運行都會被連接過來。
補充:我們目前沒有遇到多個服務配置相同域名的情況,相比只會有一個服務生效,改天試一試看。實際應用時還說要避免這種情況吧。
Q2:請問一下這個負載均衡適合哪些環境和應用?
A2:據官方壓測結果顯示Traefik可以和Nginx相媲美,所以Nginx適合的環境Traefik都適合。目前官方說Traefik只適合HTTP和HTTPS應用,不知道后期會不會支持TCP負載均衡。
Q3:請問你們在生產環境中除了用阿里雲slb做流量接入,后面接着Traefik的HA集群,中間是否還用到了nginx做代理,如果有,一般用了多少台呢?
A3:Traefik就相當於Nginx了,而且還比Nginx好用,我們生產環境就沒有用Nginx了。Traefik HA集群用了2台主機,自動適應的主備結構。
Q4:我想問一個跟traefik能訪問遠程的docker嗎?docker API可以配置認證嗎?
A4:只要是使用HTTP協議的API都可以使用Traefik代理。
Q5:請問下dnsmasq怎么實現的主備?
A5:我們目前的DNSmasq只是用在公司內網,由於沒有什么壓力,所以沒有考慮DNSmasq的高可用。生產環境使用的是域名服務商的DNS服務器,這種服務器想必都有高可用吧,比如阿里雲的DNS服務器有2個:223.5.5.5和223.6.6.6
Q6:我想問一下,rancher自帶的負載均衡除了ui上有些痛點,性能上有什么不足么?
A6:Rancher自帶的負載均衡基於haproxy,也是很成熟的負載均衡解決方案,本來不存在性能很差的問題,但是Rancher默認的內部的網絡交互上存在性能損耗問題。大家可以根據今天的壓測思路,部署一個Rancher自帶的負載均衡,用壓測看看性能。同時也對比一下把服務直接在主機上暴露端口訪問的性能,三者之間對比,性能對比還是比較明顯的。
Q7:請說下Traefik的HA集群怎么部署?
A7:Traefik的HA集群是基於consul后端做存儲,啟動多台Traefik連接到consul,Traefik會自動選舉一個節點作為主節點,其他做備用節點。具體教程請查看官方說明:https://docs.traefik.io/user-guide/cluster/
Q8:有嘗試lvs加traefik嗎?
A8:我們目前是把Traefik的HA集群的多台主機都加入到一個阿里雲SLB的虛擬服務器組,流量接入阿里雲SLB后,自動負載到Traefik的集群,然后再路由到后端服務。目前沒有使用LVS。
Q9:traefix在https上部署容易嗎?
A9:Traefik部署https應用還是很方便的,只要添加SSL證書先關配置即可。還有一個很有吸引力的特性,只要配置了ACME,就可以對SSL證書自動續費。對於想小范圍使用免費SSL證書的環境非常友好。
Q10:用了阿里雲的slb還需要自己traefik的高可用么?阿里的Slb不是支持健康檢查的么,我想的是可不可以利用這個來做高可用?
A10:阿里雲SLB是流量接入端,如果在阿里雲SLB上配置域名路由不僅麻煩(每個域名都手動添加一條記錄),而且只能配置后端到某個服務或者服務器組,這樣不利於服務的高效利用呀。所以還是需要像Traefik這樣的自動適配代理來做域名適配轉發。為了避免traefik這個核心域名路由轉發節點的單點故障,所以最好是做traefik的HA集群。當然流量小的情況下,可以先不用HA集群。健康檢查是說如果發現某個后端不健康,就把這個后端從負載均衡中移除。如果后端只有一個traefik,萬一這個traefik不健康,阿里雲SLB不就斷了后路了么?所以說至少用兩個traefik來做HA,就是避免單點故障。
Q11:請問你們的網絡是如何規划的,比如,我們有DMZ區對外訪問,核心區放置Server,不同應用服務分不同網段?
A11:我們阿里雲環境是用專有網絡的,對外都是使用SLB做接入的。專有網絡自己可以設置網段,比如10.8.1.0/24是容器服務器分區,10.8.2.0/24是數據庫服務器,在公司路由器上做路由跳轉,公司內網指定的電腦才可以直接訪問生產服務器。不應應用分不同網段,便於管理,也便於問題定位,建議做網段划分。
Q12:dns的ttl設置有講究么?
A12:DNS服務的TTL是指在DNS服務器上緩存時間,設置越小,DNS的變動就可以更快在全網生效,然而運營商的DNS設置TTL都是有限制的,默認600秒,想要設置更短,就要購買高級服務了。
Q13:單個服務支持多個域名嗎?服務的label怎么配置呢?
A13:單個服務支持多個域名,多個域名用英文逗號分隔即可。
Q16:目前貴司后端服務發布 有什么灰度發布的方案嗎?
A16:目前使用的Rancher的升級機制實現的灰度發布,每個服務在至少2個容器的情況下,升級發布服務的時候就可以保證服務不中斷,因為Rancher會先停止一個容器,馬上啟動一個容器,保證這個新容器啟動成功,才會停止升級下一個容器。這個策略基本滿足了灰度發布的需要。經過簡單壓力測試,這種服務升級發布過程中,traefik的前端是沒有遇到請求錯誤的。
獲獎名單
QA 環節,我們已從中抽取三人,請中獎的小伙伴們速速聯系群主吧~你們將收到一份精美小禮品!