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

前言

負(fù)載均衡技術(shù)Load Balance簡稱LB是構(gòu)建大型網(wǎng)站必不可少的架構(gòu)策略之一财著。它的目的是把用戶的請求分發(fā)到多臺后端的設(shè)備上仙辟,用以均衡服務(wù)器的負(fù)載庆尘。我們可以把負(fù)載均衡器劃分為兩大類:硬件負(fù)載均衡器和軟件負(fù)載均衡器。這里重點介紹軟件實現(xiàn)方法中的LVS和Keepalived空骚。

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/lvs-keepalived/

擴(kuò)展閱讀

LVS - http://www.linuxvirtualserver.org/zh/index.html
Keepalived - http://www.keepalived.org/


ReadMe

參考文章

LVS - http://www.linuxvirtualserver.org/Documents.html
How virtual server works? - http://www.linuxvirtualserver.org/how.html
Keepalived - http://www.keepalived.org/doc/
LVS入門系列:初識LVS與LVS-NAT - http://www.zsythink.net/archives/2134
使用 LVS 實現(xiàn)負(fù)載均衡原理及安裝配置詳解 - https://www.cnblogs.com/liwei0526vip/p/6370103.html
LVS 之 VS/TUN 應(yīng)用場景 - http://www.reibang.com/p/5524034b6086
LVS和Keepalived官方中文手冊PDF - https://pan.baidu.com/s/1s0P6nUt8WF6o_N3wdE3uKg

【均衡負(fù)載之 LVS 系列一】 - LVS 五種工作模式
【均衡負(fù)載之 LVS 系列二】 - LVS 基礎(chǔ)配置
【均衡負(fù)載之 LVS 系列三】 - 高可用 LVS+KeepAlived 集群
【均衡負(fù)載之 LVS 系列四】 - OSPF (ECMP)-LVS 集群

相關(guān)術(shù)語

以下術(shù)語涉及LVS三種工作模式的原理

  • LB (Load Balancer 負(fù)載均衡)
  • HA (High Available 高可用)
  • Failover (失敗切換)
  • Cluster (集群)
  • LVS (Linux Virtual Server Linux 虛擬服務(wù)器)
  • DS (Director Server)囤屹,指的是前端負(fù)載均衡器節(jié)點
  • RS (Real Server)熬甚,后端真實的工作服務(wù)器
  • VIP (Virtual IP),虛擬的IP地址肋坚,向外部直接面向用戶請求乡括,作為用戶請求的目標(biāo)的 IP 地址
  • DIP (Director IP),主要用于和內(nèi)部主機(jī)通訊的 IP 地址
  • RIP (Real Server IP)智厌,后端服務(wù)器的 IP 地址
  • CIP (Client IP)粟判,訪問客戶端的 IP 地址

負(fù)載均衡(LB)

負(fù)載均衡實現(xiàn)方法有兩種:硬件實現(xiàn)和軟件實現(xiàn)

硬件比較常見的有:

  1. F5 Big-IP
  2. Citrix Netscaler

軟件比較常見的有:

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

LVS特點是:

  1. 首先它是基于4層的網(wǎng)絡(luò)協(xié)議的,抗負(fù)載能力強峦剔,對于服務(wù)器的硬件要求除了網(wǎng)卡外档礁,其他沒有太多要求;
  2. 配置性比較低吝沫,這是一個缺點也是一個優(yōu)點呻澜,因為沒有可太多配置的東西,大大減少了人為出錯的幾率惨险;
  3. 應(yīng)用范圍比較廣羹幸,不僅僅對web服務(wù)做負(fù)載均衡,還可以對其他應(yīng)用(mysql)做負(fù)載均衡辫愉;
  4. LVS架構(gòu)中存在一個虛擬IP的概念栅受,需要向IDC多申請一個IP來做虛擬IP。

Nginx負(fù)載均衡器的特點是:

  1. 工作在網(wǎng)絡(luò)的7層之上,可以針對http應(yīng)用做一些分流的策略屏镊,比如針對域名依疼、目錄結(jié)構(gòu);
  2. Nginx安裝和配置比較簡單而芥,測試起來比較方便律罢;
  3. 也可以承擔(dān)高的負(fù)載壓力且穩(wěn)定,一般能支撐超過上萬次的并發(fā)棍丐;
  4. Nginx可以通過端口檢測到服務(wù)器內(nèi)部的故障误辑,比如根據(jù)服務(wù)器處理網(wǎng)頁返回的狀態(tài)碼、超時等等歌逢,并且會把返回錯誤的請求重新提交到另一個節(jié)點巾钉,不過其中缺點就是不支持url來檢測;
  5. Nginx對請求的異步處理可以幫助節(jié)點服務(wù)器減輕負(fù)載秘案;
  6. Nginx能支持http和Email睛琳,這樣就在適用范圍上面小很多;
  7. 默認(rèn)有三種調(diào)度算法: 輪詢踏烙、weight以及ip_hash(可以解決會話保持的問題)师骗,還可以支持第三方的fair和url_hash等調(diào)度算法;

HAProxy的特點是:

  1. HAProxy是工作在網(wǎng)絡(luò)7層之上讨惩;
  2. 支持Session的保持辟癌,Cookie的引導(dǎo)等;
  3. 支持url檢測后端的服務(wù)器出問題的檢測會有很好的幫助荐捻;
  4. 支持的負(fù)載均衡算法:動態(tài)加權(quán)輪循(Dynamic Round Robin)黍少,加權(quán)源地址哈希(Weighted Source Hash),加權(quán)URL哈希和加權(quán)參數(shù)哈希(Weighted Parameter Hash)处面;
  5. 單純從效率上來講HAProxy更會比Nginx有更出色的負(fù)載均衡速度厂置;
  6. HAProxy可以對Mysql進(jìn)行負(fù)載均衡,對后端的DB節(jié)點進(jìn)行檢測和負(fù)載均衡魂角。

LVS+Keepalived 簡介

在lvs+keepalived環(huán)境里面昵济,lvs主要的工作是提供調(diào)度算法,把客戶端請求按照需求調(diào)度在real服務(wù)器野揪,keepalived主要的工作是提供lvs控制器的一個冗余访忿,并且對real服務(wù)器做健康檢查,發(fā)現(xiàn)不健康的real服務(wù)器斯稳,就把它從lvs集群中剔除海铆,real服務(wù)器只負(fù)責(zé)提供服務(wù)。

LVS

LVS是一個開源的軟件挣惰,可以實現(xiàn)LINUX平臺下的簡單負(fù)載均衡卧斟。LVS是Linux Virtual Server的縮寫殴边,意思是Linux虛擬服務(wù)器。

LB 集群的架構(gòu)和原理很簡單珍语,就是當(dāng)用戶的請求過來時锤岸,會直接分發(fā)到 Director Server 上,然后它把用戶的請求根據(jù)設(shè)置好的調(diào)度算法廊酣,智能均衡地分發(fā)到后端真正服務(wù)器 (real server) 上能耻。為了避免不同機(jī)器上用戶請求得到的數(shù)據(jù)不一樣赏枚,需要用到了共享存儲亡驰,這樣保證所有用戶請求的數(shù)據(jù)是一樣的。

LVS 是 Linux Virtual Server 的簡稱饿幅,也就是 Linux 虛擬服務(wù)器凡辱。這是一個由章文嵩博士發(fā)起的一個開源項目,它的官方網(wǎng)站是 http://www.linuxvirtualserver.org 現(xiàn)在 LVS 已經(jīng)是 Linux 內(nèi)核標(biāo)準(zhǔn)的一部分栗恩。使用 LVS 可以達(dá)到的技術(shù)目標(biāo)是:通過 LVS 達(dá)到的負(fù)載均衡技術(shù)和 Linux 操作系統(tǒng)實現(xiàn)一個高性能高可用的 Linux 服務(wù)器集群透乾,它具有良好的可靠性、可擴(kuò)展性和可操作性磕秤。從而以低廉的成本實現(xiàn)最優(yōu)的性能乳乌。LVS 是一個實現(xiàn)負(fù)載均衡集群的開源軟件項目,LVS 架構(gòu)從邏輯上可分為調(diào)度層市咆、Server 集群層和共享存儲汉操。

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

Virtual Server via Network Address Translation(VS/NAT)
通過網(wǎng)絡(luò)地址轉(zhuǎn)換,調(diào)度器重寫請求報文的目標(biāo)地址蒙兰,根據(jù)預(yù)設(shè)的調(diào)度算法磷瘤,將請求分派給后端的真實服務(wù)器;真實服務(wù)器的響應(yīng)報文通過調(diào)度器時搜变,報文的源地址被重寫采缚,再返回給客戶,完成整個負(fù)載調(diào)度過程挠他。

Virtual Server via IP Tunneling(VS/TUN)
采用NAT技術(shù)時扳抽,由于請求和響應(yīng)報文都必須經(jīng)過調(diào)度器地址重寫,當(dāng)客戶請求越來越多時殖侵,調(diào)度器的處理能力將成為瓶頸摔蓝。為了解決這個問題,調(diào)度器把請求報 文通過IP隧道轉(zhuǎn)發(fā)至真實服務(wù)器愉耙,而真實服務(wù)器將響應(yīng)直接返回給客戶贮尉,所以調(diào)度器只處理請求報文。由于一般網(wǎng)絡(luò)服務(wù)應(yīng)答比請求報文大許多朴沿,采用 VS/TUN技術(shù)后猜谚,集群系統(tǒng)的最大吞吐量可以提高10倍败砂。

Virtual Server via Direct Routing(VS/DR)
VS/DR通過改寫請求報文的MAC地址,將請求發(fā)送到真實服務(wù)器魏铅,而真實服務(wù)器將響應(yīng)直接返回給客戶昌犹。同VS/TUN技術(shù)一樣,VS/DR技術(shù)可極大地 提高集群系統(tǒng)的伸縮性览芳。這種方法沒有IP隧道的開銷斜姥,對集群中的真實服務(wù)器也沒有必須支持IP隧道協(xié)議的要求,但是要求調(diào)度器與真實服務(wù)器都有一塊網(wǎng)卡連 在同一物理網(wǎng)段上沧竟。

三種模式的主要區(qū)別

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 模式
對服務(wù)器的要求 服務(wù)節(jié)點可以使任何操作系統(tǒng) 必須支持 IP 隧道铸敏,目前只有 Linux 系統(tǒng)支持 服務(wù)器節(jié)點支持虛擬網(wǎng)卡設(shè)備,能夠禁用設(shè)備的 ARP 響應(yīng)
網(wǎng)絡(luò)要求 擁有私有 IP 地址的局域網(wǎng)絡(luò) 擁有合法 IP 地址的局域悟泵,網(wǎng)或廣域網(wǎng) 擁有合法 IP 地址的局域杈笔,服務(wù)器節(jié)點與負(fù)載均衡器必須在同一個網(wǎng)段
通常支持節(jié)點數(shù)量 10 到 20 個,根據(jù)負(fù)載均衡器的處理能力而定 較高糕非,可以支持 100 個服務(wù)節(jié)點 較高蒙具,可以支持 100 個服務(wù)節(jié)點
網(wǎng)關(guān) 負(fù)載均衡器為服務(wù)器節(jié)點網(wǎng)關(guān) 服務(wù)器的節(jié)點同自己的網(wǎng)關(guān)或者路由器連接,不經(jīng)過負(fù)載均衡器 服務(wù)節(jié)點同自己的網(wǎng)關(guān)或者路由器連接朽肥,不經(jīng)過負(fù)載均衡器
服務(wù)節(jié)點安全性 較好禁筏,采用內(nèi)部 IP,服務(wù)節(jié)點隱蔽 較差衡招,采用公用 IP 地址篱昔,節(jié)點安全暴露 較差,采用公用 IP 地址蚁吝,節(jié)點安全暴露
IP 要求 僅需要一個合法的 IP 地址作為 VIP 地址 除了 VIPO 地址外旱爆,每個服務(wù)器界定啊需要擁有合法的 IP 地址,可以直接從路由到客戶端 除了 VIP 外窘茁,每個服務(wù)節(jié)點需擁有合法的 IP 地址怀伦,可以直接從路由到客戶端
特點 地址轉(zhuǎn)換 封裝 IP 修改 MAC 地址
配置復(fù)雜度 簡單 復(fù)雜 復(fù)雜

基本工作原理

image
  1. 當(dāng)用戶向負(fù)載均衡調(diào)度器(Director Server)發(fā)起請求,調(diào)度器將請求發(fā)往至內(nèi)核空間
  2. PREROUTING鏈?zhǔn)紫葧邮盏接脩粽埱螅袛嗄繕?biāo)IP確定是本機(jī)IP,將數(shù)據(jù)包發(fā)往INPUT鏈
  3. IPVS是工作在INPUT鏈上的廉侧,當(dāng)用戶請求到達(dá)INPUT時灵再,IPVS會將用戶請求和自己已定義好的集群服務(wù)進(jìn)行比對扰魂,如果用戶請求的就是定義的集群服務(wù),那么此時IPVS會強行修改數(shù)據(jù)包里的目標(biāo)IP地址及端口,并將新的數(shù)據(jù)包發(fā)往POSTROUTING鏈
  4. POSTROUTING鏈接收數(shù)據(jù)包后發(fā)現(xiàn)目標(biāo)IP地址剛好是自己的后端服務(wù)器,那么此時通過選路流椒,將數(shù)據(jù)包最終發(fā)送給后端的服務(wù)器

LVS的組成

LVS 由2部分程序組成,包括 ipvs 和 ipvsadm明也。

  1. ipvs(ip virtual server):一段代碼工作在內(nèi)核空間宣虾,叫ipvs惯裕,是真正生效實現(xiàn)調(diào)度的代碼。
  2. ipvsadm:另外一段是工作在用戶空間绣硝,叫ipvsadm蜻势,負(fù)責(zé)為ipvs內(nèi)核框架編寫規(guī)則,定義誰是集群服務(wù)鹉胖,而誰是后端真實的服務(wù)器(Real Server)

工作模式

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

LVS是四層負(fù)載均衡握玛,也就是說建立在OSI模型的第四層——傳輸層之上,傳輸層上有我們熟悉的TCP/UDP甫菠,LVS支持TCP/UDP的負(fù)載均衡挠铲。因為LVS是四層負(fù)載均衡,因此它相對于其它高層負(fù)載均衡的解決辦法淑蔚,比如DNS域名輪流解析市殷、應(yīng)用層負(fù)載的調(diào)度愕撰、客戶端的調(diào)度等刹衫,它的效率是非常高的。

LVS的IP負(fù)載均衡技術(shù)是通過IPVS模塊來實現(xiàn)的搞挣,IPVS是LVS集群系統(tǒng)的核心軟件带迟,它的主要作用是:安裝在Director Server上,同時在Director Server上虛擬出一個IP地址囱桨,用戶必須通過這個虛擬的IP地址訪問服務(wù)仓犬。這個虛擬IP一般稱為LVS的VIP,即Virtual IP舍肠。訪問的請求首先經(jīng)過VIP到達(dá)負(fù)載調(diào)度器搀继,然后由負(fù)載調(diào)度器從Real Server列表中選取一個服務(wù)節(jié)點響應(yīng)用戶的請求。 當(dāng)用戶的請求到達(dá)負(fù)載調(diào)度器后翠语,調(diào)度器如何將請求發(fā)送到提供服務(wù)的Real Server節(jié)點叽躯,而Real Server節(jié)點如何返回數(shù)據(jù)給用戶,是IPVS實現(xiàn)的重點技術(shù)肌括,IPVS實現(xiàn)負(fù)載均衡機(jī)制有幾種点骑,分別是NAT、DR谍夭、TUN及FULLNAT黑滴。

LVS/NAT

image

重點理解NAT方式的實現(xiàn)原理和數(shù)據(jù)包的改變。

(1). 當(dāng)用戶請求到達(dá)Director Server紧索,此時請求的數(shù)據(jù)報文會先到內(nèi)核空間的PREROUTING鏈袁辈。 此時報文的源IP為CIP,目標(biāo)IP為VIP
(2). PREROUTING檢查發(fā)現(xiàn)數(shù)據(jù)包的目標(biāo)IP是本機(jī)珠漂,將數(shù)據(jù)包送至INPUT鏈
(3). IPVS比對數(shù)據(jù)包請求的服務(wù)是否為集群服務(wù)晚缩,若是葛菇,修改數(shù)據(jù)包的目標(biāo)IP地址為后端服務(wù)器IP,然后將數(shù)據(jù)包發(fā)至POSTROUTING鏈橡羞。 此時報文的源IP為CIP眯停,目標(biāo)IP為RIP
(4). POSTROUTING鏈通過選路,將數(shù)據(jù)包發(fā)送給Real Server
(5). Real Server比對發(fā)現(xiàn)目標(biāo)為自己的IP卿泽,開始構(gòu)建響應(yīng)報文發(fā)回給Director Server莺债。 此時報文的源IP為RIP,目標(biāo)IP為CIP
(6). Director Server在響應(yīng)客戶端前签夭,此時會將源IP地址修改為自己的VIP地址齐邦,然后響應(yīng)給客戶端。 此時報文的源IP為VIP第租,目標(biāo)IP為CIP

LVS/NAT模型的特性

  • RS應(yīng)該使用私有地址措拇,RS的網(wǎng)關(guān)必須指向DIP
  • DIP和RIP必須在同一個網(wǎng)段內(nèi)
  • 請求和響應(yīng)報文都需要經(jīng)過Director Server,高負(fù)載場景中慎宾,Director Server易成為性能瓶頸
  • 支持端口映射
  • RS可以使用任意操作系統(tǒng)
  • 缺陷:對Director Server壓力會比較大丐吓,請求和響應(yīng)都需經(jīng)過director server

NAT(Network Address Translation 網(wǎng)絡(luò)地址轉(zhuǎn)換)是一種外網(wǎng)和內(nèi)外地址映射的技術(shù),內(nèi)網(wǎng)可以是私有網(wǎng)址趟据,外網(wǎng)可以使用NAT方法修改數(shù)據(jù)報頭券犁,讓外網(wǎng)與內(nèi)網(wǎng)能夠互相通信。NAT模式下汹碱,網(wǎng)絡(luò)數(shù)據(jù)報的進(jìn)出都要經(jīng)過LVS的處理粘衬。LVS需作為RS(真實服務(wù)器)的網(wǎng)關(guān)。當(dāng)包到達(dá)LVS時咳促,LVS做目標(biāo)地址轉(zhuǎn)換(DNAT)稚新,將目標(biāo)IP改為RS的IP。RS接收到包以后跪腹,仿佛是客戶端直接發(fā)給它的一樣褂删。RS處理完,返回響應(yīng)時尺迂,源IP是RS IP笤妙,目標(biāo)IP是客戶端的IP。這時RS的包通過網(wǎng)(LVS)中轉(zhuǎn)噪裕,LVS會做源地址轉(zhuǎn)換(SNAT)蹲盘,將包的源地址改為VIP,這樣膳音,這個包對客戶端看起來就仿佛是LVS直接返回給它的召衔。客戶端無法感知到后端RS的存在祭陷。

(1)RIP和DIP必須在同一個IP網(wǎng)絡(luò)苍凛,且應(yīng)該使用私網(wǎng)地址趣席;RS的網(wǎng)關(guān)要指向DIP;
(2)請求報文和響應(yīng)報文都必須經(jīng)由Director轉(zhuǎn)發(fā)醇蝴;Director易于成為系統(tǒng)瓶頸宣肚;
(3)支持端口映射,可修改請求報文的目標(biāo)PORT悠栓;
(4)vs必須是Linux系統(tǒng)霉涨,rs可以是任意系統(tǒng);

缺點:在整個過程中惭适,所有輸入輸出的流量都要經(jīng)過LVS 調(diào)度服務(wù)器笙瑟。顯然,LVS 調(diào)度服務(wù)器的網(wǎng)絡(luò)I/O壓力將會非常大癞志,因此很容易成為瓶頸往枷,特別是對于請求流量很小,而響應(yīng)流量很大的Web類應(yīng)用來說尤為如此凄杯。

優(yōu)點:NAT模式的優(yōu)點在于配置及管理簡單错洁,由于了使用NAT技術(shù),LVS 調(diào)度器及應(yīng)用服務(wù)器可以在不同網(wǎng)段中盾舌,網(wǎng)絡(luò)架構(gòu)更靈活墓臭,應(yīng)用服務(wù)器只需要進(jìn)行簡單的網(wǎng)絡(luò)設(shè)定即可加入集群蘸鲸。

LVS/DR

image

重點將請求報文的目標(biāo)MAC地址設(shè)定為挑選出的RS的MAC地址

(1) 當(dāng)用戶請求到達(dá)Director Server妖谴,此時請求的數(shù)據(jù)報文會先到內(nèi)核空間的PREROUTING鏈。 此時報文的源IP為CIP酌摇,目標(biāo)IP為VIP
(2) PREROUTING檢查發(fā)現(xiàn)數(shù)據(jù)包的目標(biāo)IP是本機(jī)膝舅,將數(shù)據(jù)包送至INPUT鏈
(3) IPVS比對數(shù)據(jù)包請求的服務(wù)是否為集群服務(wù),若是窑多,將請求報文中的源MAC地址修改為DIP的MAC地址仍稀,將目標(biāo)MAC地址修改RIP的MAC地址,然后將數(shù)據(jù)包發(fā)至POSTROUTING鏈埂息。 此時的源IP和目的IP均未修改技潘,僅修改了源MAC地址為DIP的MAC地址,目標(biāo)MAC地址為RIP的MAC地址
(4) 由于DS和RS在同一個網(wǎng)絡(luò)中千康,所以是通過二層來傳輸享幽。POSTROUTING鏈檢查目標(biāo)MAC地址為RIP的MAC地址,那么此時數(shù)據(jù)包將會發(fā)至Real Server拾弃。
(5) RS發(fā)現(xiàn)請求報文的MAC地址是自己的MAC地址值桩,就接收此報文。處理完成之后豪椿,將響應(yīng)報文通過lo接口傳送給eth0網(wǎng)卡然后向外發(fā)出奔坟。 此時的源IP地址為VIP携栋,目標(biāo)IP為CIP
(6) 響應(yīng)報文最終送達(dá)至客戶端

LVS/DR模型的特性

  • 特點1:保證前端路由將目標(biāo)地址為VIP報文統(tǒng)統(tǒng)發(fā)給Director Server,而不是RS
  • RS可以使用私有地址咳秉;也可以是公網(wǎng)地址婉支,如果使用公網(wǎng)地址,此時可以通過互聯(lián)網(wǎng)對RIP進(jìn)行直接訪問
  • RS跟Director Server必須在同一個物理網(wǎng)絡(luò)中
  • 所有的請求報文經(jīng)由Director Server澜建,但響應(yīng)報文必須不能進(jìn)過Director Server
  • 不支持地址轉(zhuǎn)換磅摹,也不支持端口映射
  • RS可以是大多數(shù)常見的操作系統(tǒng)
  • RS的網(wǎng)關(guān)絕不允許指向DIP(因為我們不允許他經(jīng)過director)
  • RS上的lo接口配置VIP的IP地址
  • 缺陷:RS和DS必須在同一機(jī)房中

特點1的解決方案:

  • 在前端路由器做靜態(tài)地址路由綁定,將對于VIP的地址僅路由到Director Server
  • 存在問題:用戶未必有路由操作權(quán)限霎奢,因為有可能是運營商提供的户誓,所以這個方法未必實用
  • arptables:在arp的層次上實現(xiàn)在ARP解析時做防火墻規(guī)則,過濾RS響應(yīng)ARP請求幕侠。這是由iptables提供的
  • 修改RS上內(nèi)核參數(shù)(arp_ignore和arp_announce)將RS上的VIP配置在lo接口的別名上帝美,并限制其不能響應(yīng)對VIP地址解析請求。

DR(Direct Routing 直接路由模式)此模式時LVS 調(diào)度器只接收客戶發(fā)來的請求并將請求轉(zhuǎn)發(fā)給后端服務(wù)器晤硕,后端服務(wù)器處理請求后直接把內(nèi)容直接響應(yīng)給客戶悼潭,而不用再次經(jīng)過LVS調(diào)度器。LVS只需要將網(wǎng)絡(luò)幀的MAC地址修改為某一臺后端服務(wù)器RS的MAC舞箍,該包就會被轉(zhuǎn)發(fā)到相應(yīng)的RS處理舰褪,注意此時的源IP和目標(biāo)IP都沒變。RS收到LVS轉(zhuǎn)發(fā)來的包時疏橄,鏈路層發(fā)現(xiàn)MAC是自己的占拍,到上面的網(wǎng)絡(luò)層,發(fā)現(xiàn)IP也是自己的捎迫,于是這個包被合法地接受晃酒,RS感知不到前面有LVS的存在。而當(dāng)RS返回響應(yīng)時窄绒,只要直接向源IP(即用戶的IP)返回即可贝次,不再經(jīng)過LVS。

注意:
(1) 確保前端路由器將目標(biāo)IP為VIP的請求報文發(fā)往Director:
(a) 在前端網(wǎng)關(guān)做靜態(tài)綁定彰导;
(b) 在RS上使用arptables蛔翅;
(c) 在RS上修改內(nèi)核參數(shù)以限制arp通告及應(yīng)答級別;
arp_announce
arp_ignore
(2) RS的RIP可以使用私網(wǎng)地址位谋,也可以是公網(wǎng)地址山析;RIP與DIP在同一IP網(wǎng)絡(luò);RIP的網(wǎng)關(guān)不能指向DIP倔幼,以確保響應(yīng)報文不會經(jīng)由Director盖腿;
(3) RS跟Director要在同一個物理網(wǎng)絡(luò);
(4) 請求報文要經(jīng)由Director,但響應(yīng)不能經(jīng)由Director翩腐,而是由RS直接發(fā)往Client鸟款;
(5) 此模式不支持端口映射;

缺點:唯一的缺陷在于它要求LVS 調(diào)度器及所有應(yīng)用服務(wù)器在同一個網(wǎng)段中茂卦,因此不能實現(xiàn)集群的跨網(wǎng)段應(yīng)用何什。

優(yōu)點:可見在處理過程中LVS Route只處理請求的直接路由轉(zhuǎn)發(fā),所有響應(yīng)結(jié)果由各個應(yīng)用服務(wù)器自行處理等龙,并對用戶進(jìn)行回復(fù)处渣,網(wǎng)絡(luò)流量將集中在LVS調(diào)度器之上。

LVS/TUN

image

在原有的IP報文外再次封裝多一層IP首部蛛砰,內(nèi)部IP首部(源地址為CIP罐栈,目標(biāo)IIP為VIP),外層IP首部(源地址為DIP泥畅,目標(biāo)IP為RIP)

(1) 當(dāng)用戶請求到達(dá)Director Server荠诬,此時請求的數(shù)據(jù)報文會先到內(nèi)核空間的PREROUTING鏈。 此時報文的源IP為CIP位仁,目標(biāo)IP為VIP 柑贞。
(2) PREROUTING檢查發(fā)現(xiàn)數(shù)據(jù)包的目標(biāo)IP是本機(jī),將數(shù)據(jù)包送至INPUT鏈
(3) IPVS比對數(shù)據(jù)包請求的服務(wù)是否為集群服務(wù)聂抢,若是钧嘶,在請求報文的首部再次封裝一層IP報文,封裝源IP為DIP琳疏,目標(biāo)IP為RIP有决。然后發(fā)至POSTROUTING鏈。 此時源IP為DIP轿亮,目標(biāo)IP為RIP
(4) POSTROUTING鏈根據(jù)最新封裝的IP報文疮薇,將數(shù)據(jù)包發(fā)至RS(因為在外層封裝多了一層IP首部,所以可以理解為此時通過隧道傳輸)我注。 此時源IP為DIP,目標(biāo)IP為RIP
(5) RS接收到報文后發(fā)現(xiàn)是自己的IP地址迟隅,就將報文接收下來但骨,拆除掉最外層的IP后,會發(fā)現(xiàn)里面還有一層IP首部智袭,而且目標(biāo)是自己的lo接口VIP奔缠,那么此時RS開始處理此請求,處理完成之后吼野,通過lo接口送給eth0網(wǎng)卡校哎,然后向外傳遞。 此時的源IP地址為VIP,目標(biāo)IP為CIP
(6) 響應(yīng)報文最終送達(dá)至客戶端

LVS/TUN模型特性

  • RIP闷哆、VIP腰奋、DIP全是公網(wǎng)地址
  • RS的網(wǎng)關(guān)不會也不可能指向DIP
  • 所有的請求報文經(jīng)由Director Server,但響應(yīng)報文必須不能進(jìn)過Director Server
  • 不支持端口映射
  • RS的系統(tǒng)必須支持隧道

其實企業(yè)中最常用的是 DR 實現(xiàn)方式抱怔,而 NAT 配置上比較簡單和方便劣坊,后邊實踐中會總結(jié) DR 和 NAT 具體使用配置過程。

TUN(virtual server via ip tunneling IP 隧道)調(diào)度器把請求的報文通過IP隧道轉(zhuǎn)發(fā)到真實的服務(wù)器屈留。真實的服務(wù)器將響應(yīng)處理后的數(shù)據(jù)直接返回給客戶端局冰。這樣調(diào)度器就只處理請求入站報文。此轉(zhuǎn)發(fā)方式不修改請求報文的IP首部(源IP為CIP灌危,目標(biāo)IP為VIP)康二,而在原IP報文之外再封裝一個IP首部(源IP是DIP,目標(biāo)IP是RIP)勇蝙,將報文發(fā)往挑選出的目標(biāo)RS赠摇;RS直接響應(yīng)給客戶端(源IP是VIP,目標(biāo)IP是CIP)浅蚪,由于一般網(wǎng)絡(luò)服務(wù)應(yīng)答數(shù)據(jù)比請求報文大很多藕帜,采用lvs-tun模式后,集群系統(tǒng)的最大吞吐量可以提高10倍

注意:
(1) DIP, VIP, RIP都應(yīng)該是公網(wǎng)地址惜傲;
(2) RS的網(wǎng)關(guān)不能洽故,也不可能指向DIP;
(3) 請求報文要經(jīng)由Director盗誊,但響應(yīng)不能經(jīng)由Director时甚;
(4) 此模式不支持端口映射;
(5) RS的操作系統(tǒng)得支持隧道功能

缺點:由于后端服務(wù)器RS處理數(shù)據(jù)后響應(yīng)發(fā)送給用戶哈踱,此時需要租借大量IP(特別是后端服務(wù)器使用較多的情況下)荒适。

優(yōu)點:實現(xiàn)lvs-tun模式時,LVS 調(diào)度器將TCP/IP請求進(jìn)行重新封裝并轉(zhuǎn)發(fā)給后端服務(wù)器开镣,由目標(biāo)應(yīng)用服務(wù)器直接回復(fù)用戶刀诬。應(yīng)用服務(wù)器之間是通過IP 隧道來進(jìn)行轉(zhuǎn)發(fā),故兩者可以存在于不同的網(wǎng)段中邪财。

LVS/FULLNAT

lvs-fullnat工作模式默認(rèn)不支持

此模式類似DNAT陕壹,它通過同時修改請求報文的源IP地址和目標(biāo)IP地址進(jìn)行轉(zhuǎn)發(fā)

注意:
(1) VIP是公網(wǎng)地址,RIP和DIP是私網(wǎng)地址树埠,且通常不在同一IP網(wǎng)絡(luò)糠馆;因此,RIP的網(wǎng)關(guān)一般不會指向DIP怎憋;
(2) RS收到的請求報文源地址是DIP又碌,因此九昧,只需響應(yīng)給DIP;但Director還要將其發(fā)往Client毕匀;
(3) 請求和響應(yīng)報文都經(jīng)由Director铸鹰;
(4) 支持端口映射;

調(diào)度算法

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

針對不同的網(wǎng)絡(luò)服務(wù)需求和服務(wù)器配置期揪,IPVS調(diào)度器實現(xiàn)了如下八種負(fù)載調(diào)度算法:

輪叫調(diào)度rr(Round Robin)
調(diào)度器通過"輪叫"調(diào)度算法將外部請求按順序輪流分配到集群中的真實服務(wù)器上掉奄,它均等地對待每一臺服務(wù)器,而不管服務(wù)器上實際的連接數(shù)和系統(tǒng)負(fù)載凤薛。

加權(quán)輪叫wrr(Weighted Round Robin)
調(diào)度器通過"加權(quán)輪叫"調(diào)度算法根據(jù)真實服務(wù)器的不同處理能力來調(diào)度訪問請求姓建。這樣可以保證處理能力強的服務(wù)器處理更多的訪問流量。調(diào)度器可以自動問詢真實服務(wù)器的負(fù)載情況缤苫,并動態(tài)地調(diào)整其權(quán)值速兔。

最少鏈接lc(Least Connections)
調(diào)度器通過"最少連接"調(diào)度算法動態(tài)地將網(wǎng)絡(luò)請求調(diào)度到已建立的鏈接數(shù)最少的服務(wù)器上。如果集群系統(tǒng)的真實服務(wù)器具有相近的系統(tǒng)性能活玲,采用"最小連接"調(diào)度算法可以較好地均衡負(fù)載涣狗。

加權(quán)最少鏈接wlc(Weighted Least Connections)
在集群系統(tǒng)中的服務(wù)器性能差異較大的情況下,調(diào)度器采用"加權(quán)最少鏈接"調(diào)度算法優(yōu)化負(fù)載均衡性能舒憾,具有較高權(quán)值的服務(wù)器將承受較大比例的活動連接負(fù)載镀钓。調(diào)度器可以自動問詢真實服務(wù)器的負(fù)載情況,并動態(tài)地調(diào)整其權(quán)值镀迂。

基于局部性的最少鏈接lblc(Locality-Based Least Connections)
"基于局部性的最少鏈接" 調(diào)度算法是針對目標(biāo)IP地址的負(fù)載均衡丁溅,目前主要用于Cache集群系統(tǒng)。該算法根據(jù)請求的目標(biāo)IP地址找出該目標(biāo)IP地址最近使用的服務(wù)器探遵,若該服務(wù)器 是可用的且沒有超載窟赏,將請求發(fā)送到該服務(wù)器;若服務(wù)器不存在箱季,或者該服務(wù)器超載且有服務(wù)器處于一半的工作負(fù)載涯穷,則用"最少鏈接"的原則選出一個可用的服務(wù) 器,將請求發(fā)送到該服務(wù)器藏雏。

帶復(fù)制的基于局部性最少鏈接lblcr(Locality-Based Least Connections with Replication)
"帶復(fù)制的基于局部性最少鏈接"調(diào)度算法也是針對目標(biāo)IP地址的負(fù)載均衡拷况,目前主要用于Cache集群系統(tǒng)。它與LBLC算法的不同之處是它要維護(hù)從一個 目標(biāo)IP地址到一組服務(wù)器的映射诉稍,而LBLC算法維護(hù)從一個目標(biāo)IP地址到一臺服務(wù)器的映射蝠嘉。該算法根據(jù)請求的目標(biāo)IP地址找出該目標(biāo)IP地址對應(yīng)的服務(wù) 器組,按"最小連接"原則從服務(wù)器組中選出一臺服務(wù)器杯巨,若服務(wù)器沒有超載,將請求發(fā)送到該服務(wù)器努酸,若服務(wù)器超載服爷;則按"最小連接"原則從這個集群中選出一 臺服務(wù)器,將該服務(wù)器加入到服務(wù)器組中,將請求發(fā)送到該服務(wù)器仍源。同時心褐,當(dāng)該服務(wù)器組有一段時間沒有被修改,將最忙的服務(wù)器從服務(wù)器組中刪除笼踩,以降低復(fù)制的 程度逗爹。

目標(biāo)地址散列dh(Destination Hashing)
"目標(biāo)地址散列"調(diào)度算法根據(jù)請求的目標(biāo)IP地址,作為散列鍵(Hash Key)從靜態(tài)分配的散列表找出對應(yīng)的服務(wù)器嚎于,若該服務(wù)器是可用的且未超載掘而,將請求發(fā)送到該服務(wù)器,否則返回空于购。

源地址散列sh(Source Hashing)
"源地址散列"調(diào)度算法根據(jù)請求的源IP地址袍睡,作為散列鍵(Hash Key)從靜態(tài)分配的散列表找出對應(yīng)的服務(wù)器,若該服務(wù)器是可用的且未超載肋僧,將請求發(fā)送到該服務(wù)器斑胜,否則返回空。

keepalived

Keepalived 是運行在lvs之上嫌吠,是一個用于做雙機(jī)熱備(HA)的軟件止潘,它的主要功能是實現(xiàn)真實機(jī)的故障隔離及負(fù)載均衡器間的失敗切換,提高系統(tǒng)的可用性辫诅。

運行原理

keepalived通過選舉(看服務(wù)器設(shè)置的權(quán)重)挑選出一臺熱備服務(wù)器做MASTER機(jī)器凭戴,MASTER機(jī)器會被分配到一個指定的虛擬ip,外部程序可通過該ip訪問這臺服務(wù)器泥栖,如果這臺服務(wù)器出現(xiàn)故障(斷網(wǎng)簇宽,重啟,或者本機(jī)器上的keepalived crash等)吧享,keepalived會從其他的備份機(jī)器上重選(還是看服務(wù)器設(shè)置的權(quán)重)一臺機(jī)器做MASTER并分配同樣的虛擬IP魏割,充當(dāng)前一臺MASTER的角色。

選舉策略

選舉策略是根據(jù)VRRP協(xié)議钢颂,完全按照權(quán)重大小护蝶,權(quán)重最大(0~255)的是MASTER機(jī)器,下面幾種情況會觸發(fā)選舉

  1. keepalived啟動的時候
  2. master服務(wù)器出現(xiàn)故障(斷網(wǎng)缔逛,重啟数冬,或者本機(jī)器上的keepalived crash等,而本機(jī)器上其他應(yīng)用程序crash不算)
  3. 有新的備份服務(wù)器加入且權(quán)重最大

keepalived的配置文件說明

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

  • keepalived 是lvs的擴(kuò)展項目,因此它們之間具備良好的兼容性
  • 對RealServer的健康檢查,實現(xiàn)對失效機(jī)器/服務(wù)的故障隔離
  • 負(fù)載均衡器之間的失敗切換 failover

全局定義

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

  1. 全局定義(global definition)
  2. 靜態(tài)路由配置(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在發(fā)生諸如切換操作時需要發(fā)送email通知以及email發(fā)送給哪些郵件地址郵件地址可以多個每行一個
notification_email_from admin@example.com: 表示發(fā)送通知郵件時郵件源地址是誰
smtp_server 127.0.0.1: 表示發(fā)送email時使用的smtp服務(wù)器地址這里可以用本地的sendmail來實現(xiàn)
smtp_connect_timeout 30: 連接smtp連接超時時間
router_id node1: 機(jī)器標(biāo)識操灿,通常配置主機(jī)名

# 靜態(tài)地址和路由配置范例
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
}
這里實際上和系統(tǒng)里面命令配置IP地址和路由一樣例如
192.168.1.1/24 brd + dev eth0 scope global 相當(dāng)于: ip addr add 192.168.1.1/24 brd + dev eth0 scope global
就是給eth0配置IP地址路由同理,一般這個區(qū)域不需要配置
這里實際上就是給服務(wù)器配置真實的IP地址和路由的在復(fù)雜的環(huán)境下可能需要配置一般不會用這個來配置我們可以直接用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 //表示當(dāng)切換到master狀態(tài)時要執(zhí)行的腳本
notify_backup /path_to/to_backup.sh //表示當(dāng)切換到backup狀態(tài)時要執(zhí)行的腳本
notify_fault "/path/fault.sh VG_1"  // keepalived出現(xiàn)故障時執(zhí)行的腳本
notify /path/to/notify.sh  
smtp_alert           //表示切換時給global defs中定義的郵件地址發(fā)送郵件通知

# 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)的初始狀態(tài)就是說在配置好后這臺 服務(wù)器的初始狀態(tài)就是這里指定的但這里指定的不算還是得要通過競選通過優(yōu)先級來確定里如果這里設(shè)置為master但如若他的優(yōu)先級不及另外一臺 那么這臺在發(fā)送通告時會發(fā)送自己的優(yōu)先級另外一臺發(fā)現(xiàn)優(yōu)先級不如自己的高那么他會就回?fù)屨紴閙aster

interface: 實例綁定的網(wǎng)卡因為在配置虛擬VIP的時候必須是在已有的網(wǎng)卡上添加的

dont track primary: 忽略VRRP的interface錯誤

track interface: 跟蹤接口設(shè)置額外的監(jiān)控里面任意一塊網(wǎng)卡出現(xiàn)問題都會進(jìn)入故障(FAULT)狀態(tài)例如用nginx做均衡器的時候內(nèi)網(wǎng)必須正常工作如果內(nèi)網(wǎng)出問題了這個均衡器也就無法運作了所以必須對內(nèi)外網(wǎng)同時做健康檢查

mcast src ip: 發(fā)送多播數(shù)據(jù)包時的源IP地址這里注意了這里實際上就是在那個地址上發(fā)送VRRP通告這個非常重要一定要選擇穩(wěn)定的網(wǎng)卡端口來發(fā)送這里相當(dāng)于heartbeat的心跳端口如果沒有設(shè)置那么就用默認(rèn)的綁定的網(wǎng)卡的IP也就是interface指定的IP地址

garp master delay: 在切換到master狀態(tài)后延遲進(jìn)行免費的ARP(gratuitous ARP)請求锯仪,默認(rèn)5s

virtual router id: 這里設(shè)置VRID這里非常重要相同的VRID為一個組他將決定多播的MAC地址

priority 100: 設(shè)置本節(jié)點的優(yōu)先級優(yōu)先級高的為master

advert int: 設(shè)置MASTER與BACKUP負(fù)載均衡之間同步即主備間通告時間檢查的時間間隔,單位為秒,默認(rèn)1s

virtual ipaddress: 這里設(shè)置的就是VIP也就是虛擬IP地址他隨著state的變化而增加刪除當(dāng)state為master的時候就添加當(dāng)state為backup的時候刪除這里主要是有優(yōu)先級來決定的和state設(shè)置的值沒有多大關(guān)系這里可以設(shè)置多個IP地址

virtual routes: 原理和virtual ipaddress一樣只不過這里是增加和刪除路由

lvs sync daemon interface: lvs syncd綁定的網(wǎng)卡趾盐,類似HA中的心跳檢測綁定的網(wǎng)卡

authentication: 這里設(shè)置認(rèn)證

auth type: 認(rèn)證方式可以是PASS或AH兩種認(rèn)證方式

auth pass: 認(rèn)證密碼

nopreempt: 設(shè)置不搶占master庶喜,這里只能設(shè)置在state為backup的節(jié)點上而且這個節(jié)點的優(yōu)先級必須別另外的高小腊,比如master因為異常將調(diào)度圈交給了備份serve,master serve檢修后沒問題久窟,如果不設(shè)置nopreempt就會將調(diào)度權(quán)重新奪回來秩冈,這樣就容易造成業(yè)務(wù)中斷問題

preempt delay: 搶占延遲多少秒,即延遲多少秒后競選master

debug:debug級別

notify master:和sync group這里設(shè)置的含義一樣可以單獨設(shè)置例如不同的實例通知不同的管理人員http實例發(fā)給網(wǎng)站管理員mysql的就發(fā)郵件給DBA

# VRRP腳本
# 如下所示為相關(guān)配置示例
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區(qū)域定義腳本名字和腳本執(zhí)行的間隔和腳本執(zhí)行的優(yōu)先級變更,如下所示:
vrrp_script check_running {
            script "/usr/local/bin/check_running"
            interval 10     #腳本執(zhí)行間隔
            weight 10       #腳本結(jié)果導(dǎo)致的優(yōu)先級變更10表示優(yōu)先級+10-10則表示優(yōu)先級-10
            }
# 然后在實例(vrrp_instance)里面引用有點類似腳本里面的函數(shù)引用一樣先定義后引用函數(shù)名
track_script {
      check_running 
}

注意:
VRRP腳本(vrrp_script)和VRRP實例(vrrp_instance)屬于同一個級別
keepalived會定時執(zhí)行腳本并對腳本執(zhí)行的結(jié)果進(jìn)行分析斥扛,動態(tài)調(diào)整vrrp_instance的優(yōu)先級入问。一般腳本檢測返回的值為0,說明腳本檢測成功稀颁,如果為非0數(shù)值芬失,則說明檢測失敗
如果腳本執(zhí)行結(jié)果為0,并且weight配置的值大于0峻村,則優(yōu)先級相應(yīng)的增加, 如果weight為非0麸折,則優(yōu)先級不變
如果腳本執(zhí)行結(jié)果非0,并且weight配置的值小于0粘昨,則優(yōu)先級相應(yīng)的減少, 如果weight為0垢啼,則優(yōu)先級不變
其他情況,維持原本配置的優(yōu)先級张肾,即配置文件中priority對應(yīng)的值芭析。
這里需要注意的是:
1) 優(yōu)先級不會不斷的提高或者降低
2) 可以編寫多個檢測腳本并為每個檢測腳本設(shè)置不同的weight
3) 不管提高優(yōu)先級還是降低優(yōu)先級,最終優(yōu)先級的范圍是在[1,254]吞瞪,不會出現(xiàn)優(yōu)先級小于等于0或者優(yōu)先級大于等于255的情況
這樣可以做到利用腳本檢測業(yè)務(wù)進(jìn)程的狀態(tài)馁启,并動態(tài)調(diào)整優(yōu)先級從而實現(xiàn)主備切換。

virtual_server 虛擬主機(jī)配置

關(guān)于keeplived的虛擬主機(jī)配置有三種如下所示
virtual server IP port
virtual server fwmark int
virtual server group string

以常用的第一種為例
virtual_server 192.168.1.2 80
含義:設(shè)置一個virtual server: VIP:Vport

delay_loop 3
含義:設(shè)置service polling的delay時間即服務(wù)輪詢的時間間隔

lb_algo rr|wrr|lc|wlc|lblc|sh|dh
含義:設(shè)置LVS調(diào)度算法

lb_kind NAT|DR|TUN
含義:設(shè)置LVS集群模式

persistence_timeout 120
含義:設(shè)置會話保持時間秒為單位即以用戶在120秒內(nèi)被分配到同一個后端realserver,超過此時間就重新分配

persistence_granularity <NETMASK>
含義:設(shè)置LVS會話保持粒度ipvsadm中的-M參數(shù)默認(rèn)是0xffffffff即每個客戶端都做會話保持

protocol TCP
含義:設(shè)置健康檢查用的是TCP還是UDP

ha_suspend
含義:suspendhealthchecker’s activity

virtualhost <string>
含義:HTTP_GET做健康檢查時檢查的web服務(wù)器的虛擬主機(jī)即host頭

sorry_server <IPADDR> <PORT>
含義:設(shè)置backupserver就是當(dāng)所有后端realserver節(jié)點都不可用時就用這里設(shè)置的也就是臨時把所有的請求都發(fā)送到這里

real_server <IPADDR> <PORT>
含義:設(shè)置后端真實節(jié)點主機(jī)的權(quán)重等設(shè)置主要后端有幾臺這里就要設(shè)置幾個

weight 1
含義:設(shè)置給每臺的權(quán)重0表示失效(不知給他轉(zhuǎn)發(fā)請求知道他恢復(fù)正常)默認(rèn)是1

inhibit_on_failure
含義:表示在節(jié)點失敗后把他權(quán)重設(shè)置成0而不是沖IPVS中刪除

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

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

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

url {                   #設(shè)置要檢查的URL可以有多個
path /                  #設(shè)置URL具體路徑
digest <STRING>         #檢查后的摘要信息這些摘要信息可以通過genhash命令工具獲取                                   
status_code 200         #設(shè)置返回狀態(tài)碼
}
connect_port 80         #設(shè)置監(jiān)控檢查的端口
bindto  <IPADD>         #設(shè)置健康檢查的IP地址
connect_timeout   3     #設(shè)置連接超時時間
nb_get_retry  3         #設(shè)置重連次數(shù)
delay_before_retry  2   #設(shè)置重連間隔
} 

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

#MISC方式 這個可以用來檢查很多服務(wù)器只需要自己會些腳本即可
MISC_CHECK {
misc_path <STRING>|<QUOTED-STRING>  #外部程序或腳本
misc_timeout <INT>                  #腳本或程序執(zhí)行超時時間
misc_dynamic                                              
#這個就很好用了可以非常精確的來調(diào)整權(quán)重是后端每天服務(wù)器的壓力都能均衡調(diào)配這個主要是通過執(zhí)行的程序或腳本返回的狀態(tài)代碼來動態(tài)調(diào)整weight值使權(quán)重根據(jù)真實的后端壓力來適當(dāng)調(diào)整不過這需要有過硬的腳本功夫才行哦
#返回0健康檢查沒問題不修改權(quán)重
#返回1健康檢查失敗權(quán)重設(shè)置為0
#返回2-255健康檢查沒問題但是權(quán)重卻要根據(jù)返回代碼修改為返回碼-2例如如果程序或腳本執(zhí)行后返回的代碼為200#那么權(quán)重這回被修改為 200-2
}

以上就是keepalived的配置項說明雖然配置項很多但很多時候很多配置項保持默認(rèn)即可芍秆,以下是默認(rèn)配置文件惯疙,方便大家做個對比參考

[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文件內(nèi)容為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服務(wù)
/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 

# 請求分配結(jié)果
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 

參數(shù)含義 
--stats 顯示統(tǒng)計信息 
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes 
                       連接數(shù) 輸入包 輸出包 輸入流量 輸出流量 

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

lvs+keepalived配置實踐

防火墻的配置不在本文的范圍妖啥,請關(guān)閉selinux和firewall

# 關(guān)閉防火墻
systemctl disable firewalld
systemctl stop firewalld

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

SELINUX=disabled

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

# 開啟LVS服務(wù)器的IP路由轉(zhuǎn)發(fā)功能
echo "1" > /proc/sys/net/ipv4/ip_forward
# 添加路由轉(zhuǎn)發(fā)至sysctl.conf
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1

sysctl -p

最簡單的keepalived做HA

# 如果開啟防火墻霉颠,請?zhí)砑覸RRP白名單
# 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

修改默認(rèn)網(wǎng)關(guān)指向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模塊后就會有默認(rèn)的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

# 手動關(guān)閉ARP轉(zhuǎn)發(fā)
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協(xié)議
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 禁言荆虱,在相對較新的版本中新增了兩個內(nèi)核參數(shù) (kernel parameter)

  • 第一個是 arp_ignore 定義接受到 ARP 請求時的相應(yīng)級別
  • 第二個是 arp_announce 定義將自己地址向外通告是的通告級別
  • 第三個是 rp_filter 定義系統(tǒng)是否開啟對數(shù)據(jù)包源地址的校驗

總結(jié): LVS/TUN 是所有模式中最最適用于跨網(wǎng)絡(luò)跨地域地理位置的一種模式蒿偎,需要注意的是:

  1. 若 DIR 和 RIP 在不同 lan 網(wǎng)絡(luò)中,比如不同的網(wǎng)段怀读,不同的 IDC 機(jī)房诉位,就不需要設(shè)置 arp 仰制,不同網(wǎng)段中菜枷,arp 會被屏蔽掉苍糠,所以只需設(shè)置 ip tunne 以及報文反向驗證即可;
  2. 若 DIR 和 RIP 在同一廣播域中啤誊,需要和 LVS/DR 模式一樣在所有的 RIP 上仰制 arp椿息,防止 arp 響應(yīng)導(dǎo)致 arp 表混亂歹袁,這樣 lvs 就不能正常工作坷衍!

配置時除了配置 DIR寝优,還需要需要配置后端 RS server,即在 tunl 上口配置 vip 地址(需要系統(tǒng)支持 tunl 才行)枫耳,廣播為為自己乏矾,此模式下無需開啟路由轉(zhuǎn)發(fā)功能!

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

DS

# 關(guān)于3中模式的參數(shù)
[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
        }
    }
}

# 檢查結(jié)果可用
[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 部署之細(xì)枝末節(jié)

原作者寫得很詳細(xì)迁杨,我這邊做下引用在此表示感謝钻心,LVS 部署之細(xì)枝末節(jié)

簡介

本文總結(jié)了在 LVS 部署過程中需要注意的一些小細(xì)節(jié)。這些內(nèi)容比較雜铅协,并且沒有規(guī)律和內(nèi)在聯(lián)系捷沸;它們分散在 LVS 部署過程中的各個小環(huán)節(jié)中,不是系統(tǒng)性的知識狐史,也沒有主線對它們進(jìn)行連接痒给。你可以通過此文對他們進(jìn)行一個大概的了解,在實踐過程中如果遇到可以再過來進(jìn)行詳細(xì)的查閱骏全,以解決實際問題苍柏。

開啟 Linux 的路由轉(zhuǎn)發(fā)功能

LVS 在 VS/NAT 方式下需要開啟數(shù)據(jù)包轉(zhuǎn)發(fā) (ip_forward) 功能。因為在 LVS 的 VS/NAT 模式下姜贡,對 IP 數(shù)據(jù)進(jìn)行負(fù)載均衡時试吁,需要把多臺真實服務(wù)器節(jié)點中的專網(wǎng) IP 映射到同一個虛擬服務(wù)器的公網(wǎng) IP 上;這就需要通過 NAT 技術(shù)對 IP 數(shù)據(jù)包進(jìn)行轉(zhuǎn)發(fā)楼咳,從而將 IP 數(shù)據(jù)包發(fā)送到真實服務(wù)器上進(jìn)行處理熄捍。LVS 在 VS/DR 模式下,因為 director 的 DIP 與真實服務(wù)器節(jié)點的 RIP 在同一網(wǎng)段母怜,所以不需要開啟路由轉(zhuǎn)發(fā)功能余耽。LVS 在 VS/TUN 模式下,IP 數(shù)據(jù)包是通過 IP 隧道技術(shù)進(jìn)行封包后再分發(fā)的方式到達(dá)真實服務(wù)器節(jié)點的糙申,也不需要開啟路由轉(zhuǎn)發(fā)功能宾添。

開啟 Linux 的路由轉(zhuǎn)發(fā)功能的方法很多,具體細(xì)節(jié)請參閱文章 Linux ip_forward 數(shù)據(jù)包轉(zhuǎn)發(fā)柜裸。

配置真實服務(wù)器的 ARP 請求與響應(yīng)策略

在 ARP 協(xié)議中缕陕,為了減少 arp 請求的次數(shù),當(dāng)主機(jī)接收到詢問自己的 arp 請求的時候疙挺,就會把源 ip 和源 Mac 放入自 己的 arp 表里面扛邑,方便接下來的通訊。如果收到不是詢問自己的包(arp 是廣播的铐然,所有人都收到)蔬崩,就會丟掉恶座,這樣不會造成 arp 表里面無用數(shù)據(jù)太多導(dǎo)致 有用的記錄被刪除。

在 LVS 的 VS/DR 模式下沥阳,當(dāng)內(nèi)網(wǎng)的真實服務(wù)器(Linux 主機(jī))要發(fā)送一個到外部網(wǎng)絡(luò)的 ip 包(LVS 負(fù)載器分配置過來的作業(yè)的處理結(jié)果)跨琳,那么它就會請求路由器的 Mac 地址,發(fā)送一個 arp 請求桐罕,這個 arp 請求里面包括了自己的 ip 地址和 Mac 地址脉让。而 linux 主機(jī)默認(rèn)是使用 ip 數(shù)據(jù)包的源 ip 地址作為 arp 里面的源 ip 地址,而不是使用發(fā)送設(shè)備上面網(wǎng)絡(luò)接口卡的 ip 地址功炮。這樣在 LVS 的 VS/DR 架構(gòu)下溅潜,所有真實服務(wù)器在響應(yīng)外部請求時的 IP 數(shù)據(jù)包的源地址都是同一個 VIP 地址,那么 arp 請求就會包括 VIP 地址和設(shè)備 Mac薪伏。而路由器收到這個 arp 請求就會更新自己的 arp 緩存滚澜,這樣就會造成 ip 欺騙了,VIP 被搶奪嫁怀,所以就會有問題设捐。

所以當(dāng) LVS 運行在 VS/DR 模式下時,需要在所有真實服務(wù)器上修改 ARP 請求與響應(yīng)策略眶掌,以保證以上問題不會發(fā)生挡育。

因為在 lo(本地環(huán)回網(wǎng)絡(luò)接口)上配置了 VIP,所以需要對真實服務(wù)器中的 ARP 請求與響應(yīng)策略配置如下:

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 文件中朴爬,然后執(zhí)行 sysctl -p 指令就可以即寒。以上配置的具體含義請參閱 Linux 內(nèi)核參數(shù) arp_ignore & arp_announce 詳解

在 VS/DR 模式下 VIP 召噩、DIP 和 RIP 必須在同一網(wǎng)段嗎母赵?

在 VS/DR 模式下 VIP 、DIP 和 RIP 不需要在同一網(wǎng)段具滴!

其中 VIP 必須是公網(wǎng) IP凹嘲;而 DIP 和 RIP 必須在同一網(wǎng)段(可以是任意網(wǎng)段的 IP,也可以是私網(wǎng) IP)构韵,且需要節(jié)點主機(jī)的 RIP 可以把 IP 數(shù)據(jù)包發(fā)送到一個能把 IP 數(shù)據(jù)包路由到公網(wǎng)的路由器上周蹭。

其實 LVS 在 VS/DR 模式下的要求是 DIP 和 RIP 必須處于同一網(wǎng)段中。在實際的部署過程中發(fā)現(xiàn)如果在 Director 上 VIP 和 DIP 在同一網(wǎng)段疲恢、或在 RealServer 上 VIP 與 RIP 在同一網(wǎng)段凶朗,LVS 集群工作會很不穩(wěn)定。因為當(dāng)一個 IP 數(shù)據(jù)包需要發(fā)到默認(rèn)網(wǎng)關(guān)時(在 RealServer 或 Director 上)显拳,Linux 主機(jī)不知道應(yīng)該使用哪個接口(在同一子網(wǎng)中的 VIP 和 DIP/RIP)棚愤,他可能會隨機(jī)選一個,但這個不一定能成功。我感覺可以通過在 Linux 中配置路由表來解決宛畦,但沒有驗證(哪位同學(xué)如果有興趣可以實踐驗證一下瘸洛,如果能把驗證結(jié)果反饋給我那是再好不過了)。

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

在 Linux 中用于對 網(wǎng)卡的反向路由過濾策略進(jìn)行配置的內(nèi)核參數(shù)是 rp_filter次和,有關(guān)此參數(shù)的詳細(xì)介紹以及配置方式請參見 Linux 內(nèi)核參數(shù) rp_filter反肋。

LVS 在 VS/TUN 模式下,需要對 tunl0 虛擬網(wǎng)卡的反向路由過濾策略進(jìn)行配置斯够。最直接的辦法是把其值設(shè)置為 0囚玫。

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

因為 Linux 系統(tǒng)在對網(wǎng)卡應(yīng)用反向路由過濾策略時,除了檢查本網(wǎng)卡的 rp_filter 參數(shù)外读规,還會檢查 all 配置項上的 rp_filter 參數(shù),并使用這兩個值中較大的值作為應(yīng)用到當(dāng)前網(wǎng)卡的反向路由過濾策略燃少。所以需要同時把 net.ipv4.conf.all.rp_filter 參數(shù)設(shè)置為 0束亏。

配置 tunl0 網(wǎng)卡

LVS 在 VS/TUN 模式下,需要在每個真實服務(wù)器上開啟 tunl0 網(wǎng)卡阵具,并把 VIP 配置到 tunl0 網(wǎng)卡上碍遍。有關(guān) tunl0 網(wǎng)卡的說明可以參考一下 Linux 中 IP 隧道模塊淺析

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

LVS 在 VS/TUN 模式下 因為 Director 主機(jī)需要通過 ipip 協(xié)議向 RealServer 分發(fā)數(shù)據(jù)包阳液;所以需要在 RealServer 上配置防火墻怕敬,允許 ipip 協(xié)議的數(shù)據(jù)包通過。

iptables -I INPUT 1 -p 4 -j ACCEPT

常見問題

配置日志

此配置為可選步驟

keepalived 默認(rèn)將日志輸出到系統(tǒng)日志/var/log/messages中帘皿,因為系統(tǒng)日志很多东跪,查詢問題時相對麻煩。

我們可以將 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

# 重啟日志記錄服務(wù)
systemctl restart rsyslog

# 重啟 keepalived
systemctl restart keepalived

# 此時可以從 /var/log/keepalived.log 查看日志了
tailf /var/log/keepalived.log

ARP導(dǎo)致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原理介紹和配置實踐

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末曹动,一起剝皮案震驚了整個濱河市斋日,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌墓陈,老刑警劉巖恶守,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贡必,居然都是意外死亡兔港,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門赊级,熙熙樓的掌柜王于貴愁眉苦臉地迎上來押框,“玉大人,你說我怎么就攤上這事理逊∠鹕。” “怎么了盒揉?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長兑徘。 經(jīng)常有香客問我刚盈,道長,這世上最難降的妖魔是什么挂脑? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任藕漱,我火速辦了婚禮,結(jié)果婚禮上崭闲,老公的妹妹穿的比我還像新娘肋联。我一直安慰自己,他們只是感情好刁俭,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布橄仍。 她就那樣靜靜地躺著,像睡著了一般牍戚。 火紅的嫁衣襯著肌膚如雪侮繁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天如孝,我揣著相機(jī)與錄音宪哩,去河邊找鬼。 笑死第晰,一個胖子當(dāng)著我的面吹牛锁孟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播但荤,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼罗岖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腹躁?” 一聲冷哼從身側(cè)響起桑包,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纺非,沒想到半個月后哑了,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡烧颖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年弱左,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炕淮。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡拆火,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情们镜,我是刑警寧澤币叹,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站模狭,受9級特大地震影響颈抚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嚼鹉,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一贩汉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锚赤,春花似錦匹舞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至酒贬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翠霍,已是汗流浹背锭吨。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留寒匙,地道東北人零如。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像锄弱,于是被迫代替她去往敵國和親考蕾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容