LVS和Keepalived的原理介紹和配置實踐

前言

負載均衡技術Load Balance簡稱LB是構建大型網站必不可少的架構策略之一。它的目的是把用戶的請求分發到多臺後端的設備上,用以均衡服務器的負載。咱們能夠把負載均衡器劃分爲兩大類:硬件負載均衡器和軟件負載均衡器。這裏重點介紹軟件實現方法中的LVS和Keepalived。html

LVS和Keepalived的原理介紹和配置實踐

更新歷史

2019年09月03日 - 拆分LVS-Keepalived
2019年08月23日 - 更新LVS/NAT、LVS/DR、LVS/TUN三種模式的原理和配置實踐
2018年12月03日 - 精簡和更新配置步驟
2018年07月31日 - 初稿前端

閱讀原文 - https://wsgzao.github.io/post...node

擴展閱讀mysql

LVS - http://www.linuxvirtualserver...
Keepalived - http://www.keepalived.org/linux


ReadMe

參考文章

LVS - http://www.linuxvirtualserver...
How virtual server works? - http://www.linuxvirtualserver...
Keepalived - http://www.keepalived.org/doc/
LVS入門系列:初識LVS與LVS-NAT - http://www.zsythink.net/archi...
使用 LVS 實現負載均衡原理及安裝配置詳解 - https://www.cnblogs.com/liwei...
LVS 之 VS/TUN 應用場景 - https://www.jianshu.com/p/552...
LVS和Keepalived官方中文手冊PDF - https://pan.baidu.com/s/1s0P6...nginx

相關術語

如下術語涉及LVS三種工做模式的原理
  • LB (Load Balancer 負載均衡)
  • HA (High Available 高可用)
  • Failover (失敗切換)
  • Cluster (集羣)
  • LVS (Linux Virtual Server Linux 虛擬服務器)
  • DS (Director Server),指的是前端負載均衡器節點
  • RS (Real Server),後端真實的工做服務器
  • VIP (Virtual IP),虛擬的IP地址,向外部直接面向用戶請求,做爲用戶請求的目標的 IP 地址
  • DIP (Director IP),主要用於和內部主機通信的 IP 地址
  • RIP (Real Server IP),後端服務器的 IP 地址
  • CIP (Client IP),訪問客戶端的 IP 地址

負載均衡(LB)

負載均衡實現方法有兩種:硬件實現和軟件實現

硬件比較常見的有:git

  1. F5 Big-IP
  2. Citrix Netscaler

軟件比較常見的有:github

  1. LVS(Linux Virtual Server)
  2. HAProxy
  3. Nginx

LVS特色是:web

  1. 首先它是基於4層的網絡協議的,抗負載能力強,對於服務器的硬件要求除了網卡外,其餘沒有太多要求;
  2. 配置性比較低,這是一個缺點也是一個優勢,由於沒有可太多配置的東西,大大減小了人爲出錯的概率;
  3. 應用範圍比較廣,不只僅對web服務作負載均衡,還能夠對其餘應用(mysql)作負載均衡;
  4. LVS架構中存在一個虛擬IP的概念,須要向IDC多申請一個IP來作虛擬IP。

Nginx負載均衡器的特色是:算法

  1. 工做在網絡的7層之上,能夠針對http應用作一些分流的策略,好比針對域名、目錄結構;
  2. Nginx安裝和配置比較簡單,測試起來比較方便;
  3. 也能夠承擔高的負載壓力且穩定,通常能支撐超過上萬次的併發;
  4. Nginx能夠經過端口檢測到服務器內部的故障,好比根據服務器處理網頁返回的狀態碼、超時等等,而且會把返回錯誤的請求從新提交到另外一個節點,不過其中缺點就是不支持url來檢測;
  5. Nginx對請求的異步處理能夠幫助節點服務器減輕負載;
  6. Nginx能支持http和Email,這樣就在適用範圍上面小不少;
  7. 默認有三種調度算法: 輪詢、weight以及ip_hash(能夠解決會話保持的問題),還能夠支持第三方的fair和url_hash等調度算法;

HAProxy的特色是:

  1. HAProxy是工做在網絡7層之上;
  2. 支持Session的保持,Cookie的引導等;
  3. 支持url檢測後端的服務器出問題的檢測會有很好的幫助;
  4. 支持的負載均衡算法:動態加權輪循(Dynamic Round Robin),加權源地址哈希(Weighted Source Hash),加權URL哈希和加權參數哈希(Weighted Parameter Hash);
  5. 單純從效率上來說HAProxy更會比Nginx有更出色的負載均衡速度;
  6. HAProxy能夠對Mysql進行負載均衡,對後端的DB節點進行檢測和負載均衡。

LVS+Keepalived 簡介

在lvs+keepalived環境裏面,lvs主要的工做是提供調度算法,把客戶端請求按照需求調度在real服務器,keepalived主要的工做是提供lvs控制器的一個冗餘,而且對real服務器作健康檢查,發現不健康的real服務器,就把它從lvs集羣中剔除,real服務器只負責提供服務。

LVS

LVS是一個開源的軟件,能夠實現LINUX平臺下的簡單負載均衡。LVS是Linux Virtual Server的縮寫,意思是Linux虛擬服務器。

LB 集羣的架構和原理很簡單,就是當用戶的請求過來時,會直接分發到 Director Server 上,而後它把用戶的請求根據設置好的調度算法,智能均衡地分發到後端真正服務器 (real server) 上。爲了不不一樣機器上用戶請求獲得的數據不同,須要用到了共享存儲,這樣保證全部用戶請求的數據是同樣的。

LVS 是 Linux Virtual Server 的簡稱,也就是 Linux 虛擬服務器。這是一個由章文嵩博士發起的一個開源項目,它的官方網站是 http://www.linuxvirtualserver... 如今 LVS 已是 Linux 內核標準的一部分。使用 LVS 能夠達到的技術目標是:經過 LVS 達到的負載均衡技術和 Linux 操做系統實現一個高性能高可用的 Linux 服務器集羣,它具備良好的可靠性、可擴展性和可操做性。從而以低廉的成本實現最優的性能。LVS 是一個實現負載均衡集羣的開源軟件項目,LVS 架構從邏輯上可分爲調度層、Server 集羣層和共享存儲。

目前有三種IP負載均衡技術(VS/NAT,VS/TUN,VS/DR)

Virtual Server via Network Address Translation(VS/NAT)
經過網絡地址轉換,調度器重寫請求報文的目標地址,根據預設的調度算法,將請求分派給後端的真實服務器;真實服務器的響應報文經過調度器時,報文的源地址被重寫,再返回給客戶,完成整個負載調度過程。

Virtual Server via IP Tunneling(VS/TUN)
採用NAT技術時,因爲請求和響應報文都必須通過調度器地址重寫,當客戶請求愈來愈多時,調度器的處理能力將成爲瓶頸。爲了解決這個問題,調度器把請求報 文經過IP隧道轉發至真實服務器,而真實服務器將響應直接返回給客戶,因此調度器只處理請求報文。因爲通常網絡服務應答比請求報文大許多,採用 VS/TUN技術後,集羣系統的最大吞吐量能夠提升10倍。

Virtual Server via Direct Routing(VS/DR)
VS/DR經過改寫請求報文的MAC地址,將請求發送到真實服務器,而真實服務器將響應直接返回給客戶。同VS/TUN技術同樣,VS/DR技術可極大地 提升集羣系統的伸縮性。這種方法沒有IP隧道的開銷,對集羣中的真實服務器也沒有必須支持IP隧道協議的要求,可是要求調度器與真實服務器都有一塊網卡連 在同一物理網段上。

三種模式的主要區別
VS/NAT VS/TUN VS/DR
server any tunneling non-arp device
server network private LAN/WAN LAN
server number low (10~20) high high
server gateway load balancer own router own router
模式與特色 NAT 模式 IPIP 模式 DR 模式
對服務器的要求 服務節點可使任何操做系統 必須支持 IP 隧道,目前只有 Linux 系統支持 服務器節點支持虛擬網卡設備,可以禁用設備的 ARP 響應
網絡要求 擁有私有 IP 地址的局域網絡 擁有合法 IP 地址的局域,網或廣域網 擁有合法 IP 地址的局域,服務器節點與負載均衡器必須在同一個網段
一般支持節點數量 10 到 20 個,根據負載均衡器的處理能力而定 較高,能夠支持 100 個服務節點 較高,能夠支持 100 個服務節點
網關 負載均衡器爲服務器節點網關 服務器的節點同本身的網關或者路由器鏈接,不通過負載均衡器 服務節點同本身的網關或者路由器鏈接,不通過負載均衡器
服務節點安全性 較好,採用內部 IP,服務節點隱蔽 較差,採用公用 IP 地址,節點安全暴露 較差,採用公用 IP 地址,節點安全暴露
IP 要求 僅須要一個合法的 IP 地址做爲 VIP 地址 除了 VIPO 地址外,每一個服務器界定啊須要擁有合法的 IP 地址,能夠直接從路由到客戶端 除了 VIP 外,每一個服務節點需擁有合法的 IP 地址,能夠直接從路由到客戶端
特色 地址轉換 封裝 IP 修改 MAC 地址
配置複雜度 簡單 複雜 複雜

基本工做原理

  1. 當用戶向負載均衡調度器(Director Server)發起請求,調度器將請求發往至內核空間
  2. PREROUTING鏈首先會接收到用戶請求,判斷目標IP肯定是本機IP,將數據包發往INPUT鏈
  3. IPVS是工做在INPUT鏈上的,當用戶請求到達INPUT時,IPVS會將用戶請求和本身已定義好的集羣服務進行比對,若是用戶請求的就是定義的集羣服務,那麼此時IPVS會強行修改數據包裏的目標IP地址及端口,並將新的數據包發往POSTROUTING鏈
  4. POSTROUTING連接收數據包後發現目標IP地址恰好是本身的後端服務器,那麼此時經過選路,將數據包最終發送給後端的服務器

LVS的組成

LVS 由2部分程序組成,包括 ipvs 和 ipvsadm。
  1. ipvs(ip virtual server):一段代碼工做在內核空間,叫ipvs,是真正生效實現調度的代碼。
  2. ipvsadm:另一段是工做在用戶空間,叫ipvsadm,負責爲ipvs內核框架編寫規則,定義誰是集羣服務,而誰是後端真實的服務器(Real Server)

工做模式

原生只有3種模式(NAT,TUN,DR), fullnat工做模式默認不支持

LVS是四層負載均衡,也就是說創建在OSI模型的第四層——傳輸層之上,傳輸層上有咱們熟悉的TCP/UDP,LVS支持TCP/UDP的負載均衡。由於LVS是四層負載均衡,所以它相對於其它高層負載均衡的解決辦法,好比DNS域名輪流解析、應用層負載的調度、客戶端的調度等,它的效率是很是高的。

LVS的IP負載均衡技術是經過IPVS模塊來實現的,IPVS是LVS集羣系統的核心軟件,它的主要做用是:安裝在Director Server上,同時在Director Server上虛擬出一個IP地址,用戶必須經過這個虛擬的IP地址訪問服務。這個虛擬IP通常稱爲LVS的VIP,即Virtual IP。訪問的請求首先通過VIP到達負載調度器,而後由負載調度器從Real Server列表中選取一個服務節點響應用戶的請求。 當用戶的請求到達負載調度器後,調度器如何將請求發送到提供服務的Real Server節點,而Real Server節點如何返回數據給用戶,是IPVS實現的重點技術,IPVS實現負載均衡機制有幾種,分別是NAT、DR、TUN及FULLNAT。

LVS/NAT

重點理解NAT方式的實現原理和數據包的改變。

(1). 當用戶請求到達Director Server,此時請求的數據報文會先到內核空間的PREROUTING鏈。 此時報文的源IP爲CIP,目標IP爲VIP
(2). PREROUTING檢查發現數據包的目標IP是本機,將數據包送至INPUT鏈
(3). IPVS比對數據包請求的服務是否爲集羣服務,如果,修改數據包的目標IP地址爲後端服務器IP,而後將數據包發至POSTROUTING鏈。 此時報文的源IP爲CIP,目標IP爲RIP
(4). POSTROUTING鏈經過選路,將數據包發送給Real Server
(5). Real Server比對發現目標爲本身的IP,開始構建響應報文發回給Director Server。 此時報文的源IP爲RIP,目標IP爲CIP
(6). Director Server在響應客戶端前,此時會將源IP地址修改成本身的VIP地址,而後響應給客戶端。 此時報文的源IP爲VIP,目標IP爲CIP

LVS/NAT模型的特性
  • RS應該使用私有地址,RS的網關必須指向DIP
  • DIP和RIP必須在同一個網段內
  • 請求和響應報文都須要通過Director Server,高負載場景中,Director Server易成爲性能瓶頸
  • 支持端口映射
  • RS可使用任意操做系統
  • 缺陷:對Director Server壓力會比較大,請求和響應都需通過director server

NAT(Network Address Translation 網絡地址轉換)是一種外網和內外地址映射的技術,內網能夠是私有網址,外網可使用NAT方法修改數據報頭,讓外網與內網可以互相通訊。NAT模式下,網絡數據報的進出都要通過LVS的處理。LVS需做爲RS(真實服務器)的網關。當包到達LVS時,LVS作目標地址轉換(DNAT),將目標IP改成RS的IP。RS接收到包之後,彷彿是客戶端直接發給它的同樣。RS處理完,返回響應時,源IP是RS IP,目標IP是客戶端的IP。這時RS的包經過網(LVS)中轉,LVS會作源地址轉換(SNAT),將包的源地址改成VIP,這樣,這個包對客戶端看起來就彷彿是LVS直接返回給它的。客戶端沒法感知到後端RS的存在。

(1)RIP和DIP必須在同一個IP網絡,且應該使用私網地址;RS的網關要指向DIP;
(2)請求報文和響應報文都必須經由Director轉發;Director易於成爲系統瓶頸;
(3)支持端口映射,可修改請求報文的目標PORT;
(4)vs必須是Linux系統,rs能夠是任意系統;

缺點:在整個過程當中,全部輸入輸出的流量都要通過LVS 調度服務器。顯然,LVS 調度服務器的網絡I/O壓力將會很是大,所以很容易成爲瓶頸,特別是對於請求流量很小,而響應流量很大的Web類應用來講尤其如此。

優勢:NAT模式的優勢在於配置及管理簡單,因爲了使用NAT技術,LVS 調度器及應用服務器能夠在不一樣網段中,網絡架構更靈活,應用服務器只須要進行簡單的網絡設定便可加入集羣。

LVS/DR

重點將請求報文的目標MAC地址設定爲挑選出的RS的MAC地址

(1) 當用戶請求到達Director Server,此時請求的數據報文會先到內核空間的PREROUTING鏈。 此時報文的源IP爲CIP,目標IP爲VIP
(2) PREROUTING檢查發現數據包的目標IP是本機,將數據包送至INPUT鏈
(3) IPVS比對數據包請求的服務是否爲集羣服務,如果,將請求報文中的源MAC地址修改成DIP的MAC地址,將目標MAC地址修改RIP的MAC地址,而後將數據包發至POSTROUTING鏈。 此時的源IP和目的IP均未修改,僅修改了源MAC地址爲DIP的MAC地址,目標MAC地址爲RIP的MAC地址
(4) 因爲DS和RS在同一個網絡中,因此是經過二層來傳輸。POSTROUTING鏈檢查目標MAC地址爲RIP的MAC地址,那麼此時數據包將會發至Real Server。
(5) RS發現請求報文的MAC地址是本身的MAC地址,就接收此報文。處理完成以後,將響應報文經過lo接口傳送給eth0網卡而後向外發出。 此時的源IP地址爲VIP,目標IP爲CIP
(6) 響應報文最終送達至客戶端

LVS/DR模型的特性
  • 特色1:保證前端路由將目標地址爲VIP報文通通發給Director Server,而不是RS
  • RS可使用私有地址;也能夠是公網地址,若是使用公網地址,此時能夠經過互聯網對RIP進行直接訪問
  • RS跟Director Server必須在同一個物理網絡中
  • 全部的請求報文經由Director Server,但響應報文必須不能進過Director Server
  • 不支持地址轉換,也不支持端口映射
  • RS能夠是大多數常見的操做系統
  • RS的網關毫不容許指向DIP(由於咱們不容許他通過director)
  • RS上的lo接口配置VIP的IP地址
  • 缺陷:RS和DS必須在同一機房中
特色1的解決方案:
  • 在前端路由器作靜態地址路由綁定,將對於VIP的地址僅路由到Director Server
  • 存在問題:用戶未必有路由操做權限,由於有多是運營商提供的,因此這個方法未必實用
  • arptables:在arp的層次上實如今ARP解析時作防火牆規則,過濾RS響應ARP請求。這是由iptables提供的
  • 修改RS上內核參數(arp_ignore和arp_announce)將RS上的VIP配置在lo接口的別名上,並限制其不能響應對VIP地址解析請求。

DR(Direct Routing 直接路由模式)此模式時LVS 調度器只接收客戶發來的請求並將請求轉發給後端服務器,後端服務器處理請求後直接把內容直接響應給客戶,而不用再次通過LVS調度器。LVS只須要將網絡幀的MAC地址修改成某一臺後端服務器RS的MAC,該包就會被轉發到相應的RS處理,注意此時的源IP和目標IP都沒變。RS收到LVS轉發來的包時,鏈路層發現MAC是本身的,到上面的網絡層,發現IP也是本身的,因而這個包被合法地接受,RS感知不到前面有LVS的存在。而當RS返回響應時,只要直接向源IP(即用戶的IP)返回便可,再也不通過LVS。

注意:
(1) 確保前端路由器將目標IP爲VIP的請求報文發往Director:

(a) 在前端網關作靜態綁定;
(b) 在RS上使用arptables;
(c) 在RS上修改內核參數以限制arp通告及應答級別;
        arp_announce
        arp_ignore

(2) RS的RIP可使用私網地址,也能夠是公網地址;RIP與DIP在同一IP網絡;RIP的網關不能指向DIP,以確保響應報文不會經由Director;
(3) RS跟Director要在同一個物理網絡;
(4) 請求報文要經由Director,但響應不能經由Director,而是由RS直接發往Client;
(5) 此模式不支持端口映射;

缺點:惟一的缺陷在於它要求LVS 調度器及全部應用服務器在同一個網段中,所以不能實現集羣的跨網段應用。

優勢:可見在處理過程當中LVS Route只處理請求的直接路由轉發,全部響應結果由各個應用服務器自行處理,並對用戶進行回覆,網絡流量將集中在LVS調度器之上。

LVS/TUN

在原有的IP報文外再次封裝多一層IP首部,內部IP首部(源地址爲CIP,目標IIP爲VIP),外層IP首部(源地址爲DIP,目標IP爲RIP)

(1) 當用戶請求到達Director Server,此時請求的數據報文會先到內核空間的PREROUTING鏈。 此時報文的源IP爲CIP,目標IP爲VIP 。
(2) PREROUTING檢查發現數據包的目標IP是本機,將數據包送至INPUT鏈
(3) IPVS比對數據包請求的服務是否爲集羣服務,如果,在請求報文的首部再次封裝一層IP報文,封裝源IP爲DIP,目標IP爲RIP。而後發至POSTROUTING鏈。 此時源IP爲DIP,目標IP爲RIP
(4) POSTROUTING鏈根據最新封裝的IP報文,將數據包發至RS(由於在外層封裝多了一層IP首部,因此能夠理解爲此時經過隧道傳輸)。 此時源IP爲DIP,目標IP爲RIP
(5) RS接收到報文後發現是本身的IP地址,就將報文接收下來,拆除掉最外層的IP後,會發現裏面還有一層IP首部,並且目標是本身的lo接口VIP,那麼此時RS開始處理此請求,處理完成以後,經過lo接口送給eth0網卡,而後向外傳遞。 此時的源IP地址爲VIP,目標IP爲CIP
(6) 響應報文最終送達至客戶端

LVS/TUN模型特性
  • RIP、VIP、DIP全是公網地址
  • RS的網關不會也不可能指向DIP
  • 全部的請求報文經由Director Server,但響應報文必須不能進過Director Server
  • 不支持端口映射
  • RS的系統必須支持隧道
其實企業中最經常使用的是 DR 實現方式,而 NAT 配置上比較簡單和方便,後邊實踐中會總結 DR 和 NAT 具體使用配置過程。

TUN(virtual server via ip tunneling IP 隧道)調度器把請求的報文經過IP隧道轉發到真實的服務器。真實的服務器將響應處理後的數據直接返回給客戶端。這樣調度器就只處理請求入站報文。此轉發方式不修改請求報文的IP首部(源IP爲CIP,目標IP爲VIP),而在原IP報文以外再封裝一個IP首部(源IP是DIP,目標IP是RIP),將報文發往挑選出的目標RS;RS直接響應給客戶端(源IP是VIP,目標IP是CIP),因爲通常網絡服務應答數據比請求報文大不少,採用lvs-tun模式後,集羣系統的最大吞吐量能夠提升10倍

注意:
(1) DIP, VIP, RIP都應該是公網地址;
(2) RS的網關不能,也不可能指向DIP;
(3) 請求報文要經由Director,但響應不能經由Director;
(4) 此模式不支持端口映射;
(5) RS的操做系統得支持隧道功能

缺點:因爲後端服務器RS處理數據後響應發送給用戶,此時須要租借大量IP(特別是後端服務器使用較多的狀況下)。

優勢:實現lvs-tun模式時,LVS 調度器將TCP/IP請求進行從新封裝並轉發給後端服務器,由目標應用服務器直接回複用戶。應用服務器之間是經過IP 隧道來進行轉發,故二者能夠存在於不一樣的網段中。

LVS/FULLNAT

lvs-fullnat工做模式默認不支持

此模式相似DNAT,它經過同時修改請求報文的源IP地址和目標IP地址進行轉發

注意:
(1) VIP是公網地址,RIP和DIP是私網地址,且一般不在同一IP網絡;所以,RIP的網關通常不會指向DIP;
(2) RS收到的請求報文源地址是DIP,所以,只需響應給DIP;但Director還要將其發往Client;
(3) 請求和響應報文都經由Director;
(4) 支持端口映射;

調度算法

八種調度算法(rr,wrr,lc,wlc,lblc,lblcr,dh,sh)

針對不一樣的網絡服務需求和服務器配置,IPVS調度器實現了以下八種負載調度算法:

輪叫調度rr(Round Robin)
調度器經過"輪叫"調度算法將外部請求按順序輪流分配到集羣中的真實服務器上,它均等地對待每一臺服務器,而無論服務器上實際的鏈接數和系統負載。

加權輪叫wrr(Weighted Round Robin)
調度器經過"加權輪叫"調度算法根據真實服務器的不一樣處理能力來調度訪問請求。這樣能夠保證處理能力強的服務器處理更多的訪問流量。調度器能夠自動問詢真實服務器的負載狀況,並動態地調整其權值。

最少連接lc(Least Connections)
調度器經過"最少鏈接"調度算法動態地將網絡請求調度到已創建的連接數最少的服務器上。若是集羣系統的真實服務器具備相近的系統性能,採用"最小鏈接"調度算法能夠較好地均衡負載。

加權最少連接wlc(Weighted Least Connections)
在集羣系統中的服務器性能差別較大的狀況下,調度器採用"加權最少連接"調度算法優化負載均衡性能,具備較高權值的服務器將承受較大比例的活動鏈接負載。調度器能夠自動問詢真實服務器的負載狀況,並動態地調整其權值。

基於局部性的最少連接lblc(Locality-Based Least Connections)
"基於局部性的最少連接" 調度算法是針對目標IP地址的負載均衡,目前主要用於Cache集羣系統。該算法根據請求的目標IP地址找出該目標IP地址最近使用的服務器,若該服務器 是可用的且沒有超載,將請求發送到該服務器;若服務器不存在,或者該服務器超載且有服務器處於一半的工做負載,則用"最少連接"的原則選出一個可用的服務 器,將請求發送到該服務器。

帶複製的基於局部性最少連接lblcr(Locality-Based Least Connections with Replication)
"帶複製的基於局部性最少連接"調度算法也是針對目標IP地址的負載均衡,目前主要用於Cache集羣系統。它與LBLC算法的不一樣之處是它要維護從一個 目標IP地址到一組服務器的映射,而LBLC算法維護從一個目標IP地址到一臺服務器的映射。該算法根據請求的目標IP地址找出該目標IP地址對應的服務 器組,按"最小鏈接"原則從服務器組中選出一臺服務器,若服務器沒有超載,將請求發送到該服務器,若服務器超載;則按"最小鏈接"原則從這個集羣中選出一 臺服務器,將該服務器加入到服務器組中,將請求發送到該服務器。同時,當該服務器組有一段時間沒有被修改,將最忙的服務器從服務器組中刪除,以下降複製的 程度。

目標地址散列dh(Destination Hashing)
"目標地址散列"調度算法根據請求的目標IP地址,做爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,不然返回空。

源地址散列sh(Source Hashing)
"源地址散列"調度算法根據請求的源IP地址,做爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,不然返回空。

keepalived

Keepalived 是運行在lvs之上,是一個用於作雙機熱備(HA)的軟件,它的主要功能是實現真實機的故障隔離及負載均衡器間的失敗切換,提升系統的可用性。

運行原理

keepalived經過選舉(看服務器設置的權重)挑選出一臺熱備服務器作MASTER機器,MASTER機器會被分配到一個指定的虛擬ip,外部程序可經過該ip訪問這臺服務器,若是這臺服務器出現故障(斷網,重啓,或者本機器上的keepalived crash等),keepalived會從其餘的備份機器上重選(仍是看服務器設置的權重)一臺機器作MASTER並分配一樣的虛擬IP,充當前一臺MASTER的角色。

選舉策略

選舉策略是根據VRRP協議,徹底按照權重大小,權重最大(0~255)的是MASTER機器,下面幾種狀況會觸發選舉

  1. keepalived啓動的時候
  2. master服務器出現故障(斷網,重啓,或者本機器上的keepalived crash等,而本機器上其餘應用程序crash不算)
  3. 有新的備份服務器加入且權重最大

keepalived的配置文件說明

Keepalived 是運行在lvs之上,它的主要功能是實現RealServer(真實服務器)的故障隔離及Director(負載均衡器)間的FailOver(失敗切換).

  • keepalived 是lvs的擴展項目,所以它們之間具有良好的兼容性
  • 對RealServer的健康檢查,實現對失效機器/服務的故障隔離
  • 負載均衡器之間的失敗切換 failover

全局定義

全局配置又包括兩個子配置

  1. 全局定義(global definition)
  2. 靜態路由配置(static ipaddress/routes)
# 全局定義(global definition) 
global_defs {                      
   notification_email {      
   acassen@firewall.loc     
   failover@firewall.loc
   sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc   
   smtp_server 192.168.200.1                         
   smtp_connect_timeout 30                                  
   router_id LVS_DEVEL     
}
notification_email: 表示keepalived在發生諸如切換操做時須要發送email通知以及email發送給哪些郵件地址郵件地址能夠多個每行一個
notification_email_from admin@example.com: 表示發送通知郵件時郵件源地址是誰
smtp_server 127.0.0.1: 表示發送email時使用的smtp服務器地址這裏能夠用本地的sendmail來實現
smtp_connect_timeout 30: 鏈接smtp鏈接超時時間
router_id node1: 機器標識,一般配置主機名

# 靜態地址和路由配置範例
static_ipaddress {
    192.168.1.1/24 brd + dev eth0 scope global
    192.168.1.2/24 brd + dev eth1 scope global
}
static_routes {
    src $SRC_IP to $DST_IP dev $SRC_DEVICE
    src $SRC_IP to $DST_IP via $GW dev $SRC_DEVICE
}
這裏實際上和系統裏面命令配置IP地址和路由同樣例如
192.168.1.1/24 brd + dev eth0 scope global 至關於: ip addr add 192.168.1.1/24 brd + dev eth0 scope global
就是給eth0配置IP地址路由同理,通常這個區域不須要配置
這裏實際上就是給服務器配置真實的IP地址和路由的在複雜的環境下可能須要配置通常不會用這個來配置咱們能夠直接用vi /etc/sysconfig/network-script/ifcfg-eth1來配置切記這裏可不是VIP不要搞混淆了切記切記

VRRPD配置

包括三個類:

  1. VRRP同步組(synchroization group)
  2. VRRP實例(VRRP Instance)
  3. VRRP腳本
# VRRP同步組(synchroization group)配置範例
vrrp_sync_group VG_1 {   //注意vrrp_sync_group  後面可自定義名稱如lvs_httpd ,httpd
group {
http
mysql
}
notify_master /path/to/to_master.sh
notify_backup /path_to/to_backup.sh
notify_fault "/path/fault.sh VG_1"
notify /path/to/notify.sh
smtp_alert 
}
其中http和mysql是實例名和下面的實例名一致
notify_master /path/to/to_master.sh //表示當切換到master狀態時要執行的腳本
notify_backup /path_to/to_backup.sh //表示當切換到backup狀態時要執行的腳本
notify_fault "/path/fault.sh VG_1"  // keepalived出現故障時執行的腳本
notify /path/to/notify.sh  
smtp_alert           //表示切換時給global defs中定義的郵件地址發送郵件通知

# VRRP實例(instance)配置範例
vrrp_instance http {  //注意vrrp_instance 後面可自定義名稱如lvs_httpd ,httpd
state MASTER
interface eth0
dont_track_primary
track_interface {
eth0
eth1
}
mcast_src_ip <IPADDR>
garp_master_delay 10
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
autp_pass 1234
}
virtual_ipaddress {
#<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL>
192.168.200.17/24 dev eth1
192.168.200.18/24 dev eth2 label eth2:1
}
virtual_routes {
# src <IPADDR> [to] <IPADDR>/<MASK> via|gw <IPADDR> dev <STRING> scope <SCOPE> tab
src 192.168.100.1 to 192.168.109.0/24 via 192.168.200.254 dev eth1
192.168.110.0/24 via 192.168.200.254 dev eth1
192.168.111.0/24 dev eth2
192.168.112.0/24 via 192.168.100.254
}
nopreempt
preemtp_delay 300
debug
}

state: state指定instance(Initial)的初始狀態就是說在配置好後這臺 服務器的初始狀態就是這裏指定的但這裏指定的不算仍是得要經過競選經過優先級來肯定裏若是這裏設置爲master但如若他的優先級不及另一臺 那麼這臺在發送通告時會發送本身的優先級另一臺發現優先級不如本身的高那麼他會就回搶佔爲master

interface: 實例綁定的網卡由於在配置虛擬VIP的時候必須是在已有的網卡上添加的

dont track primary: 忽略VRRP的interface錯誤

track interface: 跟蹤接口設置額外的監控裏面任意一塊網卡出現問題都會進入故障(FAULT)狀態例如用nginx作均衡器的時候內網必須正常工做若是內網出問題了這個均衡器也就沒法運做了因此必須對內外網同時作健康檢查

mcast src ip: 發送多播數據包時的源IP地址這裏注意了這裏實際上就是在那個地址上發送VRRP通告這個很是重要必定要選擇穩定的網卡端口來發送這裏至關於heartbeat的心跳端口若是沒有設置那麼就用默認的綁定的網卡的IP也就是interface指定的IP地址

garp master delay: 在切換到master狀態後延遲進行免費的ARP(gratuitous ARP)請求,默認5s

virtual router id: 這裏設置VRID這裏很是重要相同的VRID爲一個組他將決定多播的MAC地址

priority 100: 設置本節點的優先級優先級高的爲master

advert int: 設置MASTER與BACKUP負載均衡之間同步即主備間通告時間檢查的時間間隔,單位爲秒,默認1s

virtual ipaddress: 這裏設置的就是VIP也就是虛擬IP地址他隨着state的變化而增長刪除當state爲master的時候就添加當state爲backup的時候刪除這裏主要是有優先級來決定的和state設置的值沒有多大關係這裏能夠設置多個IP地址

virtual routes: 原理和virtual ipaddress同樣只不過這裏是增長和刪除路由

lvs sync daemon interface: lvs syncd綁定的網卡,相似HA中的心跳檢測綁定的網卡

authentication: 這裏設置認證

auth type: 認證方式能夠是PASS或AH兩種認證方式

auth pass: 認證密碼

nopreempt: 設置不搶佔master,這裏只能設置在state爲backup的節點上並且這個節點的優先級必須別另外的高,好比master由於異常將調度圈交給了備份serve,master serve檢修後沒問題,若是不設置nopreempt就會將調度權從新奪回來,這樣就容易形成業務中斷問題

preempt delay: 搶佔延遲多少秒,即延遲多少秒後競選master

debug:debug級別

notify master:和sync group這裏設置的含義同樣能夠單獨設置例如不一樣的實例通知不一樣的管理人員http實例發給網站管理員mysql的就發郵件給DBA

# VRRP腳本
# 以下所示爲相關配置示例
vrrp_script check_running {
   script "/usr/local/bin/check_running"
   interval 10
   weight 10
}

vrrp_instance http {
   state BACKUP
   smtp_alert
   interface eth0
   virtual_router_id 101
   priority 90
   advert_int 3
   authentication {
   auth_type PASS
   auth_pass whatever
   }
   virtual_ipaddress {
   1.1.1.1
   }
   track_script {
   check_running 
   }
}
# 首先在vrrp_script區域定義腳本名字和腳本執行的間隔和腳本執行的優先級變動,以下所示:
vrrp_script check_running {
            script "/usr/local/bin/check_running"
            interval 10     #腳本執行間隔
            weight 10       #腳本結果致使的優先級變動10表示優先級+10-10則表示優先級-10
            }
# 而後在實例(vrrp_instance)裏面引用有點相似腳本里面的函數引用同樣先定義後引用函數名
track_script {
      check_running 
}

注意:
VRRP腳本(vrrp_script)和VRRP實例(vrrp_instance)屬於同一個級別
keepalived會定時執行腳本並對腳本執行的結果進行分析,動態調整vrrp_instance的優先級。通常腳本檢測返回的值爲0,說明腳本檢測成功,若是爲非0數值,則說明檢測失敗
若是腳本執行結果爲0,而且weight配置的值大於0,則優先級相應的增長, 若是weight爲非0,則優先級不變
若是腳本執行結果非0,而且weight配置的值小於0,則優先級相應的減小, 若是weight爲0,則優先級不變
其餘狀況,維持本來配置的優先級,即配置文件中priority對應的值。
這裏須要注意的是:
1) 優先級不會不斷的提升或者下降
2) 能夠編寫多個檢測腳本併爲每一個檢測腳本設置不一樣的weight
3) 無論提升優先級仍是下降優先級,最終優先級的範圍是在[1,254],不會出現優先級小於等於0或者優先級大於等於255的狀況
這樣能夠作到利用腳本檢測業務進程的狀態,並動態調整優先級從而實現主備切換。

virtual_server 虛擬主機配置

關於keeplived的虛擬主機配置有三種以下所示
virtual server IP port
virtual server fwmark int
virtual server group string

以經常使用的第一種爲例
virtual_server 192.168.1.2 80
含義:設置一個virtual server: VIP:Vport

delay_loop 3
含義:設置service polling的delay時間即服務輪詢的時間間隔

lb_algo rr|wrr|lc|wlc|lblc|sh|dh
含義:設置LVS調度算法

lb_kind NAT|DR|TUN
含義:設置LVS集羣模式

persistence_timeout 120
含義:設置會話保持時間秒爲單位即以用戶在120秒內被分配到同一個後端realserver,超過此時間就從新分配

persistence_granularity <NETMASK>
含義:設置LVS會話保持粒度ipvsadm中的-M參數默認是0xffffffff即每一個客戶端都作會話保持

protocol TCP
含義:設置健康檢查用的是TCP仍是UDP

ha_suspend
含義:suspendhealthchecker’s activity

virtualhost <string>
含義:HTTP_GET作健康檢查時檢查的web服務器的虛擬主機即host頭

sorry_server <IPADDR> <PORT>
含義:設置backupserver就是當全部後端realserver節點都不可用時就用這裏設置的也就是臨時把全部的請求都發送到這裏

real_server <IPADDR> <PORT>
含義:設置後端真實節點主機的權重等設置主要後端有幾臺這裏就要設置幾個

weight 1
含義:設置給每臺的權重0表示失效(不知給他轉發請求知道他恢復正常)默認是1

inhibit_on_failure
含義:表示在節點失敗後把他權重設置成0而不是衝IPVS中刪除

notify_up <STRING> | <QUOTED-STRING>
含義:設置檢查服務器正常(UP)後要執行的腳本
notify_down <STRING> | <QUOTED-STRING>
含義:設置檢查服務器失敗(down)後要執行的腳本

注:keepalived檢查機制說明
keepalived健康檢查方式有:HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK幾種以下所示

#HTTP/HTTPS方式 
HTTP_GET|SSL_GET {      #設置健康檢查方式

url {                   #設置要檢查的URL能夠有多個
path /                  #設置URL具體路徑
digest <STRING>         #檢查後的摘要信息這些摘要信息能夠經過genhash命令工具獲取                                   
status_code 200         #設置返回狀態碼
}
connect_port 80         #設置監控檢查的端口
bindto  <IPADD>         #設置健康檢查的IP地址
connect_timeout   3     #設置鏈接超時時間
nb_get_retry  3         #設置重連次數
delay_before_retry  2   #設置重連間隔
} 

#TCP方式  
TCP_CHECK     {
connect_port 80         #設置監控檢查的端口
bindto  <IPADD>         #設置健康檢查的IP地址
connect_timeout   3     #設置鏈接超時時間
nb_get_retry  3         #設置重連次數
delay_before_retry  2   #設置重連間隔
}
#SMTP方式 (這個能夠用來給郵件服務器作集羣)
SMTP_CHECK {
host {
connect_ip <IP ADDRESS>
connect_port <PORT>     #默認檢查25端口
14 KEEPALIVED
bindto <IP ADDRESS>
}
connect_timeout <INTEGER>
retry <INTEGER>
delay_before_retry <INTEGER>
helo_name <STRING>|<QUOTED-STRING>
} 

#MISC方式 這個能夠用來檢查不少服務器只須要本身會些腳本便可
MISC_CHECK {
misc_path <STRING>|<QUOTED-STRING>  #外部程序或腳本
misc_timeout <INT>                  #腳本或程序執行超時時間
misc_dynamic                                              
#這個就很好用了能夠很是精確的來調整權重是後端天天服務器的壓力都能均衡調配這個主要是經過執行的程序或腳本返回的狀態代碼來動態調整weight值使權重根據真實的後端壓力來適當調整不過這須要有過硬的腳本功夫才行哦
#返回0健康檢查沒問題不修改權重
#返回1健康檢查失敗權重設置爲0
#返回2-255健康檢查沒問題可是權重卻要根據返回代碼修改成返回碼-2例如若是程序或腳本執行後返回的代碼爲200#那麼權重這回被修改成 200-2
}

以上就是keepalived的配置項說明雖然配置項不少但不少時候不少配置項保持默認便可,如下是默認配置文件,方便你們作個對比參考

[root@sg-gop-10-65-32-140 wangao]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }
}

virtual_server 192.168.200.100 443 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.201.100 443 {
        weight 1
        SSL_GET {
            url {
              path /
              digest ff20ad2481f97b1754ef3e12ecd3a9cc
            }
            url {
              path /mrtg/
              digest 9b3a0c85a887a256d6939da88aabd8cd
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

virtual_server 10.10.10.2 1358 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    sorry_server 192.168.200.200 1358

    real_server 192.168.200.2 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.200.3 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334c
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

virtual_server 10.10.10.3 1358 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.200.4 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.200.5 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

ipvsadm

通常建議和Keepalived配置文件搭配使用

命令

[root@d126009 wangao]# ipvsadm -h
ipvsadm v1.27 2008/5/15 (compiled with popt and IPVS v1.2.1)
Usage:
  ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine] [-b sched-flags]
  ipvsadm -D -t|u|f service-address
  ipvsadm -C
  ipvsadm -R
  ipvsadm -S [-n]
  ipvsadm -a|e -t|u|f service-address -r server-address [options]
  ipvsadm -d -t|u|f service-address -r server-address
  ipvsadm -L|l [options]
  ipvsadm -Z [-t|u|f service-address]
  ipvsadm --set tcp tcpfin udp
  ipvsadm --start-daemon state [--mcast-interface interface] [--syncid sid]
  ipvsadm --stop-daemon state
  ipvsadm -h

Commands:
Either long or short options are allowed.
  --add-service     -A        add virtual service with options
  --edit-service    -E        edit virtual service with options
  --delete-service  -D        delete virtual service
  --clear           -C        clear the whole table
  --restore         -R        restore rules from stdin
  --save            -S        save rules to stdout
  --add-server      -a        add real server with options
  --edit-server     -e        edit real server with options
  --delete-server   -d        delete real server
  --list            -L|-l     list the table
  --zero            -Z        zero counters in a service or all services
  --set tcp tcpfin udp        set connection timeout values
  --start-daemon              start connection sync daemon
  --stop-daemon               stop connection sync daemon
  --help            -h        display this help message

Options:
  --tcp-service  -t service-address   service-address is host[:port]
  --udp-service  -u service-address   service-address is host[:port]
  --fwmark-service  -f fwmark         fwmark is an integer greater than zero
  --ipv6         -6                   fwmark entry uses IPv6
  --scheduler    -s scheduler         one of rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,
                                      the default scheduler is wlc.
  --pe            engine              alternate persistence engine may be sip,
                                      not set by default.
  --persistent   -p [timeout]         persistent service
  --netmask      -M netmask           persistent granularity mask
  --real-server  -r server-address    server-address is host (and port)
  --gatewaying   -g                   gatewaying (direct routing) (default)
  --ipip         -i                   ipip encapsulation (tunneling)
  --masquerading -m                   masquerading (NAT)
  --weight       -w weight            capacity of real server
  --u-threshold  -x uthreshold        upper threshold of connections
  --l-threshold  -y lthreshold        lower threshold of connections
  --mcast-interface interface         multicast interface for connection sync
  --syncid sid                        syncid for connection sync (default=255)
  --connection   -c                   output of current IPVS connections
  --timeout                           output of timeout (tcp tcpfin udp)
  --daemon                            output of daemon information
  --stats                             output of statistics information
  --rate                              output of rate information
  --exact                             expand numbers (display exact values)
  --thresholds                        output of thresholds information
  --persistent-conn                   output of persistent connection info
  --nosort                            disable sorting output of service/server entries
  --sort                              does nothing, for backwards compatibility
  --ops          -o                   one-packet scheduling
  --numeric      -n                   numeric output of addresses and ports
  --sched-flags  -b flags             scheduler flags (comma-separated)

測試

# 每臺realserver index.html文件內容爲ip 地址,例如httpd: 
echo "172.27.233.43" > /var/www/html/index.html
echo "172.27.233.44" > /var/www/html/index.html

# Nginx test
echo "rs1" > /usr/share/nginx/html/index.html
echo "rs2" > /usr/share/nginx/html/index.html

# 啓動http服務
/etc/init.d/httpd start

# 客戶端模擬請求
for((i=1;i<=10;i++));do curl http://172.27.233.45/; done
172.27.233.44 
172.27.233.43 
172.27.233.44 
172.27.233.43 
172.27.233.44 
172.27.233.43 
172.27.233.44 
172.27.233.43 
172.27.233.44 
172.27.233.43 

# 請求分配結果
ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096) 
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes 
  -> RemoteAddress:Port 
TCP  172.27.233.45:80                   10      50        0     4330        0 
  -> 172.27.233.43:80                    5       25        0     2165        0 
  -> 172.27.233.44:80                    5       25        0     2165        0 

參數含義 
--stats 顯示統計信息 
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes 
                       鏈接數 輸入包 輸出包 輸入流量 輸出流量 

# 實時觀察
watch ipvsadm -Ln --stats

lvs+keepalived配置實踐

防火牆的配置不在本文的範圍,請關閉selinux和firewall
# 關閉防火牆
systemctl disable firewalld
systemctl stop firewalld

# 禁用selinux
setenforce 0
vi /etc/selinux/config

SELINUX=disabled

# 安裝keepalived,ipvsadm
yum install keepalived ipvsadm -y

# 開啓LVS服務器的IP路由轉發功能
echo "1" > /proc/sys/net/ipv4/ip_forward
# 添加路由轉發至sysctl.conf
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1

sysctl -p

最簡單的keepalived作HA

# 若是開啓防火牆,請添加VRRP白名單
# For keepalived
# allow vrrp
-A INPUT -p vrrp -j ACCEPT
-A INPUT -p igmp -j ACCEPT
# allow multicast
-A INPUT -d 224.0.0.18 -j ACCEPT

# 編輯keepalived配置文件
vi /etc/keepalived/keepalived.conf

vrrp_sync_group VI_GOP_NC1_HA {
    group {
        VI_GOP_NC1_HA_PRI
    }
}

vrrp_instance VI_GOP_NC1_HA_PRI {
    state BACKUP
    interface bond0
    virtual_router_id 139
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.65.33.139/23 dev bond0
    }
}

配置LVS-NAT

DS

# Install keepalived
# Ubuntu
apt-get install keepalived ipvsadm
# CentOS
yum install keepalived ipvsadm

# update iptables
vim /etc/sysconfig/iptables

# For keepalived:
# allow vrrp 
-A INPUT -p vrrp -j ACCEPT
-A INPUT -p igmp -j ACCEPT
# allow multicast
-A INPUT -d 224.0.0.18 -j ACCEPT

# reload iptables
service iptables reload

# open ip_forward
echo "1" > /proc/sys/net/ipv4/ip_forward
# edit sysctl.conf
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1

sysctl -p

# keepalived for lvs-nat
vim /etc/keepalived/keepalived.conf

vrrp_sync_group NC-MAIN-API {
    group {
        NC-MAIN-API-PUB
    }
}

vrrp_instance NC-MAIN-API-PUB {
    state BACKUP
    interface bond1
    virtual_router_id 222
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        xx.xx.xx.xx/25 dev bond1
    }
}

virtual_server xx.xx.xx.xx 15000 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    protocol TCP

    real_server 10.71.12.69 15000 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 15000
        }
    }
    real_server 10.71.12.76 15000 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 15000
        }
    }
}

RS

修改默認網關指向NAT的VIP地址

配置LVS-DR

DS

# Install keepalived
# Ubuntu
apt-get install keepalived ipvsadm
# CentOS
yum install keepalived ipvsadm

# update iptables
vim /etc/sysconfig/iptables

# For keepalived:
# allow vrrp 
-A INPUT -p vrrp -j ACCEPT
-A INPUT -p igmp -j ACCEPT
# allow multicast
-A INPUT -d 224.0.0.18 -j ACCEPT

# reload iptables
service iptables reload

# open ip_forward
echo "1" > /proc/sys/net/ipv4/ip_forward
# edit sysctl.conf
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1

sysctl -p

# keepalived for lvs-dr
vim /etc/keepalived/keepalived.conf

vrrp_sync_group GOP {
    group {
        VI_PRI_CONNECT
        VI_PRI_AUTH
    }
}

vrrp_instance VI_PRI_CONNECT {
    state BACKUP
    interface bond0
    virtual_router_id 128
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.65.32.28/23 dev bond0
    }
}

virtual_server 10.65.32.28 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    protocol TCP

    real_server 10.65.32.13 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
    }
    real_server 10.65.32.14 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
    }
}

virtual_server 10.65.32.28 443 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    protocol TCP

    real_server 10.65.32.13 443 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 443
        }
    }
    real_server 10.65.32.14 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 443
        }
    }
}

vrrp_instance VI_PRI_AUTH {
    state BACKUP
    interface bond0
    virtual_router_id 129
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.65.32.29/23 dev bond0
    }
}

virtual_server 10.65.32.29 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    protocol TCP

    real_server 10.65.32.22 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
    }
    real_server 110.65.32.23 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
    }
}

virtual_server 10.65.32.29 443 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    protocol TCP

    real_server 10.65.32.22 443 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 443
        }
    }
    real_server 110.65.32.23 443 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 443
        }
    }
}


# enable and start keepalived
systemctl start keepalived
systemctl enable keepalived
watch ipvsadm -L -n --stats

RS

  1. Edit "/etc/sysconfig/network-scripts/ifcfg-lo" to patch bug in Centos 7 (if using Centos 7). Add TYPE=Loopback to the file.
  2. Add loopback for each Virtual IP on each worker. E.g. first virtual IP create file "/etc/sysconfig/network-scripts/ifcfg-lo:0".
  3. Start adapters if not yet started
# add TYPE=Loopback
echo "TYPE=Loopback" >> /etc/sysconfig/network-scripts/ifcfg-lo
# add ifcfg-lo:0
cat > /etc/sysconfig/network-scripts/ifcfg-lo:0 << EOF
DEVICE=lo:0
IPADDR=10.65.32.28
NETMASK=255.255.255.255
ONBOOT=yes
EOF

# ifup lo:0
ifup lo:0

# add real_start
cat > /root/real_start.sh << EOF
#!/bin/bash
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
EOF

# chmod 755
chmod 755 /root/real_start.sh

# add real.service
cat > /usr/lib/systemd/system/real.service << EOF
[Unit]
Description=autostart lvs real
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
ExecStart=/root/real_start.sh

[Install]
WantedBy=multi-user.target
EOF

# enable service
systemctl enable real.service


# lvs real server example
vim /root/lvs_real.sh

#!/bin/bash
### BEGIN INIT INFO
# Provides:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start realserver
# Description:       Start realserver
### END INIT INFO

# change the VIP to proper value
VIP=10.65.32.28

case "$1" in
    start)

    echo "Start REAL Server"
    /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
    echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
    echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
    echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
    echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

    ;;

    stop)

    /sbin/ifconfig lo:0 down
    echo "Stop REAL Server"
    echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
    echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
    echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
    echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce

    ;;

    restart)

    $0 stop
    $0 start

    ;;

    *)

    echo "Usage: $0 {start|stop}"
    exit 1

    ;;
esac

exit 0

配置LVS-TUN

DS

# Install keepalived
# Ubuntu
apt-get install keepalived ipvsadm
# CentOS
yum install keepalived ipvsadm

# update iptables
vim /etc/sysconfig/iptables

# For keepalived:
# allow vrrp 
-A INPUT -p vrrp -j ACCEPT
-A INPUT -p igmp -j ACCEPT
# allow multicast
-A INPUT -d 224.0.0.18 -j ACCEPT

# reload iptables
service iptables reload

# open ip_forward
echo "1" > /proc/sys/net/ipv4/ip_forward
# edit sysctl.conf
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1

sysctl -p

# keepalived for lvs-tun
vim /etc/keepalived/keepalived.conf

vrrp_sync_group GOP {
    group {
        VI_PRI_AUTH
    }
}

vrrp_instance VI_PRI_AUTH {
    state BACKUP
    interface em1
    virtual_router_id 11
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.10.36.11/23 dev em1
    }
}

virtual_server 10.10.36.11 80 {
    delay_loop 6
    lb_algo rr
    lb_kind TUN
    protocol TCP

    real_server 10.10.36.4 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
    }
    real_server 10.10.36.7 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
    }
}

# enable and start keepalived
systemctl start keepalived
systemctl enable keepalived
watch ipvsadm -L -n --stats


# 編寫DS腳本,推薦用keepalived配置文件
#!/bin/sh
# Startup script handle the initialisation of LVS
# chkconfig: - 28 72
# description: Initialise the Linux Virtual Server for TUN
#
### BEGIN INIT INFO
# Provides: ipvsadm
# Required-Start: $local_fs $network $named
# Required-Stop: $local_fs $remote_fs $network
# Short-Description: Initialise the Linux Virtual Server
# Description: The Linux Virtual Server is a highly scalable and highly
#   available server built on a cluster of real servers, with the load
#   balancer running on Linux.
# description: start LVS of TUN
LOCK=/var/lock/lvs-tun.lock
VIP=10.10.36.11
RIP1=10.10.36.4
RIP2=10.10.36.7
. /etc/rc.d/init.d/functions

start()    {
     PID=`ipvsadm -Ln | grep ${VIP} | wc -l`
     if    [ $PID -gt 0 ];

     then
           echo "The LVS-TUN Server is already running !"
     else
           #Load the tun mod
           /sbin/modprobe tun
           /sbin/modprobe ipip
           #Set the tun Virtual IP Address
           /sbin/ifconfig tunl0 $VIP broadcast $VIP netmask 255.255.255.255 up
           /sbin/route add -host $VIP dev tunl0
           #Clear IPVS Table
           /sbin/ipvsadm -C
           #The icmp recruit setting
           echo "0" >/proc/sys/net/ipv4/ip_forward
           echo "0" >/proc/sys/net/ipv4/conf/all/send_redirects
           echo "0" >/proc/sys/net/ipv4/conf/default/send_redirects
           #Set Lvs
           /sbin/ipvsadm -At $VIP:80 -s rr
           /sbin/ipvsadm -at $VIP:80 -r $RIP1:80 -i  -w 1
           /sbin/ipvsadm -at $VIP:80 -r $RIP2:80 -i  -w 1
           /bin/touch $LOCK
           #Run Lvs
           echo "starting LVS-TUN-DIR Server is ok !"
     fi
}

stop()    {
           #stop  Lvs server
           /sbin/ipvsadm -C
           /sbin/ifconfig tunl0 down >/dev/null
           #Remove the tun mod
           /sbin/modprobe -r tun
           /sbin/modprobe -r ipip
           rm -rf $LOCK
           echo "stopping LVS-TUN-DIR server is ok !"
}

status()  {
     if [ -e $LOCK ];
     then
         echo "The LVS-TUN Server is already running !"
     else
         echo "The LVS-TUN Server is not running !"
     fi
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        sleep 1
        start
        ;;
  status)
        status
        ;;
  *)
        echo "Usage: $1 {start|stop|restart|status}"
        exit 1
esac
exit 0

RS

# 在加載好ipip模塊後就會有默認的tunl0隧道
modprobe ipip

# 添加VIP
# ifconfig tunl0 down
ifconfig tunl0 10.10.36.11 broadcast 10.10.36.11 netmask 255.255.255.255 up

# 添加路由
route add -host 10.10.36.11 tunl0

# 手動關閉ARP轉發
echo '1' > /proc/sys/net/ipv4/conf/tunl0/arp_ignore 
echo '2' > /proc/sys/net/ipv4/conf/tunl0/arp_announce
echo '1' > /proc/sys/net/ipv4/conf/all/arp_ignore
echo '2' > /proc/sys/net/ipv4/conf/all/arp_announce 
echo '0' > /proc/sys/net/ipv4/conf/tunl0/rp_filter
echo '0' > /proc/sys/net/ipv4/conf/all/rp_filter 

# iptables容許ipip協議
iptables -I INPUT 1 -p 4 -j ACCEPT
vim /etc/sysconfig/iptables
-A INPUT -p ipv4 -j ACCEPT

# 編寫RS啓停腳本
vim /etc/init.d/lvs-tun

#!/bin/sh
#
# Startup script handle the initialisation of LVS
# chkconfig: - 28 72
# description: Initialise the Linux Virtual Server for TUN
#
### BEGIN INIT INFO
# Provides: ipvsadm
# Required-Start: $local_fs $network $named
# Required-Stop: $local_fs $remote_fs $network
# Short-Description: Initialise the Linux Virtual Server
# Description: The Linux Virtual Server is a highly scalable and highly
#   available server built on a cluster of real servers, with the load
#   balancer running on Linux.
# description: start LVS of TUN-RIP
LOCK=/var/lock/ipvsadm.lock
VIP=10.10.36.11
. /etc/rc.d/init.d/functions
start() {
     PID=`ifconfig | grep tunl0 | wc -l`
     if [ $PID -ne 0 ];
     then
         echo "The LVS-TUN-RIP Server is already running !"
     else
         #Load the tun mod
         /sbin/modprobe tun
         /sbin/modprobe ipip
         #Set the tun Virtual IP Address
         /sbin/ifconfig tunl0 $VIP netmask 255.255.255.255 broadcast $VIP up
         /sbin/route add -host $VIP dev tunl0
         echo "1" >/proc/sys/net/ipv4/conf/tunl0/arp_ignore
         echo "2" >/proc/sys/net/ipv4/conf/tunl0/arp_announce
         echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
         echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
         echo "0" > /proc/sys/net/ipv4/conf/tunl0/rp_filter
         echo "0" > /proc/sys/net/ipv4/conf/all/rp_filter
         /bin/touch $LOCK
         echo "starting LVS-TUN-RIP server is ok !"
     fi
}

stop() {
         /sbin/ifconfig tunl0 down
         echo "0" >/proc/sys/net/ipv4/conf/tunl0/arp_ignore
         echo "0" >/proc/sys/net/ipv4/conf/tunl0/arp_announce
         echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
         echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
         #Remove the tun mod
         /sbin/modprobe -r tun
         /sbin/modprobe -r ipip
         rm -rf $LOCK
         echo "stopping LVS-TUN-RIP server is ok !"
}

status() {
     if [ -e $LOCK ];
     then
        echo "The LVS-TUN-RIP Server is already running !"
     else
        echo "The LVS-TUN-RIP Server is not running !"
     fi
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        start
        ;;
  status)
        status
        ;;
  *)
        echo "Usage: $1 {start|stop|restart|status}"
        exit 1
esac
exit 0

# start lvs-tun
chmod 755 /etc/init.d/lvs-tun
service lvs-tun start
chkconfig lvs-tun on

# Nginx test
echo "rs1" > /usr/share/nginx/html/index.html
echo "rs2" > /usr/share/nginx/html/index.html

for i in {1..100}; do curl 10.10.36.11; sleep 0.5; done

這一步的主要目的是讓 RS 禁言,在相對較新的版本中新增了兩個內核參數 (kernel parameter)

  • 第一個是 arp_ignore 定義接受到 ARP 請求時的相應級別
  • 第二個是 arp_announce 定義將本身地址向外通告是的通告級別
  • 第三個是 rp_filter 定義系統是否開啓對數據包源地址的校驗

總結: LVS/TUN 是全部模式中最最適用於跨網絡跨地域地理位置的一種模式,須要注意的是:

  1. 若 DIR 和 RIP 在不一樣 lan 網絡中,好比不一樣的網段,不一樣的 IDC 機房,就不須要設置 arp 仰制,不一樣網段中,arp 會被屏蔽掉,因此只需設置 ip tunne 以及報文反向驗證便可;
  2. 若 DIR 和 RIP 在同一廣播域中,須要和 LVS/DR 模式同樣在全部的 RIP 上仰制 arp,防止 arp 響應致使 arp 表混亂,這樣 lvs 就不能正常工做!

配置時除了配置 DIR,還須要須要配置後端 RS server,即在 tunl 上口配置 vip 地址(須要系統支持 tunl 才行),廣播爲爲本身,此模式下無需開啓路由轉發功能!

配置LVS/DR和LVS/TUN混合模式

DS

# 關於3中模式的參數
[packet-forwarding-method]
       -g, --gatewaying  Use gatewaying (direct routing). This is the default.
       -i, --ipip  Use ipip encapsulation (tunneling).
       -m, --masquerading  Use masquerading (network access translation, or NAT).
       Note:  Regardless of the packet-forwarding mechanism specified, real servers for addresses for which there are interfaces on the local node will  be  use  the
       local  forwarding  method, then packets for the servers will be passed to upper layer on the local node. This cannot be specified by ipvsadm, rather it set by
       the kernel as real servers are added or modified.

# ipvsadm命令行混配
/sbin/ifconfig tunl0 10.10.36.11 broadcast 10.10.36.11 netmask 255.255.255.255 up
/sbin/route add -host 10.10.36.11 dev tunl0
/sbin/ipvsadm -At 10.10.36.11:80 -s rr
/sbin/ipvsadm -at 10.10.36.11:80 -r 10.10.36.4:80 -g -w 1
/sbin/ipvsadm -at 10.10.36.11:80 -r 10.10.36.7:80 -i -w 1

# keepalived混配
vrrp_sync_group GOP {
    group {
        VI_PRI_AUTH
    }
}

vrrp_instance VI_PRI_AUTH {
    state BACKUP
    interface em1
    virtual_router_id 11
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.10.36.11/23 dev em1
    }
}

virtual_server 10.10.36.11 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    protocol TCP

    real_server 10.10.36.4 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
    }
}

virtual_server 10.10.36.11 80 {
    delay_loop 6
    lb_algo rr
    lb_kind TUN
    protocol TCP

    real_server 10.10.36.7 80 {
        weight 100
        TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
    }
}

# 檢查結果可用
[root@d126027 wangao]# for i in {1..100}; do curl 10.10.36.11; sleep 0.5; done
rs2
rs1
rs2
rs1
rs2

[root@d126009 keepalived]# ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port
TCP  10.10.36.11:80                    100      700        0    36700        0
  -> 10.10.36.4:80                      50      350        0    18350        0
  -> 10.10.36.7:80                      50      350        0    18350        0

RS

DR和TUN的模式基本不用作改動

LVS 部署之細枝末節

原做者寫得很詳細,我這邊作下引用在此表示感謝,LVS 部署之細枝末節

簡介

本文總結了在 LVS 部署過程當中須要注意的一些小細節。這些內容比較雜,而且沒有規律和內在聯繫;它們分散在 LVS 部署過程當中的各個小環節中,不是系統性的知識,也沒有主線對它們進行鏈接。你能夠經過此文對他們進行一個大概的瞭解,在實踐過程當中若是遇到能夠再過來進行詳細的查閱,以解決實際問題。

開啓 Linux 的路由轉發功能

LVS 在 VS/NAT 方式下須要開啓數據包轉發 (ip_forward) 功能。由於在 LVS 的 VS/NAT 模式下,對 IP 數據進行負載均衡時,須要把多臺真實服務器節點中的專網 IP 映射到同一個虛擬服務器的公網 IP 上;這就須要經過 NAT 技術對 IP 數據包進行轉發,從而將 IP 數據包發送到真實服務器上進行處理。LVS 在 VS/DR 模式下,由於 director 的 DIP 與真實服務器節點的 RIP 在同一網段,因此不須要開啓路由轉發功能。LVS 在 VS/TUN 模式下,IP 數據包是經過 IP 隧道技術進行封包後再分發的方式到達真實服務器節點的,也不須要開啓路由轉發功能。

開啓 Linux 的路由轉發功能的方法不少,具體細節請參閱文章 Linux ip_forward 數據包轉發

配置真實服務器的 ARP 請求與響應策略

在 ARP 協議中,爲了減小 arp 請求的次數,當主機接收到詢問本身的 arp 請求的時候,就會把源 ip 和源 Mac 放入自 己的 arp 表裏面,方便接下來的通信。若是收到不是詢問本身的包(arp 是廣播的,全部人都收到),就會丟掉,這樣不會形成 arp 表裏面無用數據太多致使 有用的記錄被刪除。

在 LVS 的 VS/DR 模式下,當內網的真實服務器(Linux 主機)要發送一個到外部網絡的 ip 包(LVS 負載器分配置過來的做業的處理結果),那麼它就會請求路由器的 Mac 地址,發送一個 arp 請求,這個 arp 請求裏面包括了本身的 ip 地址和 Mac 地址。而 linux 主機默認是使用 ip 數據包的源 ip 地址做爲 arp 裏面的源 ip 地址,而不是使用發送設備上面網絡接口卡的 ip 地址。這樣在 LVS 的 VS/DR 架構下,全部真實服務器在響應外部請求時的 IP 數據包的源地址都是同一個 VIP 地址,那麼 arp 請求就會包括 VIP 地址和設備 Mac。而路由器收到這個 arp 請求就會更新本身的 arp 緩存,這樣就會形成 ip 欺騙了,VIP 被搶奪,因此就會有問題。

因此當 LVS 運行在 VS/DR 模式下時,須要在全部真實服務器上修改 ARP 請求與響應策略,以保證以上問題不會發生。

由於在 lo(本地環回網絡接口)上配置了 VIP,因此須要對真實服務器中的 ARP 請求與響應策略配置以下:

net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_ignore=1

net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_announce=2

將以上代碼段追加到 /etc/sysctl.conf 文件中,而後執行 sysctl -p 指令就能夠。以上配置的具體含義請參閱 Linux 內核參數 arp_ignore & arp_announce 詳解

在 VS/DR 模式下 VIP 、DIP 和 RIP 必須在同一網段嗎?

在 VS/DR 模式下 VIP 、DIP 和 RIP 不須要在同一網段!

其中 VIP 必須是公網 IP;而 DIP 和 RIP 必須在同一網段(能夠是任意網段的 IP,也能夠是私網 IP),且須要節點主機的 RIP 能夠把 IP 數據包發送到一個能把 IP 數據包路由到公網的路由器上。

其實 LVS 在 VS/DR 模式下的要求是 DIP 和 RIP 必須處於同一網段中。在實際的部署過程當中發現若是在 Director 上 VIP 和 DIP 在同一網段、或在 RealServer 上 VIP 與 RIP 在同一網段,LVS 集羣工做會很不穩定。由於當一個 IP 數據包須要發到默認網關時(在 RealServer 或 Director 上),Linux 主機不知道應該使用哪一個接口(在同一子網中的 VIP 和 DIP/RIP),他可能會隨機選一個,但這個不必定能成功。我感受能夠經過在 Linux 中配置路由表來解決,但沒有驗證(哪位同窗若是有興趣能夠實踐驗證一下,若是能把驗證結果反饋給我那是再好不過了)。

配置真實服務器的 反向路由過濾 策略

在 Linux 中用於對 網卡的反向路由過濾策略進行配置的內核參數是 rp_filter,有關此參數的詳細介紹以及配置方式請參見 Linux 內核參數 rp_filter

LVS 在 VS/TUN 模式下,須要對 tunl0 虛擬網卡的反向路由過濾策略進行配置。最直接的辦法是把其值設置爲 0。

net.ipv4.conf.tunl0.rp_filter=0
net.ipv4.conf.all.rp_filter=0

由於 Linux 系統在對網卡應用反向路由過濾策略時,除了檢查本網卡的 rp_filter 參數外,還會檢查 all 配置項上的 rp_filter 參數,並使用這兩個值中較大的值做爲應用到當前網卡的反向路由過濾策略。因此須要同時把 net.ipv4.conf.all.rp_filter 參數設置爲 0。

配置 tunl0 網卡

LVS 在 VS/TUN 模式下,須要在每一個真實服務器上開啓 tunl0 網卡,並把 VIP 配置到 tunl0 網卡上。有關 tunl0 網卡的說明能夠參考一下 Linux 中 IP 隧道模塊淺析

LVS 在 VS/TUN 模式下 RealServer 上的防火牆配置

LVS 在 VS/TUN 模式下 由於 Director 主機須要經過 ipip 協議向 RealServer 分發數據包;因此須要在 RealServer 上配置防火牆,容許 ipip 協議的數據包經過。

iptables -I INPUT 1 -p 4 -j ACCEPT

常見問題

配置日誌

此配置爲可選步驟

keepalived 默認將日誌輸出到系統日誌/var/log/messages中,由於系統日誌不少,查詢問題時相對麻煩。

咱們能夠將 keepalived 的日誌單獨拿出來,這須要修改日誌輸出路徑。

# 修改 Keepalived 配置
vi /etc/sysconfig/keepalived

# Options for keepalived. See `keepalived --help' output and keepalived(8) and
# keepalived.conf(5) man pages for a list of all options. Here are the most
# common ones :
#
# --vrrp               -P    Only run with VRRP subsystem.
# --check              -C    Only run with Health-checker subsystem.
# --dont-release-vrrp  -V    Dont remove VRRP VIPs & VROUTEs on daemon stop.
# --dont-release-ipvs  -I    Dont remove IPVS topology on daemon stop.
# --dump-conf          -d    Dump the configuration data.
# --log-detail         -D    Detailed log messages.
# --log-facility       -S    0-7 Set local syslog facility (default=LOG_DAEMON)
#

# 把 KEEPALIVED_OPTIONS=」-D」 修改成 KEEPALIVED_OPTIONS=」-D -d -S 0」,其中 -S 指定 syslog 的 facility
KEEPALIVED_OPTIONS="-D -d -S 0"

# 修改 /etc/rsyslog.conf 末尾添加
vi /etc/rsyslog.conf 
local0.*                                                /var/log/keepalived.log

# 重啓日誌記錄服務
systemctl restart rsyslog

# 重啓 keepalived
systemctl restart keepalived

# 此時能夠從 /var/log/keepalived.log 查看日誌了
tailf /var/log/keepalived.log

ARP致使MAC地址衝突

[root@sg-gop-10-65-32-35 wangao]# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
10.65.32.31              ether   48:8e:ef:7b:c6:0a   C                     bond0
10.65.32.83              ether   50:5d:ac:ed:89:dd   C                     bond0
10.65.32.254             ether   00:00:0c:9f:f0:ec   C                     bond0
10.65.32.252             ether   bc:16:65:68:07:81   C                     bond0
10.65.32.34              ether   50:1d:93:f5:eb:97   C                     bond0
10.65.32.8               ether   48:8e:ef:7c:0a:8d   C                     bond0
10.65.32.253             ether   18:e7:28:97:e5:01   C                     bond0
[root@sg-gop-10-65-32-35 wangao]# arp -d 10.65.32.31
[root@sg-gop-10-65-32-35 wangao]#
[root@sg-gop-10-65-32-35 wangao]#
[root@sg-gop-10-65-32-35 wangao]# telnet 10.65.32.31 12100
Trying 10.65.32.31...
Connected to 10.65.32.31.
Escape character is '^]'.

[root@sg-gop-10-65-32-35 wangao]# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
10.65.32.31              ether   48:8e:ef:7b:c7:5a   C                     bond0
10.65.32.70              ether   00:2e:c7:3a:a5:b5   C                     bond0
10.65.32.83              ether   50:5d:ac:ed:89:dd   C                     bond0
10.65.32.254             ether   00:00:0c:9f:f0:ec   C                     bond0
10.65.32.252             ether   bc:16:65:68:07:81   C                     bond0
10.65.32.34              ether   50:1d:93:f5:eb:97   C                     bond0
10.65.32.8               ether   48:8e:ef:7c:0a:8d   C                     bond0
10.65.32.253             ether   18:e7:28:97:e5:01   C                     bond0

LVS和Keepalived系列

LVS和Keepalived的原理介紹和配置實踐
LVS原理介紹和配置實踐
Keepalived原理介紹和配置實踐
LVS-NAT原理介紹和配置實踐
LVS-DR原理介紹和配置實踐
LVS-TUN原理介紹和配置實踐

相關文章
相關標籤/搜索