最近研究了一下Openstack負載均衡,yum源和源碼級別的安裝都嘗試成功了。網上有不少文章都是LoadBalancerv1,這個已經被放棄了。因此寫一下本身是如何使用LoadBalancerv2。固然在介紹以前仍是從負載均衡基礎知識開始吧。(Mitaka版本的LoadBalancerv2)前端
負載均衡(Load Balancing)是未來訪的網絡流量在運行相同應用的多個服務器之間進行分發的一種核心網絡服務。它的功能由負載均衡器(load balancer)提供。負載均衡器能夠是一個硬件設備,也能夠由軟件實現。它充當反向代理,在多個服務器之間分發網絡或者應用流量。它經常使用來增長應用的訪問容量(併發用戶數)和可靠性,它也會經過下降服務器的負載來提升應用的整體性能。python
負載均衡器的分類linux
負載均衡器通常能夠分爲兩類:第4層負載均衡器和第7層負載均衡器。git
第 4 層負載平衡器:基於網絡和傳輸層協議(IP,TCP,FTP,UDP等)來均衡負載。github
第7層的負載均衡器:基於應用層協議好比 HTTP, SMTP, SNMP, FTP, Telnet 等均衡負載。好比對 HTTP 來講,第七層的負載均衡器能根據應用的特定數據好比 HTTP 頭,cookies 或者應用消息中的數據來作進一步的請求分發。web
負載分發算法算法
兩種類型的負載均衡器都能接收請求,而後根據特定的算法將請求分發到特定的服務器。一些行業標準的算法是:sql
輪詢 (Round robin):輪流分發到各個(活動)服務器
加權輪循 (Weighted round robin):每一個服務器有必定的加權(weight),輪詢時考慮加權。
最少鏈接 (Least connections):轉發到有最少鏈接數的服務器
最少響應時間 (Least response time):轉發到響應時間最短的服務器後端
可靠性和可用性瀏覽器
負載均衡器經過監控應用的健康狀態來確保可靠性和可用性,而且只轉發請求到能及時作出響應的服務和應用。
Session persistence (會話保持)
用戶(瀏覽器)在和服務端交互的時候,一般會在本地保存一些信息,而整個過程叫作一個會話(Session)並用惟一的Session ID進行標識。會話的概念不只用於購物車這種常見狀況,由於HTTP協議是無狀態的,因此任何須要邏輯上下文的情形都必須使用會話機制,此外HTTP客戶端也會額外緩存一些數據在本地,這樣就能夠減小請求提升性能了。若是負載均衡可能將這個會話的請求分配到不一樣的後臺服務端上,這確定是不合適的,必須經過多個backend共享這些數據,效率確定會很低下,最簡單的狀況是保證會話一致性——相同的會話每次請求都會被分配到同一個backend上去。
會話保持表示在一個會話期間,轉發一個用戶的請求到同一個後端服務器。這對購物車或者付款類的請求很是重要。 經常使用的方法包括:
Source IP:相同來源的請求轉發到同一個服務器
HTTP Cookie:該模式下,loadbalancer 爲客戶端的第一次鏈接生成 cookie,後續攜帶該 cookie 的請求會被某個 member 處理
APP Cookie:該模式下,依靠後端應用服務器生成的 cookie 決定被某個 member 處理
http重定向
當http代理(好比瀏覽器)向web服務器請求某個URL後,web服務器能夠經過http響應頭信息中的Location標記來返回一個新的URL。這意味着HTTP代理須要繼續請求這個新的URL,完成自動跳轉。
缺陷:
一、吞吐率限制
主站點服務器的吞吐率平均分配到了被轉移的服務器。現假設使用RR(Round Robin)調度策略,子服務器的最大吞吐率爲1000reqs/s,那麼主服務器的吞吐率要達到3000reqs/s才能徹底發揮三臺子服務器的做用,那麼若是有100臺子服務器,那麼主服務器的吞吐率可想而知得有大?相反,若是主服務的最大吞吐率爲6000reqs/s,那麼平均分配到子服務器的吞吐率爲2000reqs/s,而現子服務器的最大吞吐率爲1000reqs/s,所以就得增長子服務器的數量,增長到6個才能知足。
二、重定向訪問深度不一樣
有的重定向一個靜態頁面,有的重定向相比複雜的動態頁面,那麼實際服務器的負載差別是不可預料的,而主站服務器卻一無所知。所以整站使用重定向方法作負載均衡不太好。
咱們須要權衡轉移請求的開銷和處理實際請求的開銷,前者相對於後者越小,那麼重定向的意義就越大,例以下載。你能夠去不少鏡像下載網站試下,會發現基本下載都使用了Location作了重定向。
DNS負載均衡
DNS負責提供域名解析服務,當訪問某個站點時,實際上首先須要經過該站點域名的DNS服務器來獲取域名指向的IP地址,在這一過程當中,DNS服務器完成了域名到IP地址的映射,一樣,這樣映射也能夠是一對多的,這時候,DNS服務器便充當了負載均衡調度器,它就像http重定向轉換策略同樣,將用戶的請求分散到多臺服務器上,可是它的實現機制徹底不一樣。
相比http重定向,基於DNS的負載均衡徹底節省了所謂的主站點,或者說DNS服務器已經充當了主站點的職能。但不一樣的是,做爲調度器,DNS服務器自己的性能幾乎不用擔憂。由於DNS記錄能夠被用戶瀏覽器或者互聯網接入服務商的各級DNS服務器緩存,只有當緩存過時後纔會從新向域名的DNS服務器請求解析。也說是DNS不存在http的吞吐率限制,理論上能夠無限增長實際服務器的數量。
缺陷:
一、沒有用戶能直接看到DNS解析到了哪一臺實際服務器,加服務器運維人員的調試帶來了不便。
二、策略的侷限性。例如你沒法將HTTP請求的上下文引入到調度策略中,而在前面介紹的基於HTTP重定向的負載均衡系統中,調度器工做在HTTP層面,它能夠充分理解HTTP請求後根據站點的應用邏輯來設計調度策略,好比根據請求不一樣的URL來進行合理的過濾和轉移。
三、若是要根據實際服務器的實時負載差別來調整調度策略,這須要DNS服務器在每次解析操做時分析各服務器的健康狀態,對於DNS服務器來講,這種自定義開發存在較高的門檻,更況且大多數站點只是使用第三方DNS服務。
四、DNS記錄緩存,各級節點的DNS服務器不一樣程序的緩存會讓你暈頭轉向。
五、基於以上幾點,DNS服務器並不能很好地完成工做量均衡分配,最後,是否選擇基於DNS的負載均衡方式徹底取決於你的須要。
反向代理負載均衡
幾乎全部主流的Web服務器都熱衷於支持基於反向代理的負載均衡。它的核心工做就是轉發HTTP請求。
相比前面的HTTP重定向和DNS解析,反向代理的調度器扮演的是用戶和實際服務器中間人的角色:
一、任何對於實際服務器的HTTP請求都必須通過調度器
二、調度器必須等待實際服務器的HTTP響應,並將它反饋給用戶(前兩種方式不須要通過調度反饋,是實際服務器直接發送給用戶)
特性:
一、調度策略豐富。例如能夠爲不一樣的實際服務器設置不一樣的權重,以達到能者多勞的效果。
二、對反向代理服務器的併發處理能力要求高,由於它工做在HTTP層面。
三、反向代理服務器進行轉發操做自己是須要必定開銷的,好比建立線程、與後端服務器創建TCP鏈接、接收後端服務器返回的處理結果、分析HTTP頭部信息、用戶空間和內核空間的頻繁切換等,雖然這部分時間並不長,可是當後端服務器處理請求的時間很是短時,轉發的開銷就顯得尤其突出。例如請求靜態文件,更適合使用前面介紹的基於DNS的負載均衡方式。
四、反向代理服務器能夠監控後端服務器,好比系統負載、響應時間、是否可用、TCP鏈接數、流量等,從而根據這些數據調整負載均衡的策略。
五、反射代理服務器可讓用戶在一次會話週期內的全部請求始終轉發到一臺特定的後端服務器上(粘滯會話),這樣的好處一是保持session的本地訪問,二是防止後端服務器的動態內存緩存的資源浪費。
IP層負載均衡LVS-NAT
咱們須要在HTTP層面如下實現負載均衡,這些負載均衡調度器的工做必須由Linux內核來完成,由於咱們但願網絡數據包在從內核緩衝區進入進程用戶地址空間以前,儘早地被轉發到其餘實際服務器上。並且正由於能夠將調度器工做在應用層之下,這些負載均衡系統能夠支持更多的網絡服務協議,好比ftp,smtp,dns,以及流媒體和VoIP等應用。
DNAT: 反向NAT,將實際服務器放置在內部網絡,而做爲網關的NAT服務器未來自用戶端的數據包轉發給內部網絡的實際服務器(須要修改的是數據包的目標地址和端口)。比較著名的例子是LVS。NAT調度器的吞吐率很高是由於其在內核中進行請求轉發的較低開銷。
可是NAT服務器的帶寬卻成爲了瓶頸。幸運的是,LVS提供了另外一種負載均衡的方式,那就是直接路由。
直接路由LVS-DR
不一樣於NAT機制,直接路由的負載均衡調度器工做在數據鏈路層上,簡單地說,它經過修改數據包的目標mac地址,將數據包轉發到實際服務器上,而且重要的是,實際服務器的響應數據包將直接發送給客戶端,不通過調度器。適用於視頻網站(響應的數據包遠遠超過請求的數據包)。對於LVS-DR,一旦調度器失效,你能夠立刻將LVS-DR切換到DNS-RR模式
負載均衡器 目前有2種,一種是經過硬件來進行進行,常見的硬件有比較昂貴的NetScaler、F五、Radware和Array等商用的負載均衡器,它的優勢就是有專業的維護團隊來對這些服務進行維護、缺點就是花銷太大,因此對於規模較小的網絡服務來講暫時尚未須要使用;另一種就是相似於LVS/HAProxy、Nginx的基於Linux的開源免費的負載均衡軟件策略,這些都是經過軟件級別來實現,因此費用很是低廉。
Nginx、LVS及HAProxy是目前最經常使用的開源軟件負載均衡器。
LVS
LVS:使用集羣技術和Linux操做系統實現一個高性能、高可用的服務器,它具備很好的可伸縮性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。
LVS的特色是:
一、抗負載能力強、是工做在網絡4層之上僅做分發之用,沒有流量的產生,這個特色也決定了它在負載均衡軟件裏的性能最強的;
二、配置性比較低,這是一個缺點也是一個優勢,由於沒有可太多配置的東西,因此並不須要太多接觸,大大減小了人爲出錯的概率;
三、工做穩定,自身有完整的雙機熱備方案,如LVS+Keepalived和LVS+Heartbeat,不過咱們在項目實施中用得最多的仍是LVS/DR+Keepalived;
四、無流量,保證了均衡器IO的性能不會收到大流量的影響;
五、應用範圍比較廣,能夠對全部應用作負載均衡;
六、軟件自己不支持正則處理,不能作動靜分離,這個就比較遺憾了;其實如今許多網站在這方面都有較強的需求,這個是Nginx/HAProxy+Keepalived的優點所在。
七、若是是網站應用比較龐大的話,實施LVS/DR+Keepalived起來就比較複雜了,特別後面有Windows Server應用的機器的話,若是實施及配置還有維護過程就比較複雜了,相對而言,Nginx/HAProxy+Keepalived就簡單多了。
Nginx
Nginx的特色是:
一、工做在網絡的7層之上,能夠針對http應用作一些分流的策略,好比針對域名、目錄結構,它的正則規則比HAProxy更爲強大和靈活,這也是許多朋友喜歡它的緣由之一;
二、Nginx對網絡的依賴很是小,理論上能ping通就就能進行負載功能,這個也是它的優點所在;
三、Nginx安裝和配置比較簡單,測試起來比較方便;
四、也能夠承擔高的負載壓力且穩定,通常能支撐超過幾萬次的併發量;
五、Nginx能夠經過端口檢測到服務器內部的故障,好比根據服務器處理網頁返回的狀態碼、超時等等,而且會把返回錯誤的請求從新提交到另外一個節點,不過其中缺點就是不支持url來檢測;
六、Nginx僅能支持http和Email,這樣就在適用範圍上面小不少,這個它的弱勢;
七、Nginx不只僅是一款優秀的負載均衡器/反向代理軟件,它同時也是功能強大的Web應用服務器。LNMP如今也是很是流行的web架構,大有和之前最流行的LAMP架構分庭抗爭之勢,在高流量的環境中也有很好的效果。
八、Nginx如今做爲Web反向加速緩存愈來愈成熟了,不少朋友都已在生產環境下投入生產了,並且反映效果不錯,速度比傳統的Squid服務器更快,有興趣的朋友能夠考慮用其做爲反向代理加速器。
HAProxy
HAProxy的特色是:
一、HAProxy是支持虛擬主機的,之前有朋友說這個不支持虛擬主機,我這裏特此更正一下。
二、可以補充Nginx的一些缺點好比Session的保持,Cookie的引導等工做
三、支持url檢測後端的服務器出問題的檢測會有很好的幫助。
四、它跟LVS同樣,自己僅僅就只是一款負載均衡軟件;單純從效率上來說HAProxy更會比Nginx有更出色的負載均衡速度,在併發處理上也是優於Nginx的。
五、HAProxy能夠對Mysql讀進行負載均衡,對後端的MySQL節點進行檢測和負載均衡,不過在後端的MySQL slaves數量超過10臺時性能不如LVS,因此我向你們推薦LVS+Keepalived。
六、HAProxy的算法如今也愈來愈多了,具體有以下8種:
roundrobin,表示簡單的輪詢,這個很少說,這個是負載均衡基本都具有的;
static-rr,表示根據權重,建議關注;
leastconn,表示最少鏈接者先處理,建議關注;
source,表示根據請求源IP,這個跟Nginx的IP_hash機制相似,咱們用其做爲解決session問題的一種方法,建議關注;
ri,表示根據請求的URI;
rl_param,表示根據請求的URl參數’balance url_param’ requires an URL parameter name;
hdr(name),表示根據HTTP請求頭來鎖定每一次HTTP請求;
rdp-cookie(name),表示根據據cookie(name)來鎖定並哈希每一次TCP請求。
基本的負載均衡場景有3種:
Two-Arm (or sometimes called In-Line)(雙臂)模式
One-Arm(單臂)模式
Direct Server Response模式
Two-Arm (or sometimes called In-Line)(雙臂)模式
雙臂模式有 switched mode(「bridge mode」 or 「transparent mode」) 和routed mode兩種,routed mode要優於switched mode,實際生產環境也沒有switched mode方式。
對於routed mode模式來講,As you can agree, the Load-Balancer is also a router between the 「Front End」 and 「Back End」 networks. As such, he can simply do destination IP NAT in client request coming to the load-balanced virtual IP and forward the packet to one of the servers in server farm. During this proces, the destination physical server is chosen by the load-balancing algorithm.Return traffic is going back via the Load-Balancer and the source IP is again changed to the virtual load-balanced IP in the response to the Client.
One-Arm(單臂)模式
the Load-Balancer is using only one interface and this interface is on the same L2 network with all the servers.
The traffic that the client initializes will get to the Load-Balancer that has the virtual load-balanced IP. The load-sharing algorithm will pick a physical server to which the Load-Balancer will forward the traffic with destination IP NATed to the physical IP of the server and forward it out the same interface towards the physical server.BUT the Load-balancer also needs to do source IP nat so that the server reply will go back from the server to the Load-Balancer and not directly back to the Client, who is not expecting a reply directly from physical server IP. From the physical servers perspective, all the traffic is coming from Load-Balancer
Direct Server Response (or sometimes called Direct Server Return)
As we hopefully all know, switches learn about MAC addresses as they see frames coming on ports with source MACs. Also imagine that we have a router that has to know the MAC address of the Load-Balanced IP on the last L3 hop. With the picture below, you can already spot the 「trick」 this scenario tries to present here once you notice the disabled ARP on physical servers
Direct Server Response (or sometimes called Direct Server Return)
As we hopefully all know, switches learn about MAC addresses as they see frames coming on ports with source MACs. Also imagine that we have a router that has to know the MAC address of the Load-Balanced IP on the last L3 hop. With the picture below, you can already spot the 「trick」 this scenario tries to present here once you notice the disabled ARP on physical servers
In this scenario, Load-balancer only sees the incoming part of client-server traffic and all the returning traffic from physical servers is coming directly back to the client IP. The biggest advantages of this solution is that there is no NAT and the Load-Balancer throughput is only used in one way, so less performance impact for the Load-Balancer system. Disabling ARP on a physical server is not a difficult task.
Disadvantages however are that you have to manually configure the Load-Balancer with all the server MAC addresses and might be more difficult to troubleshoot with only one way traffic seen by the Load-Balancer on the whole L2 segment.
1.部署
咱們假設LoadBalancerv2服務在網絡節點啓動,以yum源的方式安裝。源碼是:
https://github.com/openstack/neutron-lbaas/tree/stable/mitaka
在控制節點(neutron-server)操做以下:
yum install openstack-neutron-lbaas cd /etc/neutron/ #1.3編輯neutron.conf文件 service_plugins =router, neutron_lbaas.services.loadbalancer.plugin.LoadBalancerPluginv2 #1.4 編輯lbaas_agent.ini 文件 [DEFAULT] interface_driver =neutron.agent.linux.interface.OVSInterfaceDriver ovs_use_veth = True device_driver = neutron_lbaas.drivers.haproxy.namespace_driver.HaproxyNSDriver [haproxy] user_group =haproxy #1.5 編輯neutron_lbaas.conf文件 service_provider =LOADBALANCERV2:Haproxy:neutron_lbaas.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default #而後執行 neutron-db-manage --subproject neutron-lbaas upgrade head systemctl restart neutron-server
在網絡節點操做以下:分佈式的狀況下能夠用做計算節點好比L2模式下
yum install haproxy yum install openstack-neutron-lbaas cd /etc/neutron/ #1.4 編輯neutron.conf文件 service_plugins =router, neutron_lbaas.services.loadbalancer.plugin.LoadBalancerPluginv2 #1.5 編輯lbaas_agent.ini 文件 [DEFAULT] interface_driver =neutron.agent.linux.interface.OVSInterfaceDriver ovs_use_veth = True device_driver = neutron_lbaas.drivers.haproxy.namespace_driver.HaproxyNSDriver [haproxy] user_group =haproxy #1.6 編輯neutron_lbaas.conf文件 service_provider =LOADBALANCERV2:Haproxy:neutron_lbaas.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default #1.7啓動服務 systemctl start neutron-lbaasv2-agent.service
另外能夠安裝前端界面
1.8安裝neutron-lbaas-dashboard
這個是在openstack_dashboard安裝的節點,通常是controller節點
git clone https://git.openstack.org/openstack/neutron-lbaas-dashboard cd neutron-lbaas-dashboard python setup.py install cp neutron_lbaas_dashboard/enabled/1480project_loadbalancersv2_panel.py /usr/share/openstack-dashboard/openstack_dashboard/local/enabled/ systemctl restart httpd.service memcached.service
2.建立負載均衡
Load balancer
The load balancer occupies a neutron network port and has an IP address assigned from a subnet.
Listener
Load balancers can listen for requests on multiple ports. Each one of those ports is specified by a listener.
Pool
A pool holds a list of members that serve content through the load balancer.
Member
Members are servers that serve traffic behind a load balancer. Each member is specified by the IP address and port that it uses to serve traffic.
Health monitor
Members may go offline from time to time and health monitors divert traffic away from members that are not responding properly. Health monitors are associated with pools.
因爲lbaas dashboard有些問題,因此在後臺用命令行建立, dashboard可顯示,但不能任何操做
[root@controller ~]# source admin-openrc.sh
[root@controller ~]# neutron subnet-list
建立loadbalancer
[root@controller ~]# neutron lbaas-loadbalancer-create –name lb1 96f0db98-45fb-48ef-afae-808425fbb2bc
添加lbaas-listener
[root@controller ~]# neutron lbaas-listener-create –loadbalancer lb1 –protocol HTTP –protocol-port 80 –name listener1
建立pool
[root@controller ~]# neutron lbaas-pool-create –lb-algorithm ROUND_ROBIN –listener listener1 –protocol HTTP –name pool1
添加member
[root@controller ~]# neutron lbaas-member-create –subnet 96f0db98-45fb-48ef-afae-808425fbb2bc –address 172.16.1.4 –protocol-port 80 pool1
[root@controller ~]# neutron lbaas-member-create –subnet 96f0db98-45fb-48ef-afae-808425fbb2bc –address 172.16.1.5 –protocol-port 80 pool1
[root@controller ~]# neutron lbaas-member-create –subnet 96f0db98-45fb-48ef-afae-808425fbb2bc –address 172.16.1.6 –protocol-port 80 pool1
添加監控
[root@controller ~]# neutron lbaas-healthmonitor-create –delay 3 –type HTTP –max-retries 3 –timeout 3 –pool pool1
[root@controller ~]# neutron lbaas-loadbalancer-show lb1
3.簡單驗證:
咱們對member成員進行模擬http服務,即172.16.1.4,172.16.1.5,172.16.1.6分別運行
172.16.1.4
while true; do echo -e ‘HTTP/1.0 200 OK\r\nContent-Length: 8\r\n\r\nserver1’ | sudo nc -l -p 80 ; done
172.16.1.5
while true; do echo -e ‘HTTP/1.0 200 OK\r\nContent-Length: 8\r\n\r\nserver2’ | sudo nc -l -p 80 ; done
172.16.1.6
while true; do echo -e ‘HTTP/1.0 200 OK\r\nContent-Length: 8\r\n\r\nserver3’ | sudo nc -l -p 80 ; done
而後建立一個客戶端訪問負載均衡的vip 172.16.1.9 ,屢次執行,以下圖
wget -O - http:// 172.16.1.9 (第一次)
wget -O - http:// 172.16.1.9 (第二次)
wget -O - http:// 172.16.1.9 (第三次)
wget -O - http:// 172.16.1.9(第四次)
咱們發現第一次是server1響應
第二次是server2響應
第三次是server3響應
第四次是server1響應