一、LVS羣集技術基礎
根據企業的環境不同,羣集所提供的功能也是各不相同。採用的技術也是各有千秋,然而他們從整體上來看,需要了解一些關於集羣的供共同特徵。
1、羣集的類型
無論是那種羣集第一點都是不必須使用兩臺服務器,而對外就是一個整體,只提供一個訪問入口。集羣可以分爲以下三種
負載均衡羣集:主要的作用是提高對客戶端的響應能力,均勻的調用服務器資源。將來自客戶端的請求分發給多個服務器節點,從而緩解整個系統的壓力。
高可用羣集:這種羣集技術主要是實現網絡中服務器的單點故障,服務的連續性以及減少服務的中斷時間。
高性能運算羣集:這類羣集是將所有服務器的CPU資源進行整合從而能夠提高CPU的運算速度,這種羣集適合大數據處理
2、羣集負載均衡的分層結構
圖1典型的負載均橫羣集結構
第一層,負載調度器:這是訪問羣集的唯一入口,也就是說客戶端的訪問請求的目標地址都是這個負載調度器,對外使用的所有服務器都使用一個共有的VIP也就是羣集IP,通常會配置主從兩臺服務器來實現。
第二層,服務器池:羣集所提供的應用服務(如HTTP、FTP等),其中每個節點都有自己的真實IP,只處理調度器分配的客戶端請求,當某個節點宕機時,調度器將會將其隔離,等待錯誤排除之後再重新加入到服務器池。
第三層,共享存儲:爲服務器池中的節點提供存儲,確保服務器池內的主機提供的內容都是相同的。在Linux/UNIX中,共享存儲可以使用NAS設備,或者是提供NFS的共享服務器。
3、負載均橫的工作模式
關於羣集的負載調度技術,可以基於IP、端口進行分發,其中基於IP的是效率最高的。基於IP的負載平衡模式中,常見的有地址轉換、IP隧道和直接路由三種工作模式
圖2三種負載均橫模式示意圖比較
地址轉換:簡稱NAT模式,類似於防火牆的私有網絡結構,負載調度器作爲所有服務器的網關,即作爲客戶端的訪問入口,也是各個節點應答的出口,服務器使用私網地址與調度器位於同一物理網絡,這種工作模式安全性比較好,但是當訪問量過大時將會成爲整個網絡的瓶頸。
IP隧道:簡稱TUN模式,採用開放式的網絡結構,調度器僅作爲客戶端的訪問入口,各個節點分佈在互聯網的其他不同位置,具有獨立的公網IP地址,通過專用的IP隧道與負載調度器通信,這種工作模式其性能較差,安全也得不到保障。
直接路由方式:採用半開放式的網絡結構,必須與調度器在一個物理網絡中的同一網段內。這種工作模式也是最常用的,性能最好的,安全性也能夠得到保障。
二、LVS虛擬服務器
Linux Virtual Server 是針對linux內核開發的一個負載均衡項目,由我國的章文嵩不博士在1988年5月創建,官方站點位於http://www.linuxvritualserver.org/。LVS實際上就是相當於一個IP地址的虛擬化應用,未基於IP地址和內容請求分發的負載均衡提出了一種高效的解決辦法。
LVS現在已經成爲了Linux內核的一部分,默認編譯模塊爲ip_vs模塊,必要時能夠自動調用。在Cetnos6中一下操作可以加載ip_vs模塊,並查看當前系統中ip_vs模塊的版本信心。
[root@centos1 ~]# modprobe ip_vs
[root@centos1 ~]# cat /proc/net/ip_vs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@centos1 ~]#
下面介紹一下LVS負載均衡主要的調度算法,以及如何使用Ipvsadm工具管理工具
1、LVS的負載均衡算法
針對不同的網絡和服務器配置需求,LVS調度器提供多種不同的負載均衡調度算法,其中最常用的四種算法分別是輪詢、加權輪詢、最少連接以及加權最少連接
輪詢:將接收到的客戶端請求順序分配到各個服務器節點,不管服務器的真實負載
加權輪詢:根據真實的服務器處理能力輪流分配收到的訪問請求,調度器根據服務器的真實負載動態的調整權重。
最少連接:根據服務器的真實連接數而將客戶端請求分配給連接最少的服務器節點
加權最少連接:在服務器節點性能差異較大時建議使用,權重高的節點可以承擔更大的連接負載。
我個人認爲第一種不是特別好,剩下的三種都是比較不錯的算法。
2、安裝ipvsadm管理工具
ipvsadm是在負載調度器上使用的LVS羣集管理工具,通過調用ip_vs模塊來添加、刪除服務器節點。在centos6中需要手動安裝ipvsadm-1.26.2.e16.x86_64軟件包
[root@centos1 ~]# yum -y install ipvsadm
[root@centos1 ~]# ipvsadm -v
ipvsadm v1.26 2008/5/15 (compiled with popt and IPVS v1.2.1)
接下來我們先不介紹ipvsadm工具的使用,我們首先利用nfs建立一個共享存儲在搭建一個環境來進行講解。
3、安裝nfs-utils、rpcbind軟件包
root@centos2 ~]# yum -y install nfs-utils rpcbind
[root@centos2 ~]# chkconfig nfs on
[root@centos2 ~]# chkconfig rpcbind on
在啓動服務時應先啓動rpcbind再啓動nfs,因爲nfs依賴於rpcbind
3.1建立共享目錄以及共享目錄
[root@centos2 ~]# mkdir /opt/html
vi /etc/exports
/opt/html 192.168.1.0/24(rw,sync,no_root_squash)
第一個字段爲共享目錄
第二個字段爲訪問源IP(也就是可以被那些IP地址訪問)小括號比分內是權限列表這些IP地址都具有那些權限。
rw具有讀寫 ro內容只讀 sync表示同步寫入(內存和硬盤之間同步寫入) no_root_squash表示當客戶端使用root訪問時賦予本地root的權限,當一個目錄分配給不同主機時可以使用空格隔開。以下是賦予不同權限的格式(不是我這個共享所需要的格式,這裏只是演示)
/opt/html 192.168.1.150(rw) 192.168.1.200(ro)
接下來我們將這兩個服務啓動
[root@centos2 ~]# service rpcbind start
[root@centos2 ~]# service nfs start
可以通過一下方式驗證,查看一下本機的NFS目錄
[root@centos2 ~]# showmount -e 127.0.0.1
Export list for 192.168.1.1:
/opt/html 192.168.1.0/24
由於默認的nfs監聽端口是動態的,我們無法建立防火牆規則,所以我們通過修改/etc/sysconfig/nfs文件將其端口固定。
vim /etc/sysconfig/nfs
MOUNTD_PORT="825"
STATD_PORT="909"
LOCKD_TCPPORT="4004"
LOCKD_UPPORT="4004"
RQUOTAD_PORT="909"
通過lsof -nPi 查看使用mount需要通過哪些端口
[root@centos2 ~]# lsof -nPi
rpc.mount 1834 root 7u IPv4 15868 0t0 UDP *:825
rpc.mount 1834 root 8u IPv4 15872 0t0 TCP *:825 (LISTEN)
rpc.mount 1834 root 9u IPv6 15876 0t0 UDP *:825
rpc.mount 1834 root 10u IPv6 15880 0t0 TCP *:825 (LISTEN)
可以看出TCP的 825號端口正在監聽mount操作,所以我們在防火牆上建立825允許入站的規則
[root@centos2 ~]# iptables -I INPUT -p tcp --dport 825 -j ACCEPT
建立一個測試頁到共享目錄下
[root@centos2 ~]# echo "test lvs Cluster" > /opt/html/index.html
這樣我們的共享存數就搭建完成了,這時我們就可以搭建我們的實驗環境了。
圖3
上圖的實驗拓撲爲NET模式,後面我們會演示DR模式的LVS
我們使用兩臺web服務器作爲節點,一臺服務器作爲調度器同時作爲網關,一臺服務器最爲存儲服務器。其中調度器爲雙網卡,一個鏈接互聯網,一個鏈接局域網。
存儲我們已經搭建完成了,這裏我們就不在搭建了,我們首先將兩臺web服務器啓動,使用nginx服務來搭建web站點,注意防火牆。
1、建立虛擬服務器,提供http的負載均衡並且算法使用輪詢(rr)算法
-使用-A新建虛擬服務器 -t 指定監聽地址 -s 指定算法
[root@centos1 ~]# ipvsadm -A -t 172.16.16.172:80 -s rr
2、添加節點主機到虛擬服務器中
[root@centos1 ~]# ipvsadm -a -t 172.16.16.172:80 -r 192.168.1.3:80 -m -w 1
[root@centos1 ~]# ipvsadm -a -t 172.16.16.172:80 -r 192.168.1.4:80 -m -w 1
[root@centos1 ~]# service ipvsadm save
[root@centos1 ~]# service ipvsadm start
3、配置節點主機
node_1:192.168.1.3
[root@centos3 ~]# nginx
[root@centos3 ~]# mount 192.168.1.2:/opt/html /var/www/html/
[root@centos3 ~]# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
node_1:192.168.1.4
[root@centos4 ~]# nginx
[root@centos4 ~]# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
4、配置NAT轉發規則並且配置防火牆規則
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@centos1 ~]# sysctl -p
[root@centos1 ~]# iptables -t nat -I POSTROUTING -s 192.168.1.0/24 -o eht1 -j SNAT --to 172.16.16.172
[root@centos1 ~]# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
[root@centos1 ~]# iptables -I INPUT -p tcp --sport 80 -j ACCEPT
[root@centos1 ~]# service iptables save
5、客戶端測試
這就是NAT模式的配置,比較簡單但是在實際生產環境下應用的不多,只適合一些小型企業
這裏我在來介紹一下ipvsadm工具的選項
ipvsadm
-A 創建虛擬服務器
-t 指定羣集IP地址
-r添加節點服務器
-s 指定算法 rr 輪詢 wrr 加權輪詢 lc 最少連接 wlc 加權最少連接
-m 指定爲NAT模式
-g 指定爲DR模式
-i 指定爲TUN模式
-w 指定權重
-l 列出服務器池內各節點狀態
-c 列出詳細的訪問信息
-v 輸出ipvsadm版本信息
NAT模式的lvs總結的來所他的原理就是:調度器收到來自客戶端的請求將目標地址改爲節點服務器的IP地址,節點服務器在應答時直接應答給客戶端目標地址爲客戶端的IP地址,但是由於是NAT模式所以調度器也就成爲了節點服務器的唯一出口。
三、直接路由模式
1、準備環境
在DR模式羣集中,LVS僅負責作爲客戶端訪問的入口,並不作爲服務器節點應答的出口。服務器池中內每臺節點都各自接入Internet,發送給客戶端的應答不需要經過LVS負載調度器,如下圖所示
圖6
這裏我們IP地址都使用共有地址網段來體現,服務器節點採用雙網卡,一塊用於應答客戶端請求,一塊連接共享存儲,在實際的生產環境下,可以連接一臺交換機。在實際生產環境下一般我們會採用服務器節點都是私有地址,而通過路由器轉換爲公網IP這樣就不會增加成本了。
這種方式入站,出站的數據包被分別處理,由於在服務器池中的節點主機應答客戶端時,需要使用羣集的IP地址應答,所以還需要在各個節點中的lo網卡中配置一個虛擬網卡,並且子網掩碼爲32位。
2、配置負載調度器。
現在的網絡環境,與前面的網絡環境不同,也就是另外一個實驗環境,我們重新開始搭建。
1)加載ip_vs模塊並安裝ipvsadm工具
[root@centos1 ~]# modprobe ip_vs
[root@centos1 ~]# yum -y install ipvsadm
2)配置羣集IP地址(配置在eth0的虛擬接口eth0:0)
[root@centos1 ~]# cd /etc/sysconfig/network-scripts/
[root@centos1 network-scripts]# cp ifcfg-eth0 ifcfg-eth0:0
[root@centos1 network-scripts]# vim ifcfg-eth0:0
DEVICE=eth0:0
TYPE=Ethernet
UUID=342c9eb9-6125-43a7-94be-729c5cb1d96d
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=none
IPADDR=172.16.16.172
NETMASK=255.255.255.0
[root@centos1 ~]# service network restart
3)調整內核參數
對於DR羣集模式來說,由於LVS負載調度器和各個節點公用一個VIP,應該關閉內核的重定向功能也就是管理ICMP重定向報文
[root@centos1 ~]# vim /etc/sysctl.conf
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
註釋:net.ipv4.tcp_syncookies = 1
當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少量SYN×××。
net.ipv4.ip_forward = 1
啓用IP轉發功能,做NAT服務或者路由時纔會用到。
net.ipv4.icmp_echo_ignore_broadcasts = 1
忽略廣播icmp包
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
惡意用戶可以使用IP重定向來修改遠程主機中的路由表,在設計良好的網絡中,末端的重定向設置是不需要的,發送和接受重定向信息包都要關閉。
net.ipv4.conf.all.accept_source_route = 0
禁用icmp源路由選項
net.ipv4.conf.all.forwarding = 0
不轉發源路由幀,如果做NAT建議開啓。
net.ipv4.tcp_max_syn_backlog = 8192
定義backlog隊列容納的最大半連接數,如果配置高可以設置的更高
net.ipv4.tcp_synack_retries = 3
net.ipv4.tcp_syn_retries = 3
定義SYN連接的重試次數,默認是5,降低這個值以提高系統性能。
net.ipv4.tcp_fin_timeout = 10
決定了它保持在FIN-WAIT-2狀態的時間,默認是60,降低這個值以提高系統性能。
net.ipv4.tcp_rfc1337 = 1
啓用後,內核將丟棄那些發往time-wait狀態TCP套接字的RST包。卻省爲0。
[root@centos1 ~]# sysctl -p
4)配置負載平衡策略
[root@centos1 ~]# service ipvsadm stop //清除原有策略
[root@centos1 ~]# ipvsadm -A -t 172.16.16.172:80 -s wrr
[root@centos1 ~]# ipvsadm -a -t172.16.16.172:80 -r 172.16.16.177:80 -g -w 1
[root@centos1 ~]# ipvsadm -a -t 172.16.16.172:80 -r 172.16.16.178:80 -g -w 1
[root@centos1 ~]# service ipvsadm save
5)配置防火牆
[root@centos1 ~]# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
2、配置服務器節點
使用DR模式時,節點服務器也需要配置VIP地址,因爲客戶端請求的是羣集IP地址,目標MAC地址是LVS的,節點服務器迴應時應該以羣集IP迴應,否則客戶端不能成功接收。還需要調整內核的ARP響應參數阻止更新VIP的MAC地址,因爲客戶端在發送ARP請求的時候IP地址是羣集地址,這是所有的節點都配置了VIP這時客戶端的ARP緩存內就會出現多條重複的IP單絲對用的MAC地址確不相同,這回導致客戶端無法正確找到調度器。
1)172.16.16.177 配置虛擬VIP地址 (多臺幾點之間配置一樣)
在每個節點上,同樣需要配置VIP地址172.16.16.172,但此地址只作爲發送web響應的源地址,並不需要監聽客戶端的訪問請求,因此使用lo:0來承載虛擬VIP地址,並添加一條路由記錄,將訪問VIP的數據包限制在本機,避免通信紊亂
[root@centos4 ~]# cd /etc/sysconfig/network-scripts/
[root@centos4 network-scripts]# cp ifcfg-lo ifcfg-lo:0
[root@centos4 network-scripts]# vim ifcfg-lo:0
DEVICE=lo:0
IPADDR=172.16.16.172
NETMASK=255.255.255.255
ONBOOT=yes
[root@centos4 network-scripts]# ifdown lo
[root@centos4 network-scripts]# ifup lo
[root@centos4 network-scripts]# cd
[root@centos4 ~]# vim /etc/rc.local
/sbin/route add -host 172.16.16.172 dev lo:0
[root@centos4 ~]# route add -host 172.16.16.172 dev eth0 //臨時生效
2)調整內核參數
[root@centos4 ~]# vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
[root@centos4 ~]# sysctl -p
以上配置爲忽略ARP更新請求解析其他網卡的MAC以及禁止lo網卡宣告自己的MAC地址
註釋:arp_ignore:定義對目標地址爲本地IP的ARP詢問不同的應答模式0
0 - (默認值): 迴應任何網絡接口上對任何本地IP地址的arp查詢請求
1 - 只回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求
2 -只回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求,且來訪IP必須在該網絡接口的子網段內
3 - 不迴應該網絡界面的arp請求,而只對設置的唯一和連接地址做出迴應
4-7 - 保留未使用
8 -不迴應所有(本地地址)的arp查詢
arp_announce:對網絡接口上,本地IP地址的發出的,ARP迴應,作出相應級別的限制: 確定不同程度的限制,宣佈對來自本地源IP地址發出Arp請求的接口
0 - (默認) 在任意網絡接口(eth0,eth1,lo)上的任何本地地址
1 -儘量避免不在該網絡接口子網段的本地地址做出arp迴應. 當發起ARP請求的源IP地址是被設置應該經由路由達到此網絡接口的時候很有用.此時會檢查來訪IP是否爲所有接口上的子網段內ip之一.如果改來訪IP不屬於各個網絡接口上的子網段內,那麼將採用級別2的方式來進行處理.
2 - 對查詢目標使用最適當的本地地址.在此模式下將忽略這個IP數據包的源地址並嘗試選擇與能與該地址通信的本地地址.首要是選擇所有的網絡接口的子網中外出訪問子網中包含該目標IP地址的本地地址. 如果沒有合適的地址被發現,將選擇當前的發送網絡接口或其他的有可能接受到該ARP迴應的網絡接口來進行發送.
3)配置防火牆
[root@centos4 ~]# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
4)啓動HTTP服務
[root@centos4 ~]# service httpd start
3、建立共享存儲
[root@centos2 ~]# mkdir /opt/wwwroot
[root@centos2 ~]# vim /etc/exports
/opt/wwwroot 192.168.1.0/24(rw,sync,no_root_squash)
[root@centos2 ~]# service rpcbind restart
[root@centos2 ~]# service nfs start
vim /etc/sysconfig/nfs
將IPTABLES關閉,或者通過修改內核的方式建立防火牆規則,這裏我就直接將防火牆關閉。
[root@centos2 ~]# echo "aaaaaaa" >/opt/wwwroot/index.html
4、服務器節點掛在共享存儲到/var/www/html
[root@centos4 ~]# mount 192.168.1.250:/opt/wwwroot /var/www/html/
5、測試LVS
圖8
可以通過ipvsadm -lnc 查看分配的情況。
今天我們通過以上實驗發現了兩個問題,一個是調度器的單點故障,第二個就是當摸一個服務器節點出現故障時,調度器並不知道,還會分配任務給出現故障的服務器節點,這樣就會出現客戶端訪問失敗的情況,爲了避免這樣的情況發生,我們在下一次會學習使用keepalived實現調度器的雙擊熱備並且動態添加和刪除服務器節點。實現服務器節點的健康檢查。