LVS簡介
LVS(Linux Virtual Server),即Linux上虛擬的服務器集羣系統。其實LVS就是一個前端的負載調度器,它在軟件層次上實現了負載均衡,將接收到的請求均衡地轉移至多個不同的服務器上運行,用較低的成本實現了將一組服務器構建成高性能、高可用的服務器集羣。
LVS由兩部分組成ipvsadm和ipvs,ipvsadm工作於用戶空間,用於編寫集羣服務。ipvs工作於內核空間。ipvsadm編寫的集羣服務交由ipvs來具體實現。ipvs是基於netfilter實現的,它工作在input鏈上,當有報文經過input鏈時,ipvs查看其目標IP及請求的端口,若請求的是集羣服務,則通過指定的算法在服務器集羣中選擇一臺服務器,然後將報文發送給該服務器。
lvs的術語
Director Server # 調度器,即實現負載均衡的地方
Real Server # 正真能夠提供服務的服務器
VIP # Director上用於接收用戶請求的IP
DIP # Director上用於和Real Server交互的IP
RIP # Real Server上的IP
CIP # 客戶端IP
ipvsadm配置集羣服務
在用ipvsadm配置Director之前,需要先安裝ipvsadm。
語法:ipvsadm [options] -t|-u|-f service-address [options]
定義一個集羣服務:
ipvsadm -A|-E -t|-u|-f service-address [-s scheduler]
-A # 添加一個集羣服務
-E # 修改一個集羣服務
-s # 指定調度用的算法
-t|-u # service-address爲VIP:port
-f # service-address爲防火牆標記
向集羣服務中添加RS:
ipvsadm -a|e -t|u|f service-address -r server-address [options]
-a # 添加一個RS
-e # 修改一個RS
service-address # 已定義過的集羣服務
-r # 指定RS地址
-w,weight # 指定該real server的權重,這個設爲0表示禁用該realserver。
指定LVS的類型:
-g,--gatewaying # direct routing(DR模型,默認選項)
-m,--masquerading # masquerading(NAT模型)
-i,--ipip #ipip encapsulation(tun類型)
scheduler(LVS算法)
ipvs在調度時所使用的算法,添加集羣服務時通過“-s”指定。一個內置了10種算法(這個由內核中的ipvs代碼提供)
[root@CentOS-6 ~]# grep -i 'VS' /boot/config-version
/boot/config-version爲當前操作系統內核編譯時使用的配置文件,使用這條語句可查看內核當中ipvs的代碼支持哪些算法。
靜態方法:僅根據算法本身進行調度,不考慮後端服務器的負載
rr # round robin,輪詢
wrr # weighted round robin, 加權輪詢(根據添加RS時指定的權重進行調度,權重越大,調度
# 的次數越多)
sh # source hashing,表示來源於同一個CIP的請求將始終被定向至同一個RS(SESSION保持)
dh: # destination hashing,只要訪問同一個地址,就調度到同一個real server
動態方法:根據算法及各RS當前的負載狀況進行調度
lc # least connection,調度給當前連接數最少的RS
Overhead=Active*256+Inactive # Active:活動狀態連接數,Inactive:非活動狀態連接數。 # 這個值越小就挑哪個
wlc # weighted lc,默認使用這種算法,這個更容易保證調度公平
Overhead=(Active*256+Inactive)/weight #weight:權重
sed # shortest expection delay
Overhead=(Active+1)*256/weight
nq # Never Queue,現將請求分配給所有的空閒服務器,沒有空閒的服務器了之後,再根據sed
# 算法進行調度
lblc # Locality-Based Least Connection
#適用於後端服務器爲緩存服務器的場景,動態的DH,很少用到
lblcr # Replicated lblc #帶複製功能的lblc
LVS的模型介紹
LVS有4種模型:NAT,DR,tun,fullnat。常用的是前兩者。
NAT模型
工作原理:Director的DIP和各RIP必須得在同一個網段中且應該使用私有IP,各個Real Server的網關必須指向Director的RIP。Director在接收到客戶端請求報文(目標地址VIP,源地址CIP)後,根據算法從後面的集羣中選出一臺Real Server,將報文的目標IP改成這臺Real Server的RIP,然後發送。Read Server在構建響應報文時,源IP爲自己的RIP,目標爲CIP,發送至Director,Director再將報文的源IP改成VIP發送給客戶端。
使用NAT模型的缺點在於請求報文和響應報文都要經過Director,在高負載額場景中,Director很容易成爲系統性能的瓶頸。
實現方式
Direcor:
vip:192.168.1.118
dip:192.168.2.8
Real Server:
192.168.2.5
192.168.2.6
192.168.2.7
Real Server上:
每個Real server上都配置好默認路由,指向dip
[root@node1 ~]# ip route add default via 192.168.2.8
Direcor上:
集羣服務配置:
[root@vm1 ~]# ipvsadm -A -t 192.168.1.118:80 -s rr [root@vm1 ~]# ipvsadm -a -t 192.168.1.118:80 -r 192.168.2.5 -m [root@vm1 ~]# ipvsadm -a -t 192.168.1.118:80 -r 192.168.2.6 -m [root@vm1 ~]# ipvsadm -a -t 192.168.1.118:80 -r 192.168.2.7 -m
確保路由轉發功能打開:
[root@vm1 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
DR模型
DR模型在實現過程中,VIP、DIP、RIP必須在同一個物理網絡中,中間不能有路由器拆分包信息。
DR模型的工作原理與NAT模型的區別在於Director在收到請求報文後沒有修改目標地址,而是僅修改了報文的目標MAC地址(爲某一臺Real Server的MAC地址),直接發送給Real Server。Real Server爲了接收這個目標地址爲VIP的報文,需要在本地配置一個VIP,這個VIP地址一般配置在lo接口的別名(lo:0)上,這個VIP地址不向外通告,也不響應ARP請求。當發送響應報文時,響應報文不會經過Director,而是直接發往客戶端。所以響應報文的目標IP爲CIP,源IP爲VIP。爲了確保源IP爲VIP,需要讓報文先經過lo:0接口,再由eth0轉發出去。
實現方式
路由器1:
eth0:192.168.1.118
eth1:192.168.2.8
路由器2:
eth0:192.168.1.119
eth1:192.168.2.9
Direcor:
vip: eth0:0,192.168.2.100
dip: eth0,192.168.2.7
Real Server:
192.168.2.5
192.168.2.6
Direcor上:
添加vip
[root@node3 ~]# ip addr add 192.168.2.100/24 label eth0:0 dev eth0 [root@node3 ~]# ip route add 192.168.2.100 dev eth0:0
Real Server上:
在每個Real Server執行(這些可以寫成腳本)
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
arp_ignore # 是否響應ARP地址請求,默認0。
0 # 回覆本機的所有ip地址(不管地址在哪裏)。
1 # 請求從哪個網卡接口進來,就響應該接口上的地址。
arp_announce # 限制本機如何通告本地地址,默認0。
通告級別:
0 # 通高所有本機ip地址。
1 # 儘量使用2這個級別,但有時候會有意外。
2 # 僅通知最佳的本地地址進行通告。
# 例如某個IP地址處在某個網段,那麼僅用這個接口的地址通告該網段。
在lo上添加vip
[root@node3 ~]# ip addr add 192.168.2.100/32 label lo:0 brd 192.168.2.100 dev lo [root@node3 ~]# ip route add 192.168.2.100 dev lo:0
在Direcor上:
添加集羣服務
[root@node3 ~]# ipvsadm -A -t 192.168.2.100:80 -s rr [root@node3 ~]# ipvsadm -a -t 192.168.2.100:80 -r 192.168.2.5 -g [root@node3 ~]# ipvsadm -a -t 192.168.2.100:80 -r 192.168.2.6 -g [root@node3 ~]# 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.2.100:80 rr -> 192.168.2.5:80 Route 1 0 0 -> 192.168.2.6:80 Route 1 0 0
最後Director上不要忘了網關的配置。
基於LVS-DR模型部署discuz
實驗環境:
路由器:
eth0:192.168.1.118
eth1:192.168.2.8
Direcor:
vip: eth0:0,192.168.2.100
dip: eth0,192.168.2.7
Real Server:
192.168.2.5
192.168.2.6
PHP服務器:192.168.2.10
NFS:192.168.2.10
MySQL服務器:192.168.2.3
LVS的環境的實現與上述DR模型中的實現方式一致。
在NFS服務器上創建共享目錄
[root@www ~]# mkdir /httpd_dir [root@www ~]# vim /etc/exports /httpd_dir 192.168.2.0/24(rw,no_root_squash) [root@www ~]# service nfs status
Real Server上掛載共享目錄
[root@node1 ~]# showmount -e 192.168.2.10 Export list for 192.168.2.10: /httpd_dir 192.168.2.0/24 [root@node1 ~]# mount -t nfs 192.168.2.10:/httpd_dir /httpd_dir
配置httpd:
[root@node1 httpd]# vim httpd.conf #DocumentRoot "/httpd" #使用虛擬主機需要註釋這一項 ... LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so .... <IfModule dir_module> DirectoryIndex index.php index.html </IfModule> ...... AddType application/x-httpd-php .php #支持識別php格式的頁面 AddType application/x-httpd-php-source .phps ...... Include /etc/httpd/extra/httpd-vhosts.conf
虛擬主機:
<VirtualHost *:80> ServerAdmin [email protected] DocumentRoot "/httpd_dir" ProxyRequests Off ProxyPassMatch ^/(.*\.php)$ fcgi://192.168.2.10:9000/httpd_dir/$1 <Directory "/httpd_dir"> Options none AllowOverride none Require all granted </Directory> </VirtualHost>
配置完成之後,將配置文件同步至其他各節點。
在NFS服務器上部署discuz
[root@www ~]# unzip Discuz_7.2_FULL_SC_GBK.zip [root@www ~]# mv upload/* /httpd_dir/ [root@www ~]# cd /httpd_dir/ [root@www httpd_dir]# chown -R nobody:nobody ./*
由於應用的需要在php的配置文件中將這一項打開
[root@www httpd_dir]# vim /etc/php.ini short_open_tag = On
在數據庫中創建數據庫和對應的用戶,然後授權
MariaDB [(none)]> create database discuz; Query OK, 1 row affected (0.02 sec) MariaDB [(none)]> grant all on discuz.* to discuz@'192.168.%.%' identified by 'discuz'; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> flush privileges; Query OK, 0 rows affected (0.00 sec)
最後打開http://192.168.2.100/install/index.php,安裝一下數據庫即可。
完成發帖.................^_^