LVS
本文來自http://467754239.blog.51cto.com/4878013/1549699的Lvs之NAT、DR、TUN三種模式的應用配置案例
一、LVS簡介
LVS是Linux Virtual Server的簡寫,意即Linux虛擬服務器,是一個虛擬服務器集羣系統。本項目在1998年5月由章文嵩博士成立,是中國國內最早出現的自由軟件之一。
二、LVS的分類
LVS-NAT:地址轉換
LVS-DR: 直接路由
LVS-TUN:隧道
三、ipvsadm用法
其 實LVS的本身跟iptables很相似,而且連命令的使用格式都很相似,其實LVS是根據iptables的框架開發的,那麼LVS的本身分成了兩個部 分,第一部分是工作在內核空間的一個IPVS的模塊,其實LVS的功能都是IPVS模塊實現的,,第二部分是工作在用戶空間的一個用來定義集羣服務的一個 工具ipvsadm, 這個工具的主要作用是將管理員定義的集羣服務列表傳送給工作在內核空間中的IPVS模塊,下面來簡單的介紹下ipvsadm命令的用法
ipvsadm組件定義規則的格式: 1.定義集羣服務格式: (1).添加集羣服務: ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] -A: 表示添加一個新的集羣服務 -E: 編輯一個集羣服務 -t: 表示tcp協議 -u: 表示udp協議 -f: 表示firewall-Mark,防火牆標記 service-address: 集羣服務的IP地址,即VIP -s 指定調度算法 -p 持久連接時長,如#ipvsadm -Lcn ,查看持久連接狀態 -M 定義掩碼 ipvsadm -D -t|u|f service-address 刪除一個集羣服務 ipvsadm -C 清空所有的規則 ipvsadm -R 重新載入規則 ipvsadm -S [-n] 保存規則 2.向集羣服務添加RealServer規則: (1).添加RealServer規則 ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight] -a 添加一個新的realserver規則 -e 編輯realserver規則 -t tcp協議 -u udp協議 -f firewall-Mark,防火牆標記 service-address realserver的IP地址 -g 表示定義爲LVS-DR模型 -i 表示定義爲LVS-TUN模型 -m 表示定義爲LVS-NAT模型 -w 定義權重,後面跟具體的權值 ipvsadm -d -t|u|f service-address -r server-address --刪除一個realserver ipvsadm -L|l [options] --查看定義的規則 如:#ipvsadm -L -n ipvsadm -Z [-t|u|f service-address] --清空計數器 清空和查看: ipvsadm -C ipvsadm -L|l [options] -n: numeric,基於數字格式顯示地址和端口; -c: connection,顯示ipvs連接; --stats:統計數據 --rate: 速率 --exact: 精確值
四、lvs的10種調度算法
可以分爲兩大類
LVS Scheduling Method LVS的調度方法: 1.Fixed Scheduling Method 靜態調服方法 (1).RR 輪詢 (2).WRR 加權輪詢 (3).DH 目標地址hash (4).SH 源地址hash 2.Dynamic Scheduling Method 動態調服方法 (1).LC 最少連接 (2).WLC 加權最少連接 (3).SED 最少期望延遲 (4).NQ 從不排隊調度方法 (5).LBLC 基於本地的最少連接 (6).LBLCR 帶複製的基於本地的最少連接
LVS-NAT
一、架構平臺環境
系統平臺:CentOS 6.4 64bit 內核:2.6.32 相關服務和專有名詞定義 Director:負責調度集羣的主機;也簡稱調度器、分發器 VIP:Virtual IP 向外提供服務的IP;通常此IP綁定域名 DIP:與內部主機RIP通信的IP,在Director主機上 RIP:RealServer IP;內部真正提供服務的主機 CIP:客戶端IP
二、LVS-NAT架構
三、LVS-NAT模型實現負載均衡的工作方式
NAT
模型其實就是通過網絡地址轉換來實現負載均衡的,它的工作方式幾乎跟DNAT一模一樣的,目前的DNAT只能轉發到一個目標地址,早期的DNAT是可以將
請求轉發到多個目標的,在LVS出現之後就將此功能從DNAT中去掉了,下面來說說NAT模型的工作方式或者說NAT模型是怎麼實現負載均衡的,根據上
圖,
1.用戶請求VIP(也可以說是CIP請求VIP)
2,Director Server
收到用戶的請求後,發現源地址爲CIP請求的目標地址爲VIP,那麼Director
Server會認爲用戶請求的是一個集羣服務,那麼Director Server 會根據此前設定好的調度算法將用戶請求負載給某臺Real
Server ;假如說此時Director Server 根據調度算法的結果會將請求分攤到RealServer1上去,那麼Director
Server 會將用戶的請求報文中的目標地址,從原來的VIP改爲RealServer1的IP,然後再轉發給RealServer1
3,此時RealServer1收到一個源地址爲CIP目標地址爲自己的請求,那麼RealServer1處理好請求後會將一個源地址爲自己的rip目標地址爲CIP的數據包通過Director Server 發出去,
4.當Driector Server收到一個源地址爲RealServer1 的IP 目標地址爲CIP的數據包,此時Driector Server 會將源地址修改爲VIP,然後再將數據包發送給用戶,
四、LVS-NAT的性能瓶頸
在 LVS/NAT的集羣系統中,請求和響應的數據報文都需要通過負載調度器(Director),當真實服務器(RealServer)的數目在10臺和 20臺之間時,負載調度器(Director)將成爲整個集羣系統的新瓶頸。大多數Internet服務都有這樣的特點:請求報文較短而響應報文往往包含 大量的數據。如果能將請求和響應分開處理,即在負載調度器(Director)中只負責調度請求而響應直接(RealServer)返回給客戶,將極大地 提高整個集羣系統的吞吐量。
五、部署環境
1、準備工作
(1)關閉所有節點的iptables和selinux服務 setenforce 0 service iptables stop && chkconfig iptables off (2)HA中所有節點儘可能保證時間是一致的,方法是時間同步+任務計劃同步時間; 注意:對於LB來說時間的影響不是很大,但是對於HP來說各節點之間的時間偏差不應該超出一秒鐘: ntpdate -u asia.pool.ntp.org
2、拓撲圖地址規劃
LVS Director機器:
公網地址:vip
主機名:lvs
vip地址: 192.168.0.200
子網掩碼:255.255.255.0
網關: 192.168.0.1
網絡連接方式:Bridge
LVS Director機器: 公網地址:vip 主機名:lvs vip地址: 192.168.0.200 子網掩碼:255.255.255.0 網關: 192.168.0.1 網絡連接方式:Bridge 私網地址:dip 主機名:lvs dip地址: 172.16.100.1 子網掩碼:255.255.0.0 網關: 不指定網關 網絡連接方式:Host-Only RealServer機器: 私網地址:rip1 主機名:web1 rip1地址:172.16.100.10 子網掩碼:255.255.0.0 網關: 172.16.100.1 網絡連接方式:Host-Only 私網地址:rip2 主機名:web2 rip1地址:172.16.100.11 子網掩碼:255.255.0.0 網關: 172.16.100.1 網絡連接方式:Host-Only
3、在RealServer上部署httpd服務並測試
安裝httpd服務,創建httpd測試頁面,啓動httpd服務 [root@web1 ~]# yum -y install httpd [root@web1 ~]# service httpd start [root@web1 ~]# echo "RS1-web1 Allentuns.com" > /var/www/html/index.html [root@web2 ~]# yum -y install httpd [root@web2 ~]# echo "RS2-web2 Allentuns.com" > /var/www/html/index.html [root@web2 ~]# service httpd start 測試httpd服務是否OK! [root@web1 ~]# curl http://localhost RS1-web1 Allentuns.com [root@web1 ~]# curl http://172.16.100.11 RS2-web2 Allentuns.com
4、在Director上部署ipvs服務並測試
(1)確定本機ip_vs模塊是否加載,也就是是否支持lvs,2.4.2後都支持了;然後安裝ipvsadm 用戶操作命令 [root@LVS ~]# grep -i "ip_vs" /boot/config-2.6.32-358.el6.x86_64 CONFIG_IP_VS=m #將ipvs定義成模塊 CONFIG_IP_VS_IPV6=y # CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12 CONFIG_IP_VS_PROTO_TCP=y #IPVS支持哪些集羣服務 CONFIG_IP_VS_PROTO_UDP=y CONFIG_IP_VS_PROTO_AH_ESP=y CONFIG_IP_VS_PROTO_ESP=y CONFIG_IP_VS_PROTO_AH=y CONFIG_IP_VS_PROTO_SCTP=y CONFIG_IP_VS_RR=m #ipvs支持的十種調度算法 CONFIG_IP_VS_WRR=m CONFIG_IP_VS_LC=m CONFIG_IP_VS_WLC=m CONFIG_IP_VS_LBLC=m CONFIG_IP_VS_LBLCR=m CONFIG_IP_VS_DH=m CONFIG_IP_VS_SH=m CONFIG_IP_VS_SED=m CONFIG_IP_VS_NQ=m CONFIG_IP_VS_FTP=m #支持代理ftp協議的 (2)安裝ipvsadm [root@LVS ~]# yum -y install ipvsadm (3)添加集羣服務 [root@LVS ~]# ipvsadm -A -t 192.168.0.200:80 -s rr #定義一個集羣服務 [root@LVS ~]# ipvsadm -a -t 192.168.0.200:80 -r 172.16.100.10 -m #添加RealServer並指派調度算法爲NAT [root@LVS ~]# ipvsadm -a -t 192.168.0.200:80 -r 172.16.100.11 -m #添加RealServer並指派調度算法爲NAT [root@LVS ~]# ipvsadm -L -n #查看ipvs定義的規則列表 IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.0.200:80 rr -> 172.16.100.10:80 Masq 1 0 0 -> 172.16.100.11:80 Masq 1 0 0 [root@LVS ~]# cat /proc/sys/net/ipv4/ip_forward #查看Linux是否開啓路由轉發功能 0 [root@LVS ~]# echo 1 > /proc/sys/net/ipv4/ip_forward #啓動Linux的路由轉發功能 [root@LVS ~]# cat /proc/sys/net/ipv4/ip_forward 1 (4)測試訪問http頁面 [root@LVS ~]# curl http://192.168.0.200/index.html RS2-web2 Allentuns.com #第一次是web2 [root@LVS ~]# curl http://192.168.0.200/index.html RS1-web1 Allentuns.com #第二次是web1 [root@LVS ~]# curl http://192.168.0.200/index.html RS2-web2 Allentuns.com #第三次是web1 [root@LVS ~]# curl http://192.168.0.200/index.html RS1-web1 Allentuns.com #第四次是web2 (5)更改LVS的調度算並壓力測試,查看結果 [root@LVS ~]# ipvsadm -E -t 192.168.0.200:80 -s wrr [root@LVS ~]# ipvsadm -e -t 192.168.0.200:80 -r 172.16.100.10 -m -w 3 [root@LVS ~]# ipvsadm -e -t 192.168.0.200:80 -r 172.16.100.11 -m -w 1 [root@LVS ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.0.200:80 wrr -> 172.16.100.10:80 Masq 3 0 2 -> 172.16.100.11:80 Masq 1 0 2 [root@LVS ~]# curl http://192.168.0.200/index.html RS1-web1 Allentuns.com [root@LVS ~]# curl http://192.168.0.200/index.html RS1-web1 Allentuns.com [root@LVS ~]# curl http://192.168.0.200/index.html RS1-web1 Allentuns.com [root@LVS ~]# curl http://192.168.0.200/index.html RS2-web2 Allentuns.com [root@LVS ~]# curl http://192.168.0.200/index.html RS1-web1 Allentuns.com (6)永久保存LVS規則並恢復 第一種方法: [root@LVS ~]# service ipvsadm save ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm: [確定] 第二種方法: [root@LVS ~]# ipvsadm -S > /etc/sysconfig/ipvsadm.s1 模擬清空ipvsadm規則來恢復 [root@LVS ~]# ipvsadm -C [root@LVS ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn [root@LVS ~]# ipvsadm -R < /etc/sysconfig/ipvsadm.s1 [root@LVS ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.0.200:80 wrr -> 172.16.100.10:80 Masq 3 0 0 -> 172.16.100.11:80 Masq 1 0 0
六、LVS-NAT服務控制腳本部署在Director上
#!/bin/bash # # chkconfig: - 88 12 # description: LVS script for VS/NAT # . /etc/rc.d/init.d/functions # VIP=192.168.0.200 DIP=172.16.100.1 RIP1=172.16.100.10 RIP2=172.16.100.11 # case "$1" in start) # /sbin/ifconfig eth1:0 $VIP netmask 255.255.255.0 up # Since this is the Director we must be able to forward packets echo 1 > /proc/sys/net/ipv4/ip_forward # Clear all iptables rules. /sbin/iptables -F # Reset iptables counters. /sbin/iptables -Z # Clear all ipvsadm rules/services. /sbin/ipvsadm -C # Add an IP virtual service for VIP 192.168.0.219 port 80 # In this recipe, we will use the round-robin scheduling method. # In production, however, you should use a weighted, dynamic scheduling method. /sbin/ipvsadm -A -t $VIP:80 -s rr # Now direct packets for this VIP to # the real server IP (RIP) inside the cluster /sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -m /sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -m /bin/touch /var/lock/subsys/ipvsadm.lock ;; stop) # Stop forwarding packets echo 0 > /proc/sys/net/ipv4/ip_forward # Reset ipvsadm /sbin/ipvsadm -C # Bring down the VIP interface ifconfig eth1:0 down rm -rf /var/lock/subsys/ipvsadm.lock ;; status) [ -e /var/lock/subsys/ipvsadm.lock ] && echo "ipvs is running..." || echo "ipvsadm is stopped..." ;; *) echo "Usage: $0 {start|stop}" ;; esac
七、分享LVS-NAT一鍵安裝腳本
#!/bin/bash # # 一鍵安裝lvs-nat腳本,需要注意的是主機名成和ip的變化稍作修改就可以了 HOSTNAME=`hostname` Director='LVS' VIP="192.168.0.200" RIP1="172.16.100.10" RIP2="172.16.100.11" RealServer1="web1" RealServer2="web2" Httpd_config="/etc/httpd/conf/httpd.conf" #Director Server Install configure ipvsadm if [ "$HOSTNAME" = "$Director" ];then ipvsadm -C yum -y remove ipvsadm yum -y install ipvsadm /sbin/ipvsadm -A -t $VIP:80 -s rr /sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -m /sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -m echo 1 > /proc/sys/net/ipv4/ip_forward echo "========================================================" echo "Install $Director sucess Tel:13260071987 Qq:467754239" echo "========================================================" fi #RealServer Install htpd if [ "$HOSTNAME" = "$RealServer1" ];then yum -y remove httpd rm -rf /var/www/html/index.html yum -y install httpd echo "web1 Allentuns.com" > /var/www/html/index.html sed -i '/#ServerName www.example.com:80/a\ServerName localhost:80' $Httpd_config service httpd start echo "========================================================" echo "Install $RealServer1 success Tel:13260071987 Qq:467754239" echo "========================================================" fi if [ "$HOSTNAME" = "$RealServer2" ];then yum -y remove httpd rm -rf /var/www/html/index.html yum -y install httpd echo "web2 Allentuns.com" > /var/www/html/index.html sed -i '/#ServerName www.example.com:80/a\ServerName localhost:80' $Httpd_config service httpd start echo "Install $RealServer2" echo "=========================================================" echo "Install $RealServer1 success Tel:13260071987 Qq:467754239" echo "=========================================================" fi
LVS-DR
一、LVS-DR架構
二、DR模型實現負載均衡的工作方式,
上面說了NAT模型的實現方式,那麼NAT模型有個缺陷,因爲進出的每個數據包都要經過Director
Server,當集羣系統負載過大的時候Director
Server將會成爲整個集羣系統的瓶頸,那麼DR模型就避免了這樣的情況發生,DR模型在只有請求的時候纔會經過Director Server,
迴應的數據包由Real Server 直接響應用戶不需要經過Director
Server,其實三種模型中最常用的也就是DR模型了,下面來說DR模型具體是怎麼實現負載均衡的,根據上圖,
1, 首先用戶用CIP請求VIP,
2,
根據上圖可以看到,不管是Director Server還是Real
Server上都需要配置VIP,那麼當用戶請求到達我們的集羣網絡的前端路由器的時候,請求數據包的源地址爲CIP目標地址爲VIP,此時路由器會發arp廣播問VIP這個地址對應的mac是誰,此時director server回覆了自己的mac後,路由器會在數據包上封裝這個mac發出去到達director server,但是我們集羣中所有的節點都配置有VIP,此時誰先響應路由器那麼路由器就會將用戶請求發給誰,這樣一來我們的集羣系統是不是沒有意義
了,那我們可以在網關路由器上配置靜態路由指定VIP就是Director Server,或者使用一種機制不讓Real Server
接收來自網絡中的ARP地址解析請求,這樣一來用戶的請求數據包都會經過Director Server
3,當Director
Server收到用戶的請求後根據此前設定好的調度算法結果來確定將請求負載到某臺Real
Server上去,假如說此時根據調度算法的結果,會將請求負載到Real Server 1上面去,此時Director Server
會將數據幀中的目標MAC地址修改爲Real Server1的MAC地址,然後再將數據幀發送出去
4,當Real Server1
收到一個源地址爲CIP目標地址爲VIP的數據包時,Real
Server1發現目標地址爲VIP,而VIP是自己,對於每一個real server,rip配置在物理網卡上,vip配置在lo接口的別名上,由lo接口響應給應用程序服務,要求從哪個接口進來的報文必須從哪個接口出去,應用程序構建成響應報文後傳輸給lo接口封裝上vip,然後發還給通信的接口傳回客戶端,當Real
Server1處理完請求後,會將一個源地址爲VIP目標地址爲CIP的數據包發出去,此時的響應請求就不會再經過Director
Server了,而是直接響應給用戶,這裏響應報文源地址是vip,目的地址是cip,vip和rip不在同一網絡時,real server的網關就需要指向另一個與rip在同一網段的路由器接口。
編輯DR有三種方式 第 一種方式:在路由器上明顯說明vip對應的地址一定是Director上的MAC,只要綁定,以後再跟vip通信也不用再請求了,這個綁定是靜態的,所以 它也不會失效,也不會再次發起請求,但是有個前提,我們的路由設備必須有操作權限能夠綁定MAC地址,萬一這個路由器是運行商操作的,我們沒法操作怎麼 辦?第一種方式固然很簡便,但未必可行。 第 二種方式:在給別主機上(例如:紅帽)它們引進的有一種程序arptables,它有點類似於iptables,它肯定是基於arp或基於MAC做訪問控 制的,很顯然我們只需要在每一個real server上定義arptables規則,如果用戶arp廣播請求的目標地址是本機的vip則不予相應,或者 說相應的報文不讓出去,很顯然網關(gateway)是接受不到的,也就是director相應的報文才能到達gateway,這個也行。第二種方式我們 可以基於arptables。 第 三種方式:在相對較新的版本中新增了兩個內核參數(kernelparameter),第一個是arp_ignore定義接受到ARP請求時的相應級別; 第二個是arp_announce定義將自己地址向外通告是的通告級別。【提示:很顯然我們現在的系統一般在內核中都是支持這些參數的,我們用參數的方式 進行調整更具有樸實性,它還不依賴於額外的條件,像arptables,也不依賴外在路由配置的設置,反而通常我們使用的是第三種配置】 arp_ignore:定義接受到ARP請求時的相應級別 0:只要本地配置的有相應地址,就給予響應。 1:從這個接口進來的,並且目標地址是此接口,纔給予響應 2:只回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求,且來訪IP必須在該網絡接口的子網段內 3:不迴應該網絡界面的arp請求,而只對設置的唯一和連接地址做出迴應 4-7:保留未使用 8:不迴應所有(本地地址)的arp查詢 此處因該將arp_ignore設置爲1 arp_announce:定義將自己地址向外通告是的通告級別; 0: 將本地任何接口上的任何地址向外通告 1:僅響應目標網絡通告與其網絡匹配的地址 2:僅向與本地接口上地址匹配的網絡進行通告 此處應該將arp_announce設置爲2
所有的Director和RealServer都在同一個物理網絡中(交換機)並且都只有一塊網卡,交換機前面有個路由器,這個路由器可能是我們機房內部的,也有可能是網絡運行商的。 當客戶端的請求被送到R2和Switch之間的時候,這個時候源ip是cip,目標地址是vip。vip一定在Director上是毋庸置疑的,所以這個報文就背送到Director的vip網卡上。 當客戶端的請求被送到Switch和Director之間的時候,這個時候源ip仍然是cip,目標地址是vip。Director發現當前本機配置的有vip地址,所以請求的一定是當前主機 所以報文經過Prerouting鏈到達Input鏈,而監控在Input鏈上的ipvs規則發現請求的是一個集羣服務,比如監聽在80端口的web集羣服務。這個時候lvs要根據ipvs規則 等等要修改報文了,在LVS-DR模型下報文送到Director上的時候,Director不會拆它的IP首部,也不會拆它的TCP首部,Director只要將MAC地址或者幀首部拆掉了。 爲什麼Director要拆開幀首部MAC地址呢?因爲報文的目的地址就是Director本地主機,只要到達目的主機,網卡就會拆開幀首部的。因爲目標MAC就是本地主機。 拆掉幀首部以後,查看IP首部和TCP首部,它發現請求的報文訪問的是一個集羣服務。 因此爲了實現LVS-DR模型的效果,在源有的IP首部之上(切記源IP、目標IP、源端口、目標端口等等沒有動),僅僅是在原有的報文外面又重新封裝了一個MAC地址幀首部 幀首部有源MAC和目標MAC,這個時候發送的主機是Director。於是Director把本地網卡的MAC地址作爲整個報文的源MAC地址,而目的MAC就是選擇的後端某臺RealServer [選擇後端的某臺RealServe是Director根據它的一些調度算法(rr,wrr...)選擇的]。假如選擇的是RealServer2,那麼會找到RealServer2 IP對應的MAC地址,於是找到了 RealServer2網卡對應的MAC地址,它是通過ARP地址解析找到的RealServer2對應的MAC地址。 那麼Director到RealServer2之間的報文傳送是源MAC地址是Director網卡對應的MAC地址,目標MAC地址是RealServer2網卡對應的MAC地址。 RealServer2接收到報文以後,發現請求的報文真的是自已,於是拆掉了MAC的幀首部,拆掉後發現請求的報文源地址是cip,目標地址是VIP。如果RealServer2上沒有VIP ,那麼RealServer2是不會接受這個報文的,因此必須在每個RealServer上配置VIP地址。因爲RealServer2上有VIP地址,報文被接收下來,拆掉了IP首部,發現了報文 請求的是一個服務,比如80 因爲傳輸層沒有做任何修改,用戶請求的是80服務,那麼RealServer2接收到的報文也是請求的80服務。如果RealServer2上有80服務,於是 RealServer2把這個請求轉交給用戶空間的進程,由用戶空間處理完成後,向外響應的。而請求報文的源地址是CIP,目標地址是VIP。那麼儘可能讓它使用CIP是目標地址 VIP是源地址,於是這個響應報文直接被髮送到了交換機上。 當RealServer2響應報文到達Switch的時候,這個時候源地址是VIP,目標地址是CIP。 因爲目標地址是CIP,假如VIP和CIP不在同一個網段當中,這個時候要根據目標地址CIP做路由選擇,比如默認路由,網關才能響應CIP的報文請求 大家都知道目標地址CIP是互聯網地址,那麼每個RealServer的網關要指向哪呢?????? 要指向能夠訪問互聯網的設備,不應該指向Director的DIP地址。而是直接指向了能夠訪問互聯網的路由設備。所有(很有可能)指向的是R2路由的私有地址做網關。 爲什麼是很有可能而不是說一定呢???? 當報文被送到Switch和R2的時候,這個時候的源地址是VIP,目標地址是CIP。那麼這個時候報文被送到R2網關的時候,R2發現目標地址是互聯網的地址CIP,它會通過 路由NAT然後被送到CIP上的。 這裏要考慮一個問題,爲了實現每臺RealServer在向外發送響應報文的時候,可以把VIP作爲源地址,因此我們在每臺RealServer上配置了VIP地址。 假如客戶端發送請求報文被送到R2路由器的時候,那麼R2路由器會拆開客戶端的請求報文發現源地址是CIP,目標地址是VIP;無論是將請求送給Director還是RealServer,必須要根據 MAC地址向內轉發,因爲在同一網段,那麼它怎麼知道VIP對應的MAC地址是什麼呢???? 那麼將進行廣播說:‘我知道有一個傢伙的VIP地址,那麼請告訴我它對應的MAC地址’,那麼它發送的廣播請求,同一網段的所有主機都能收到,於是配置有 VIP地址的所有主機都進行相應並告訴自已的MAC地址,那麼如果所有的主機都進行相應,那麼前端的路由設備就混亂了,它就無法分辨誰纔是VIP對應的 MAC地址。 默認情況下,誰相應的快,就會把客戶端的請求報文發送給那臺主機,如果被送到RealServer2 那麼就不符合我們負載均衡的條件了。 那麼我們在這裏需要做一個非常重要的事情,就是每臺配置有RealServer的VIP地址不給予ARP響應。那麼我們如果屏蔽它不能響應呢? 那麼所有的RealServer上都要關閉對ARP廣播的響應。 要達到的目的:讓我們的前端路由或者網關,實現報文發送的時候,僅僅能夠將報文對目標IP爲VIP發送給Director? 實現的方式有以下三種: 1、在R2路由器的內部接口上手動綁定一個靜態的解析地址,明確指明目標是VIP的MAC一定是Director的MAC 那麼以後發送報文的時候就不用再次請求了,可以由指定的靜態解析地址直接發送給Director 這個綁定是靜態的也不會失效 缺點: R2路由是內部路由器,那麼VIP是私有地址;如果R2是網絡運營商提供的路由設備,也就是VIP是公網地址,我們就無法再R2上進行靜態綁定了。 2、arptables: 基於MAC地址做訪問控制的,我們只需要在每臺RealServer上定義arptables規則,如果用戶的arp廣播請求的目標地址是本機的VIP則不給予響應或者響應的報文不出去。 那麼這個情況所有的RealServer上不響應arp廣播請求,只有Director響應給路由則報文就必然被髮送給Director。 3、kernel paramter: arp_ignore arp_announce 作用:限定我們的Linux主機對arp廣播請求的響應級別,以及向外通告自已ip地址的通告級別的。
三、配置集羣服務
1、在Real Server1 和Real Server2上做以下配置
# 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 以上命令需填加到/etc/rc.local文件中讓其開機自動生效 # vim /etc/sysconfig/network-scripts/ifcfg-lo:0 內容如下 DEVICE=lo:0 IPADDR=172.16.100.100 NETMASK=255.255.255.255 BROADCAST=172.16.100.100 ONBOOT=yes NAME=loopback # ifdown lo:0 # ifup lo:0 # route add -host 172.16.100.100 dev lo:0 # echo "route add -host 172.16.100.100 dev lo:0" >> /etc/rc.local
2、在Director Server上做以下配置
# vim /etc/sysconfig/network-scripts/ifcfg-eth2:0 內容如下 DEVICE=eth2:0 IPADDR=172.16.100.100 NETMASK=255.255.255.255 BROADCAST=172.16.100.100 ONBOOT=yes # ifdown eth2:0 # ifup eth2:20 # route add -host 172.16.100.100 dev eth2:0 # echo "route add -host 172.16.100.100 dev eth2:0" >> /etc/rc.local # echo "1" > /proc/sys/net/ipv4/ip_forward # echo "echo "1" > /proc/sys/net/ipv4/ip_forward" >> /etc/rc.local # ipvsadm -A -t 172.16.100.100:80 -s wlc # ipvsadm -a -t 172.16.100.100:80 -r 172.16.100.10 -g -w 2 # ipvsadm -a -t 172.16.100.100:80 -r 172.16.100.11 -g -w 1
3、瀏覽器訪問測試
四、分享腳本
Director腳本:
#!/bin/bash # # LVS script for VS/DR # . /etc/rc.d/init.d/functions # VIP=172.16.100.100 RIP1=172.16.100.10 RIP2=172.16.100.11 PORT=80 # case "$1" in start) /sbin/ifconfig eth2:0 $VIP broadcast $VIP netmask 255.255.255.255 up /sbin/route add -host $VIP dev eth2:0 # Since this is the Director we must be able to forward packets echo 1 > /proc/sys/net/ipv4/ip_forward # Clear all iptables rules. /sbin/iptables -F # Reset iptables counters. /sbin/iptables -Z # Clear all ipvsadm rules/services. /sbin/ipvsadm -C # Add an IP virtual service for VIP 192.168.0.219 port 80 # In this recipe, we will use the round-robin scheduling method. # In production, however, you should use a weighted, dynamic scheduling method. /sbin/ipvsadm -A -t $VIP:80 -s wlc # Now direct packets for this VIP to # the real server IP (RIP) inside the cluster /sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -g -w 1 /sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w 2 /bin/touch /var/lock/subsys/ipvsadm &> /dev/null ;; stop) # Stop forwarding packets echo 0 > /proc/sys/net/ipv4/ip_forward # Reset ipvsadm /sbin/ipvsadm -C # Bring down the VIP interface /sbin/ifconfig eth2:0 down /sbin/route del $VIP /bin/rm -f /var/lock/subsys/ipvsadm echo "ipvs is stopped..." ;; status) if [ ! -e /var/lock/subsys/ipvsadm ]; then echo "ipvsadm is stopped ..." else echo "ipvs is running ..." ipvsadm -L -n fi ;; *) echo "Usage: $0 {start|stop|status}" ;; esac
RealServer腳本:
#!/bin/bash # # Script to start LVS DR real server. # description: LVS DR real server # . /etc/rc.d/init.d/functions VIP=172.16.100.100 host=`/bin/hostname` case "$1" in start) # Start LVS-DR real server on this machine. /sbin/ifconfig lo down /sbin/ifconfig lo 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 /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up /sbin/route add -host $VIP dev lo:0 ;; stop) # Stop LVS-DR real server loopback device(s). /sbin/ifconfig lo:0 down 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 ;; status) # Status of LVS-DR real server. islothere=`/sbin/ifconfig lo:0 | grep $VIP` isrothere=`netstat -rn | grep "lo:0" | grep $VIP` if [ ! "$islothere" -o ! "isrothere" ];then # Either the route or the lo:0 device # not found. echo "LVS-DR real server Stopped." else echo "LVS-DR real server Running." fi ;; *) # Invalid entry. echo "$0: Usage: $0 {start|status|stop}" exit 1 ;; esac
LVS-TUN
TUN的工作機制跟DR一樣,只不過在轉發的時候,它需要重新包裝IP報文。這裏的real server(圖中爲RIP)離得都比較遠。real server的rip必須是公網地址,用戶請求以後,到director上的VIP上,它跟DR模型一樣,每個realserver上既有RIP又有VIP,Director就挑選一個real server進行響應,但是director和real server並不在同一個網絡上,這時候就用到隧道了,director進行轉發的時候,一定要記得CIP和VIP不能動。我們轉發是這樣的,讓它的CIP和VIP不動,在它上面再加一個IP首部,再加的IP首部源地址是DIP,目標地址的RIP的IP地址,RIP必須是公網地址。收到報文的RIP,拆掉報文以後發現了裏面還有一個封裝,它就知道了,這就是隧道。
其實數據轉發原理和DR是一樣的,不過這個我個人認爲主要是位於不同位置(不同機房);LB是通過隧道進行了信息傳輸,雖然增加了負載,可是因爲地理位置不同的優勢,還是可以參考的一種方案;
優 點:負載均衡器只負責將請求包分發給物理服務器,而物理服務器將應答包直接發給用戶。所以,負載均衡器能處理很巨大的請求量,這種方式,一臺負載均衡能爲 超過100臺的物理服務器服務,負載均衡器不再是系統的瓶頸。使用VS-TUN方式,如果你的負載均衡器擁有100M的全雙工網卡的話,就能使得整個 Virtual Server能達到1G的吞吐量。
不足:但是,這種方式需要所有的服務器支持"IP Tunneling"(IP Encapsulation)協議;需要注意封裝時的MTU大小不要超出1500
LVS-NAT:
director通過同時修改請求報文的目標地址和源地址進行轉發;
(1) VIP是公網地址;RIP和DIP是私網地址,二者無須在同一網絡中;
(2) RS接收到的請求報文的源地址爲DIP,因此要響應給DIP;
(3) 請求報文和響應報文都必須經由Director;
(4) 支持端口映射機制;
(5) RS可以使用任意OS;
LVS的健康狀態檢查
在 LVS模型中,director不負責檢查RS的健康狀況,這就使得當有的RS出故障了,director還會將服務請求派發至此服務器,這種情況對用戶、企業都是很不爽的,哪個用戶倒黴說不定就遇到類似了,爲了讓director更人性化、可靠還要給director提供健康檢查功能;如何實現?Director沒有自帶檢查工具,只有手動編寫腳本給director實現健康狀態檢查功能!
#!/bin/bash # VIP=172.16.100.100 CPORT=80 FAIL_BACK=127.0.0.1 RS=("172.16.100.10" "172.16.100.11") declare -a RSSTATUS RW=("2" "1") RPORT=80 TYPE=g CHKLOOP=3 LOG=/var/log/ipvsmonitor.log addrs() { ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2 [ $? -eq 0 ] && return 0 || return 1 } delrs() { ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT [ $? -eq 0 ] && return 0 || return 1 } checkrs() { local I=1 while [ $I -le $CHKLOOP ]; do if curl --connect-timeout 1 http://$1 &> /dev/null; then return 0 fi let I++ done return 1 } initstatus() { local I local COUNT=0; for I in ${RS[*]}; do if ipvsadm -L -n | grep "$I:$RPORT" && > /dev/null ; then RSSTATUS[$COUNT]=1 else RSSTATUS[$COUNT]=0 A++ Dir[0]=$A fi let COUNT++ done } initstatus while :; do let COUNT=0 for I in ${RS[*]}; do if checkrs $I; then if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then addrs $I ${RW[$COUNT]} [ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I is back." >> $LOG fi else if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then delrs $I [ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date +'%F %H:%M:%S'`, $I is gone." >> $LOG fi fi let COUNT++ done sleep 5 done
LVS持久連接
一、定義
持久連接是指無論LVS使用什麼算法,LVS持久都能實現在一定時間內,將來自同一個客戶端請求派發至此前選定的RS
二、原理
無論使用LVS任何調度算法,LVS持久連接都能實現在一定時間內,將來自同一個客戶端請求派發至此前選定的服務器;當一個新的客戶端請求連接時,LVS就 會在內存的緩衝區內記錄客戶端的IP以及所選的服務器,在一定時間內用戶再次訪問時,LVS會通過內存緩衝區來查找是否有此用戶記錄,如果有將直接連接到 已選定的服務器上,否則記錄IP及連接的服務器;這個內存緩衝區稱之爲持久連接模板,它存儲了每一個客戶端,及分配給它的RS的映射關係。
持久連接在一定環境下還是非常有用的,由於在SSL會話中,比如當用戶和服務器好不容易建立了SSL會話,用戶一不小心刷新了頁面,director有給用 戶分發了一個新的服務器,用戶還要從新建立SSL連接請求,這是很不爽的!這種連接方式稱爲持久端口連接(PPC),將來自於同一個客戶端對同一個集羣服務的請求,始終定向至此前選定的RS。
持久連接還會將同個用戶的其他服務請求連接到已建立連接的服務器上,比如當用戶訪問web服 務時,還要能實現https認證,如果訪問web時,分配了一個RS,要通過https認證則又分配了一個RS;這樣就產生了矛盾,它認證的不是一個 RS,使得訪問無法安全進行;因此持久連接是必不可少的,這種稱爲持久客戶端連接(PCC),將來自於同一個客戶端對所有端口的請求,始終定向至此前選定 的RS;把所有端口統統定義爲集羣服務,一律向RS轉發!
持久防火牆標記連接(PNMPP):定義端口間的姻親關係,將特定端口定 義在同一個RS上。這是通過在防火牆內部PREROUTING鏈上,將規定的端口打上標記;比如:80端口標記爲10,23端口也標記爲10;這樣在寫規 則時只需將端口該爲10即可,80和23端口就會在同一個RS上響應了
三、持久連接的分類
1、PPC 將來自於同一個客戶端對同一個集羣服務的請求,始終定向至此前選定的RS; 持久端口連接
2、PCC 將來自於同一個客戶端對所有端口的請求始終定向至此前選定的RS 持久客戶端連接
把所有端口統統定義爲集羣服務,一律向RS轉發:
定義所有的服務
3、PNMPP 持久防火牆標記連接
定義部分服務
四、持久連接的命令
ipvsadm -A|E ... -p timeout:
timeout:持久連接時長,默認300秒:單位是秒
五、額外的補充
持久連接模板(內存緩衝區) 持久連接模板記錄了:每一個客戶端IP及分配給它的RS的映射關係 查看持久連接模板 ipvsadm -L -c #顯示當前的每一個連接模板 ipvsadm -L --persistent-conn #顯示當前的持久連接數 { [root@LVS ~]# ipvsadm -L -c IPVS connection entries pro expire state source virtual destination [root@LVS ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.100:80 wlc -> 172.16.100.10:80 Route 1 0 0 -> 172.16.100.11:80 Route 2 0 0 } PNMPP的語法 PREROUTING 80:標記10 23:標記10 語法: /sbin/iptables -F -t mangle /sbin/iptables -A PREROUTING -i eth0 -t mangle -p tcp -d 172.16.100.6 --dport 80 -j MARK -set-mark 1 /sbin/iptables -A PREROUTING -i eth0 -t mangle -p tcp -d 172.16.100.6 --dport 443 -j MARK -set-mark 1 /sbin/ipvsadm -A -f 1 -s rr -p 3600 /sbin/ipvsadm -a -f 1 -r 172.16.100.10 -g -w 2 /sbin/ipvsadm -a -f 1 -r 172.16.100.11 -g -w 1
六、部署
假如後端有多臺RS;同時定義了兩個集羣服務,web服務和telnet服務 目的:前端用戶訪問80端口的時候會同時負載後端的多臺RS上,並且23號端口的訪問也會同時負載到多臺RS上。 描述:後端有多臺RS。每臺RS上同時提供web服務和telnet服務。我們希望前端用戶訪問的時候,對80端口發起的訪問請求會分別負載到多臺RS上。 同時對23號端口的訪問也會負載到多臺RS上。所以說,它們同時提供了兩類集羣服務,那麼就是Dirctor同時提供兩種集羣服務的負載均衡。 結論: 持久連接有這種功能 比如,user1訪問80端口服務的時候,Director把報文轉發RS1上;當user1下次在訪問23號端口的時候,Director還是會把報文轉發RS1上的。 1、ipvsadm輪詢算法rr [root@LVS ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.100:80 rr -> 172.16.100.10:80 Route 1 0 0 -> 172.16.100.11:80 Route 2 0 0 結論:通過上面的輪詢算法rr;用瀏覽器訪問的結果是 第一次被定向到RS1上面 第二次被定向到RS2上面 第三次被定向到RS1上面 第四次被定向到RS2上面 ...... 2、ipvsadm的持久連接web服務(PPC) [root@LVS ~]# ipvsadm -E -t 172.16.100.100:80 -s rr -p 600 [root@LVS ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.100:80 rr persistent 600 -> 172.16.100.10:80 Route 1 0 0 -> 172.16.100.11:80 Route 2 0 0 結論:通過上面的持久連接;用瀏覽器訪問的結果是 如果此時定向到RS1上,那麼刷新頁面之後被定向到RS2上,以後你無論怎麼刷新都被定向到RS2上面。 [root@LVS ~]# ipvsadm -L --persistent-conn IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Weight PersistConn ActiveConn InActConn -> RemoteAddress:Port TCP 172.16.100.100:http rr persistent 600 -> 172.16.100.10:http 1 0 0 0 -> 172.16.100.11:http 2 1 0 16 [root@LVS ~]# ipvsadm -L -c IPVS connection entries pro expire state source virtual destination TCP 00:00 FIN_WAIT 172.16.100.2:52083 172.16.100.100:http 172.16.100.11:http TCP 00:10 FIN_WAIT 172.16.100.2:52086 172.16.100.100:http 172.16.100.11:http TCP 00:00 FIN_WAIT 172.16.100.2:52071 172.16.100.100:http 172.16.100.11:http TCP 00:00 FIN_WAIT 172.16.100.2:52085 172.16.100.100:http 172.16.100.11:http TCP 08:00 NONE 172.16.100.2:0 172.16.100.100:http 172.16.100.11:http TCP 00:00 FIN_WAIT 172.16.100.2:52084 172.16.100.100:http 172.16.100.11:http 3、ivpsadm的持久連接telnet服務(PPC) 注意:telnet是不允許超級管理員root直接遠程登陸的 { #安裝、啓動telnet服務 # yum -y install telnet-server # chkconfig --add telnet # chkconfig telnet on # useradd jerry # passwd jerry # netstat -tnlp |grep :23 } { #定義telnet集羣服務 ipvsadm -C ipvsadm -A -t 172.16.100.100:23 -s rr ipvsadm -a -t 172.16.100.100:23 -r 172.16.100.10 -g -w 2 ipvsadm -a -t 172.16.100.100:23 -r 172.16.100.11 -g -w 1 測試1 Xshell:\> telnet 172.16.100.100 login: jerry Password: jerry [jerry@web2 ~]$ #RS2 看主機名稱可以辨別出連接的是哪一臺RS,然後退出後在此登陸 Xshell:\> telnet 172.16.100.100 login: jerry Password: jerry [jerry@web1 ~]$ #RS1 支持持久連接的telnet服務 [root@LVS ~]# ipvsadm -E -t 172.16.100.100:23 -s rr -p 3600 [root@LVS ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.100:23 rr persistent 3600 -> 172.16.100.10:23 Route 2 0 0 -> 172.16.100.11:23 Route 1 0 1 測試2 Xshell:\> telnet 172.16.100.100 login: jerry Password: jerry [jerry@web1 ~]$ #RS1 退出後再次登陸 Xshell:\> telnet 172.16.100.100 login: jerry Password: jerry [jerry@web1 ~]$ #RS1 結論:telnet集羣服務的持久連接成功 } 4、ipvsadm持久連接(PCC) { #把0端口定義成集羣服務,這意味所有的端口都是集羣服務 ipvsadm -C ipvsadm -A -t 172.16.100.100:0 -s rr -p 600 ipvsadm -a -t 172.16.100.100:0 -r 172.16.100.10 -g -w 2 ipvsadm -a -t 172.16.100.100:0 -r 172.16.100.11 -g -w 1 測試 瀏覽器、telnet、ssh 瀏覽器訪問被定向到比如RS2 telnet測試被定向到RS2 Xshell:\> telnet 172.16.100.100 login: jerry Password: jerry [jerry@web2 ~]$ #RS2 ssh 172.16.100.100 [root@web2 ~]# 看下連接的模板 [root@LVS ~]# ipvsadm -L -c IPVS connection entries pro expire state source virtual destination TCP 14:32 ESTABLISHED 172.16.100.2:52735 172.16.100.100:ssh 172.16.100.11:ssh TCP 00:09 NONE 172.16.100.2:0 172.16.100.100:0 172.16.100.11:0 TCP 04:11 NONE 172.16.100.2:0 172.16.100.100:telnet 172.16.100.10:telnet TCP 14:55 ESTABLISHED 172.16.100.2:52499 172.16.100.100:telnet 172.16.100.11:telnet } 5、ivpsadm持久連接(PCC) 現在把23端口和80端口的定義成一個集羣服務 22端口的是另外一個集羣服務 ipvsadm -C service ipvsadm restart ipvsadm -L -n iptables -A PREROUTING -i eth2 -t mangle -p tcp -d 172.16.100.100 --dport 80 -j MARK --set-mark 8 iptables -A PREROUTING -i eth2 -t mangle -p tcp -d 172.16.100.100 --dport 23 -j MARK --set-mark 8 ipvsadm -A -f 8 -s rr [-p 600] ipvsadm -a -f 8 -r 172.16.100.10 -g -w 2 ipvsadm -a -f 8 -r 172.16.100.11 -g -w 1 結論: 由於22端口的ssh服務沒有被定義成集羣服務,所以在登陸的時候是Director來響應 Xshell:\> ssh 172.16.100.100 [root@LVS ~]# 由於80服務和23服務都被定義集羣服務,所以在訪問的時候應該是調度算法輪詢來響應的 Xshell:\> telnet 172.16.100.100 login: jerry Password: [jerry@web2 ~]$ 退出再次訪問 Xshell:\> telnet 172.16.100.100 login: jerry Password: [jerry@web1 ~]$ 瀏覽器訪問也是一樣的,輪詢這響應請求 第一次響應的是RS1 第二次響應的是RS2 第三次響應的是RS1 第四次響應的是RS2