LVS詳解及基於DR模型的案例

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,安裝一下數據庫即可。

完成發帖.................^_^




















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章