2018年7月23日課程 原

一、LVS-DR介紹

director分配請求到不同的real server。real server 處理請求後直接回應給用戶,這樣director負載均衡器僅處理客戶機與服務器的一半連接。負載均衡器僅處理一半的連接,避免了新的性能瓶頸,同樣增加了系統的可伸縮性。Director Routing採用的是物理層(修改MAC地址)技術,因此,所以服務器都必須在同一個物理網段。

·這種模式,需要一個公共的IP配置在分發器和所有的rs上,也就是vip

·跟TUN模式不同的是,它會把數據包的MAC地址修改爲rs的MAC地址

·rs接收到數據包後,會還原原始數據包,這樣目標ip爲vip,因爲所有的rs都配置了這個vip,所以它會認爲是它自己

LVS-DR模式工作原理:MAC地址轉換

假設每臺機子的ip與mac信息如下:

MAC地址轉換過程:

(1)客戶端(ip:192.168.10.201)向目標vip發出請求, Director接收。此時IP包頭部及數據幀頭信息如下:

(2)Director根據負載均衡算法選擇一臺active的RS(假設是192.168.10.101),並將此RIP所在網卡的mac地址作爲目標mac地址,發送到局域網裏。此時IP包頭部及數據幀頭信息如下:

(3)real server(192.168.10.101)在局域網中收到這個幀,拆開後發現目標IP(VIP)與本地匹配,於是處理這個報文,隨後重新封裝報文,發送到局域網。此時IP包及數據幀頭信息如下:

(4)如果client與LVS在同一網段,那麼clinet(192.168.10.201)將收到這個回覆報文。如果跨了網段,那麼這個報文通過gateway/路由通過Internet返回給用戶。 以上就是LVS-DR模式的原理。

二、LVS-DR模式搭建

lvs-dr模式網絡拓撲圖:

使用使用3臺機子,每臺機子都可以直接連接外網,每臺機子只有一塊網卡。每臺機子都通過配置網卡別名配一個vip

1、Director分發器配置

1、安裝ipvsadm、net-tools

因爲我的系統是最小化安裝的,沒有ifconfig命令,所以要安裝net-tools

[root@localhost ~]# yum install -t ipvsadm net-tools

2、編寫dr模式腳本,並執行

#!/bin/bash
#關閉路由端口轉發,其實就dr模式,開不開啓路由轉發都行
echo 0 > /proc/sys/net/ipv4/ip_forward
#相關變量
ipv=/usr/sbin/ipvsadm
vip=192.168.10.88
rs1=192.168.10.205
rs2=192.168.10.206
#通過網卡別名配置vip,也就是虛擬網卡
ifdown ens33 #先關閉網卡再開啓,是爲了清空已有的虛擬網卡設置
ifup ens33
ifconfig ens33:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip dev ens33:0
#設置規則
$ipv -C
$ipv -A -t $vip:80 -s wrr
$ipv -a -t $vip:80 -r $rs1:80 -g -w 1
$ipv -a -t $vip:80 -r $rs2:80 -g -w 1

參數:-g:表示dr模式,-w:權重

執行腳本:

[root@node5 ~]# sh lvs_dr_rs.sh

2、RS1、RS2配置

1、RS1、RS2安裝net-tools

# yum install -y net-tools

2、RS1、RS2安裝httpd服務

# yum install -y httpd

測試頁:

RS1:

[root@node5 ~]# echo "<h1> Real Server 1 :192.168.10.205 </h1>" > /var/www/html/index.html 

RS2:

[root@node1 ~]# echo "<h1> Real Server 2 :192.168.10.206 </h1>" > /var/www/html/index.html 

RS1、RS2開啓httpd服務,並清空防火牆規則

# systemctl restart httpd
# iptables -F

2、編寫dr腳本,並執行。

RS1、RS2都創建一個腳本:lvs_dr_rs.sh,腳本內容:

#!/bin/bash
vip=192.168.10.88
#把vip綁定在lo上,是爲了實現rs直接把結果返回給客戶端
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
#修改arp參數
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

因爲Director、Real Server都配置了相同的VIP(192.168.10.88),如果不關閉ARP轉發,則ip衝突了。

arp參數解釋:

 arp_ignore爲1:只回答目標ip地址是訪問本網絡接口(此處爲ens33)的ARP查詢請求。
 也就是說,arp_ignore設爲1,當別人的arp請求過來的時候,如果接收的網卡設備上面沒有這個ip,就不做出相應。默認爲0,只要這臺機子上任何一個網卡設備上面有這個ip,就響應arp請求,併發送mac地址。

 arp_announce(宣告)設爲2:對查詢目標使用最適當的本地地址。例如,如果在ens33接口上接收到了一個VIP的arp請求包,內核判斷這個VIP地址是不是跟ens33接口上的IP一樣。如果一樣,則回覆這個包;如果不一樣,就丟棄不迴應。

RS1、RS2執行腳本:

# sh lvs_dr_rs.sh

3、測試

瀏覽器打開vip:192.168.10.88

使用curl測試,但不能在director上執行curl測試:

在192.168.10.207機子上測試:

[root@localhost ~]# curl 192.168.10.88
<h1> Real Server 1 :192.168.10.205 </h1>
[root@localhost ~]# curl 192.168.10.88
<h1> Real Server 2 :192.168.10.206 </h1>
[root@localhost ~]# curl 192.168.10.88
<h1> Real Server 1 :192.168.10.205 </h1>
[root@localhost ~]# curl 192.168.10.88
<h1> Real Server 2 :192.168.10.206 </h1>
[root@localhost ~]# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:24:42:91  
          inet addr:192.168.10.207  Bcast:192.168.10.255  Mask:255.255.255.0

OK。lvs-dr搭建成功。

4、ab壓力測試

在192.168.10.207機子上測試。

1、安裝httpd-tools工具

[root@localhost ~]# yum install -y httpd-tools

2、使用ab命令測試。

語法:ab -n  數字 -c 數字  http://連接

參數解釋:
-n:requests Number of requests to perform,在測試會話中所執行的請求總個數。默認時,僅執行一個請求
-c:concurrency Number of multiple requests to make,一次產生的請求個數。默認是,一次一個。

測試:同時處理1000個請求,一次要執行1000個併發請求。

[root@localhost ~]# ab -n 1000 -c 1000 http://192.168.10.88/index.html
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.10.88 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
apr_socket_recv: Connection reset by peer (104)
Total of 742 requests completed

失敗,分發器、RS1、RS2均執行一下命令:

# echo "net.ipv4.tcp_syncookies = 0" >> /usr/lib/sysctl.d/50-default.conf
# sysctl -p

 

重新測試:

[root@localhost ~]# ab -n 1000 -c 1000 http://192.168.10.88/index.html
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.10.88 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.4.6
Server Hostname:        192.168.10.88
Server Port:            80

Document Path:          /index.html
Document Length:        41 bytes

Concurrency Level:      1000
Time taken for tests:   3.394 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      301301 bytes
HTML transferred:       41041 bytes
Requests per second:    294.67 [#/sec] (mean)
Time per request:       3393.581 [ms] (mean)
Time per request:       3.394 [ms] (mean, across all concurrent requests)
Transfer rate:          86.70 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1   99  12.8     98     124
Processing:    31 1317 1313.0    127    3250
Waiting:        2 1311 1317.0    121    3249
Total:        113 1416 1314.8    237    3351

Percentage of the requests served within a certain time (ms)
  50%    237
  66%   2160
  75%   2169
  80%   3150
  90%   3321
  95%   3339
  98%   3347
  99%   3350
 100%   3351 (longest request)
[root@localhost ~]# 

測試結果解釋:

 

Server Software:        Apache/2.4.6       #被測試的httpd版本
Server Hostname:        192.168.10.88    #服務器主機名
Server Port:            80                                #服務器端口

Document Path:          /index.html         #測試的頁面文檔
Document Length:        41 bytes             # 文檔大小

Concurrency Level:      1000                      #併發數
Time taken for tests:   3.394 seconds    #整個測試的耗時
Complete requests:      1000                    #完成的請求數量
Failed requests:        0                               #失敗的請求數量    
Write errors:           0
Total transferred:      301301 bytes       
#整個測試中總傳輸字節數
HTML transferred:       41041 bytes       #整個場景中HTML內容傳輸量。
Requests per second:    294.67 [#/sec] (mean)     #每秒處理請求數,相當於服務器中的每秒事務數,後面的括號的mean表示這是一個平均值。
Time per request:       3393.581 [ms] (mean)      #平均請求響應時間,mean表示這是一個平均值。
Time per request:       3.394 [ms] (mean, across all concurrent requests)   #每個請求的時間,1.080[毫秒](意思是說,在所有的併發請求),每個請求實際運行時間的平均值。由於對於併發請求,cpu實際上並不是同時處理的,而是按照每個請求獲得的時間片逐個輪轉處理的,所以基本上第一個Time per  request時間約等於第二個Time per  request時間乘以併發請求數。
Transfer rate:          86.70 [Kbytes/sec] received     #傳輸速率,平均每秒網絡上的流量,可以幫助排除是否存在網絡流量過大導致響應時間延長的問題。

Connection Times (ms)    #連接時間
              min  mean[+/-sd] median   max
Connect:        1   99  12.8     98     124
Processing:    31 1317 1313.0    127    3250
Waiting:        2 1311 1317.0    121    3249
Total:        113 1416 1314.8    237    3351

Percentage of the requests served within a certain time (ms)   #在一定的時間內提供服務的請求的百分比(毫秒)
  50%    237
  66%   2160
  75%   2169
  80%   3150
  90%   3321
  95%   3339
  98%   3347
  99%   3350
 100%   3351 (longest request)

三、keepalived+LVS搭建

keepalived本身具有負載均衡功能,內置了ipvsadm的功能,因此不需要使用ipvsadm設置規則了。

這裏使用3臺機子:

1、還原實驗環境

由於前面已經做了DR模式,所以爲了有一個乾淨的實驗環境,把三臺機子還原快照。

2、director設置

1、安裝keepalived

[root@localhost ~]# yum install keepalived -y

2、配置keepalived

keepalived安裝目錄:/etc/keepalived/

[root@localhost ~]# cd /etc/keepalived/
[root@localhost keepalived]# mv keepalived.conf keepalived.conf.bak
[root@localhost keepalived]# grep -v "#" keepalived.conf.bak > keepalived.conf
[root@localhost keepalived]# vim keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER  #備用服務器爲BACKUP
    interface ens33 #綁定vip的網卡,這裏爲ens33
    virtual_router_id 51
    priority 100  #權重,備用服務器上的權重比MASTER的權重小,比如設爲90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.88 #設置vip
    }
}

virtual_server 192.168.10.88 80 {
    delay_loop 6 #每隔6每秒查詢real server的狀態
    lb_algo rr  #lvs算法,這裏爲rr:輪詢
    lb_kind DR  #lvs模式,DR模式
    persistence_timeout 50 #同一IP的連接50秒內被分配到同一臺real  server
    protocol TCP  #使用TCP協議

    real_server 192.168.10.205 80 {
        weight 100 #權重
        TCP_CHECK {
        connect_timeout 10 #10秒無響應超時
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
    real_server 192.168.10.206 80 {
        weight 100 #權重
        TCP_CHECK {
        connect_timeout 10 #10秒無響應超時
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
}

解釋:

! Configuration File for keepalived

global_defs {
   notification_email {
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER  #備用服務器爲BACKUP
    interface ens33 #綁定vip的網卡,這裏爲ens33
    virtual_router_id 51
    priority 100      #權重,備用服務器上的權重比MASTER的權重小,比如設爲90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111   #認證密鑰,默認1111,可使用 openssl rand -hex 6產生
    }
    virtual_ipaddress {
        192.168.10.88    #設置vip
    }
}

virtual_server 192.168.10.88 80 {
    delay_loop 6      #每隔6每秒查詢real server的狀態
    lb_algo rr           #lvs算法,這裏爲rr:輪詢
    lb_kind DR          #lvs模式,DR模式
    persistence_timeout 50         #同一IP的連接50秒內被分配到同一臺real  server
    protocol TCP    #使用TCP協議

    real_server 192.168.10.205 80 {
        weight 100   #權重
        TCP_CHECK {
        connect_timeout 10     #10秒無響應超時
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
    real_server 192.168.10.206 80 {
        weight 100     #權重
        TCP_CHECK {
        connect_timeout 10    #10秒無響應超時
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
}

3、清空防火牆,關閉selinux

這裏是臨時關閉selinux

[root@localhost ~]# iptables -F
[root@localhost ~]# setenforce 0
[root@localhost ~]# 

4、啓動keepalived

[root@localhost ~]# systemctl start keepalived

查看一下ip:

[root@localhost ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:55:10:a8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.200/24 brd 192.168.10.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.10.88/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::b3d1:90a4:26af:f468/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:55:10:b2 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]# 

OK,虛擬ip已經設置好了

5、查看ipvsadm的規則

要看規則,必須安裝ipvsadm 

[root@localhost ~]# yum install ipvsadm -y

查看規則:

[root@localhost ~]# 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.10.88:80 rr persistent 50

規則沒添加成功。RS1、RS2清空防火牆、關閉selinux之後,director重啓keepalived

[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# 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.10.88:80 rr persistent 50
  -> 192.168.10.205:80            Route   100    0          0         
  -> 192.168.10.206:80            Route   100    0          0         
[root@localhost ~]# 

OK,規則添加成功了。

3、RS1、RS2設置

1、RS1、RS2安裝httpd、創建測試頁參考前面的實驗

2、RS1、RS2清空防火牆、關閉selinux

3、RS1、RS2編寫腳本並執行

腳本名:lvs_dr_rs.sh,腳本內容如下:

#!/bin/bash
vip=192.168.10.88
#把vip綁定在lo上,是爲了實現rs直接把結果返回給客戶端
ifdown lo
ifup lo
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
#修改arp參數
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

RS1、RS2執行腳本:

# sh lvs_dr_rs.sh

4、測試

瀏覽器打開vip:192.168.10.88

curl測試:

因爲設置了:persistence_timeout 50    #同一IP的連接50秒內被分配到同一臺real  server

所以請求分配到同一rs。沒有輪詢效果,把persistence_timeout 50刪除,重啓keepalived,再請求:

OK。輪詢效果出來了

這裏keepalived之配置了MASTER,沒有配置BACKUP。

 

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