Linux集群部署和ipvsadm命令的使用
在日常的使用中,一臺服務器足夠勝任很多的工作,但是當很多人同時訪問的時候就會顯得稍有些無力,這個時候。可以有兩種解決的方法,第一種是不斷的改善這臺服務器的性能,但是總是會有一個上限存在,而且提升的效果並不明顯。另外一種方法就是使用多臺服務器,來均攤需要處理的任務,這就是集群,通過一定的組合方式,將很多功能一樣的服務器祖喝道一起,但是使用時感受不到他們的差異。組合的方式目前有四種,分別是lvs-nat、lvs-dr、lvs-tunnel和熱心網友提供的lvs-fullnat,在Linux內核中僅支持前三種,最後一種如果想要使用需要自己重新編譯內核。在開始介紹之前我們需要了解幾個常用術語:
vs:virtual server,構成集群的調度器(中心節點) rs:real server,用戶只能找到vs,但是真正提供服務的是rs CIP:Client IP,客戶端的IP地址,即請求發送方的IP地址 VIP:Virtual Server IP,,虛擬服務器的虛擬IP地址,客戶端訪問的目的地址 DIP:Director IP,調度器IP地址,向後方Real Server轉發客戶端請求時使用的IP地址 RIP:Real Server IP,後方真實服務器的IP地址
簡單來說就是當用戶訪問服務器的時候首先訪問到的是調度器,然後由調度器查看有哪一臺集群中的服務器是相對空閑,那麽就將請求送到這一臺服務器上進行處理。用戶的地址叫做CIP,用戶訪問的地址叫做VIP,調度器上用於訪問集群的地址叫做DIP,集群中各個服務器的地址叫做RIP。下面開始依次介紹各種集群方式。
一、lvs-nat
這種方式構建集群的架構如圖所示:
首先由客戶端的CIP發起請求,由調度器分發到後端服務器上進行處理,在處理之後返回處理結果。具體是哪個主機由調度器根據算法進行選擇,根據lvs在調度時是否考慮各RS當前的負載狀態,可以將調度算法分為兩類,分別是靜態算法和動態算法,靜態算法是事先就將分配的過程安排好,而動態算法是在實時的處理過程中根據服務器的忙碌程度進行分配。(每種架構方式使用的基本都是如下算法,後邊不再重復說明)
靜態算法,根據算法本身的特點進行調度,註重起點公平,包括以下幾種:
RR:RoundRobin,輪詢(一人一個任務,但是有的服務器性能好,有的差,所以這種分配方式不太好) WRR:Weighted RR,加權輪詢(有額外的權重幹擾分配結果)(能力越大責任越大)(權重高,代表工作能力強,就會被多分配任務) SH:Source Hashing,源地址哈希,將來自於同一個IP地址的請求始終發往後端第一次被挑中的RS,從而可以實現會話綁定,例如購物等操作,最好要保持在同一臺服務器上 DH:Destination Hashing,目的地址哈希,將發往同一個目標地址的請求,始終發送至後端第一次被挑中的RS,一般用於正向代理服務器集群
動態算法,主要根據每個RS當前的負載狀態進度調度,註重結果公平,包括以下幾種:
(後端RS的負載情況,用Overhead表示,使用這個變量可以來實時的觀測任務最好分配給哪臺服務器,通過active connection(活動的連接數)和inavtive connection(不活動的連接數)來進行計算)
LC:least connections,最少連接數
計算公式:Overhead=activeconnections*256+inactiveconnections
註意:第一次調度時,按照在ipvsadm中配置的順序自上而下進行分配
WLC:Weighted LC,加權最小連接(如果在部署時未指定,默認為這個)
計算公式:Overhead=(activeconnections*256+inactiveconnections)/weight
註意:第一次調度時,按照在ipvsadm中配置的順序自上而下進行分配,權重在第一次調度時不發揮作用
SED:Shortest Expection Delay,最短期望延遲
計算公式:Overhead=(activeconnections+1)*256/weight
註意:SED可以解決起點不公平的問題,但是在權重差距比較大時,可能會導致不公平
例如:weight一個1,一個10,那麽為10的會連續獲得多個任務
NQ:Never Queue,改進版的SED算法,首次調度時,根據後端RS的權重依次為每臺RS分配一個連接;然後再按照SED算法調度;必然會保證後端每臺RS至少有一個 activeconnection; LBLC:Locality-Based Least Connections:基於本地的最少連接,動態的DH算法 LBLCR:LBLC with Replication,帶有復制功能的LBLC
集群部署時最難的是理解架構方式,在理解了之後,部署是十分簡單的,在lvs-nat的方式下,我們只需要將各個網段設置好,使相同網段之間能夠ping通即可,然後在調度器上使用“ipvsadm”命令(在內核中有ipvs,是實現集群的功能,主要工作在INPUT鏈上,ipvs(INPUT):內核中的TCP/IP協議棧上的組件,而ipvsadm用來編寫規則送給ipvs(類似於防火墻的iptables軟件的功能,是用戶空間中的用於編寫ipvs規則的組件)查看內核中是否支持ipvs功能:~]# grep -i -C 10 "ipvs" /boot/config*):
ipvsadm: 格式: ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] 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 [-g|i|m] [-w weight] 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 syncid] ipvsadm --stop-daemon state ipvsadm -h
管理集群服務:增,刪,改(對集群整體的處理) 增加lvs集群服務:ipvsadm -A -t|u|f service-address [-s scheduler] [-p [timeout]] -t:基於TCP協議的集群服務 service-address:與VIP綁定的套接字 -u:基於UDP服務的集群服務 service-address:與VIP綁定的套接字 -f:基於防火墻協議(FWM—Firewall mark,防火墻標記)的集群服務 通過iptables的mangle表對數據設置的標記 -s:指定集群服務的調度算法(如果省略,默認是wlc) -p:是否開啟持久連接 修改lvs集群服務:ipvsadm -E -t|u|f service-address [-s scheduler] [-p [timeout]] 參數和增加類似 刪除lvs集群服務:ipvsadm -D -t|u|f service-address 清除lvs集群服務:ipvsadm -C(類似於iptables的“-F”)(最好不要輕易的使用)
管理集群中的RS:增,刪,改(這是對集群中的哪些服務器進行處理的命令) 在集群中添加RS:ipvsadm -a -t|u|f service-address -r server-address [-g|i|m] [-w weight] -r:指定要添加到集群中的後端RS的IP地址和端口 -g:選擇集群類型為DR(默認值) -i:選擇集群類型為TUN -m:選擇集群的類型為NAT -w:為RS(Real Server)設定的權重(不要設定的懸殊過大,否則分配會不當) 修改集群中的RS:ipvsadm -e -t|u|f service-address -r server-address [-g|i|m] [-w weight] 從集群中刪除的RS:ipvsadm -d -t|u|f service-address -r server-address
查看lvs集群狀態及屬性信息: ipvsadm -L|l [options]: options包括: -c, --connection:查看當前的ipvs中的各種連接的狀態 --stats:顯示lvs集群的統計數據信息 --rate:顯示lvs集群與傳輸速率有關的內容 --timeout:顯示TCP、TCP的FIN標誌位及UDP會話的超時時長
保存和重載ipvs的規則(兩種方法都可以): 保存: ipvsadm -S [-n](只是顯示出來並不是保存,需要重定向,自己保存) > /PATH/TO/IPVS_RULE_FILE ipvsadm-save > /PATH/TO/IPVS_RULE_FILE 重載: ipvsadm -R < /PATH/TO/IPVS_RULE_FILE ipvsadm-restore < /PATH/TO/IPVS_RULE_FILE 保存規則並於開機時自動載入: CentOS 6-: # chkconfig ipvsadm on 將規則保存至:/etc/sysconfig/ipvsadm CentOS 7: 將規則保存至:/etc/sysconfig/ipvsadm # systemctl enable ipvsadm.service
清空計數器(當想要重置的時候可以清空計數器): ipvsadm -Z [-t|u|f service-address] 後頭如果沒參數則清空所有的計數器
在了解了命令之後,我們就可以開始部署lvs-nat集群了,首先按照圖中所示,配置好相應的IP,並在調度器上使用以下命令:
~]# yum install ipvsadm -y #安裝管理軟件ipvsadm ~]# ipvsadm -A -t 172.15.0.2:80 -s rr #創建一個集群服務 ~]# ipvsadm -a -t 172.15.0.2:80 -r 172.16.128.18:80 -m -w 1 #在剛才創建的集群中添加一臺服務器,“-m”指定為NAT方式 ~]# ipvsadm -a -t 172.15.0.2:80 -r 172.16.128.19:80 -m -w 2 #在剛才創建的集群中添加一臺服務器,“-w”指定權重(在NAT中權重沒用,但是先寫上,後邊會用)
然後在RS上安裝httpd服務(所有服務器上都要安裝)(默認是已經安裝完的):
~]# yum install httpd -y ~]# route add default gw 172.16.128.17 #並指定網關,否則即使服務轉到服務器上也回不去 ~]# echo "This is 172.16.128.18" > /var/www/html/index.html 在172.16.128.18上執行
~]# echo "This is 172.16.128.19" > /var/www/html/index.html 在172.16.128.19上執行
最後將服務都開啟:
~]# service httpd start #CentOS 6 上
回到調度器上進行驗證:
驗證通過之後,在調度器上開啟轉發功能:
~]# echo 1 > /proc/sys/net/ipv4/ip_forward
這樣,lvs-nat集群就配置完成了,我們可以在作為客戶端的主機上通過命令來進行查看:
~]# for i in {1..10} ; do curl http://172.15.0.2 ; done #使用循環的方式連續訪問10次
從圖中我們可以看出,調度器安裝輪詢的方式,一次訪問172.16.128.19,一次訪問172.16.128.18,此時我設置的是兩個不同的網頁,如果兩個相同,那麽在用戶使用的時候就看不出差距,就可以實現任務均攤,來減輕服務器的負擔。
然後,我們可以更換一個算法,改為wlc算法:
~]# ipvsadm -E -t 172.15.0.2:80 -s wlc
再使用上面的方式進行查看發現,兩臺服務器的工作分配方式變成了2比1,這是因為在上面添加服務器的時候172.16.128.18的權重為1,而172.16.128.19的權重為2:
二、lvs-dr
lvs-dr的配置相對於lvs-nat來說減輕了調度器的工作壓力,如果是lvs-nat方式,那麽不管是進入集群的數據包還是從集群中出來的數據包都要經過調度器進行分發,那麽調度器就是這個集群的效率瓶頸,如果調度器不夠好,集群的工作效率就會大打折扣。所以lvs-dr模型減輕了調度器的工作壓力,只有進入集群的數據包才會經過調度器,而從集群中出來的數據包直接由服務器發送回客戶端。不過這樣又會遇到一個問題,就是IP地址的問題,如果直接從服務器進行發送,那麽源地址就不是客戶端請求的地址,客戶端就會禁止這種數據包,所以lvs-dr模型通過偽裝用戶訪問的IP地址來實現集群。架構的方式如圖所示(客戶端的IP現實中不會是這個,在這裏只是為了進行簡單的驗證)(如果做過上面lvs-nat的實驗,主機IP等配置需要重置):
此時的客戶端可以和上圖中所有的IP進行通信:
在DR模型中,各個主機均需要配置VIP;解決地址沖突的方法通常有三種:
1.在前端網關上靜態綁定VIP和MAC;
2.在各個RS中使用arptables進行arp報文的過濾;
3.在各個RS中修改對應的內核參數,來限制ARP的通告和應答的級別;
在內核中通過更改下面兩個值可以達到相應的效果:
arp_ignore: 0:默認值,對於從任何網絡接口接收到對本機任意IP地址的ARP查詢請求均予以回應; 1:只應答目標IP地址是入站接口上配置的IP地址所在網段的IP地址的ARP請求; 2:只應答目標IP地址是入站接口上配置的IP地址所在網段的IP地址的ARP請求,且來訪IP地址也必須與該接口的IP地址在同一子網中; 3:不響應該網絡接口的ARP請求,而只對設置為全局的IP地址做應答; 4-7:保留; 8:不應答所有的ARP請求;
arp_announce: 0:默認值,將本機所有接口的信息向所有接口所連接的網絡中通告; 1:盡量避免向與本接口不同網絡中的其他接口通告; 2:絕對避免向非本網絡的主機通告;
在兩臺服務器上都運行下面的命令:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore #設置所有接口(在所有中包含lo接口) echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore #設置lo接口(為了安全起見,在lo接口上再設置一次) echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig lo:0 172.16.128.128 netmask 255.255.255.255 broadcast 172.16.128.128 up route add -host 172.16.128.128 dev lo:0
這樣,在服務器上的配置就完成了,然後還是像lvs-nat一樣將httpd服務開啟,並設置主頁,之後回到調度器上執行命令:
~]# ifconfig eth0:0 172.16.128.128 netmask 255.255.255.255 broadcast 172.16.128.128 up
~]# ipvsadm -C #情空規則 ~]# ipvsadm -A -t 172.16.128.128:80 -s rr #添加集群 ~]# ipvsadm -a -t 172.16.128.128:80 -r 172.16.128.18 -g -w 1 #向集群中添加服務器 ~]# ipvsadm -a -t 172.16.128.128:80 -r 172.16.128.19 -g -w 3 #添加幾個,就寫幾個 “-g”選項是選擇集群類型為DR,不寫也可以,因為默認就是這個
到此,lvs-dr模型就配置好了,可以到客戶端(172.16.128.17)上使用命令進行查看:
~]# for i in {1..10} ; do curl http://172.16.128.128 ; done
更改算法的方式和lvs-nat一樣。
三、基於標記的轉發
上面是兩種架構的方式,接下來要說一說基於標記的轉發方式,可以使用任何一個架構方式。通過防火墻的mangle表的PREROUTING鏈來對訪問調度器的數據包進行標記,例如訪問80端口就給其標記為6,然後在配置集群的時候就可以使用這個標記來進行分配。這樣的方式相對於其他的方法更為靈活。配置的方法是首先使用iptables進行標記:
iptables -t mangle -F #清空規則,目的是防止其他規則的影響,可以不用執行 iptables -t mangle -A PREROUTING -d 172.16.128.128 -p tcp --dport 80 -j MARK --set-mark 6
然後使用ipvsadm命令基於標記進行服務器調度:
ipvsadm -C ipvsadm -A -f 6 -s rr #“-f”後跟的是標記的記號,根據上頭設定的記號進行修改 ipvsadm -a -f 6 -r 172.16.128.18:80 -g -w 1 ipvsadm -a -f 6 -r 172.16.128.19:80 -g -w 3
上面的命令都是在調度器上進行配置,服務器不用管,下面使用客戶端查看
四、長連接
在上面的基礎上,在調度器上使用下面這條命令:
~]# ipvsadm -E -f 6 -s wrr -p
這條命令的作用是構建長連接,即如果一個客戶端連接了集群中的服務器之後,那麽在“-p”選項後指定的時間(默認360秒)之內訪問還是這個服務器。
如圖所示,在調度器上使用這個命令:
最後就可以在客戶端上重復連接10次,可以發現10次都是連接的同一個服務器:
如果換一個主機,就會是另外一個服務器了(根據算法進行選擇)
Linux集群部署和ipvsadm命令的使用