lvs_dr 負載均衡模式分析

1.前言

上一篇文章《lvs_nat 負載均衡模式及抓包分析》,已經對開源負載均衡軟件的 nat 模式進行了實驗和 tcpdump 數據包分析。經過分析,我們知道 lvs 的 nat 負載均衡模式,它的性能瓶頸在 lvs 調度器。因爲網絡上的客戶端請求連接和後端服務的響應數據都要經過 lvs 調度器,所以 lvs 調度器在大請求量的情況,就容易出現瓶頸。所以,在這篇文章,對 lvs 負載均衡的另一種架構 dr 模式進行分析,dr 模式它最大的特點就是,負載均衡集羣的後端服務響應,直接從後端服務發回客戶端,也就是說返回數據不需經過 lvs 調度器。大大減輕了集羣的調度器的負載。

2. lvs_dr 模式的架構圖

lvs_dr 負載均衡模式分析

說明: 圖中展示的是最簡單的 lvs_dr 模式架構,也是這篇博客的實驗環境。

3. arp 基礎知識掃盲

爲什麼要先了解arp 的知識呢?因爲,在lvs_dr 負載均衡模式中,realserver 和 lvs 調度器都配置了vip。客戶端需要和 lvs 的 vip 通信,所以,就要抑制realserver 對vip 的mac 地址的請求。具體會涉及到 arp_ignore 和 arp_announce 兩個參數的設置。注意在文章的後半段,我會再詳細講一下。

什麼是arp廣播?通俗講,就是在網絡中,根據ip地址找mac地址的協議,即ARP 協議。

3.1 舉一個例子:

主機A的IP地址爲192.168.1.1,MAC地址爲0A-11-22-33-44-01;
主機B的IP地址爲192.168.1.2,MAC地址爲0A-11-22-33-44-02;

當主機A要與主機B通信時:
第1步:根據主機A上的路由表內容,IP確定用於訪問主機B的轉發IP地址是192.168.1.2。然後A主機在自己的本地ARP緩存中檢查主機B的匹配MAC地址。
第2步:如果主機A在ARP緩存中沒有找到映射,它將詢問192.168.1.2的硬件地址,從而將ARP請求幀廣播到本地網絡上的所有主機。源主機A的IP地址和MAC地址都包括在ARP請求中。本地網絡上的每臺主機都接收到ARP請求並且檢查是否與自己的IP地址匹配。如果主機發現請求的IP地址與自己的IP地址不匹配,它將丟棄ARP請求。
第3步:主機B確定ARP請求中的IP地址與自己的IP地址匹配,則將主機A的IP地址和MAC地址映射添加到本地ARP緩存中。
第4步:主機B將包含其MAC地址的ARP回覆消息直接發送回主機A。
第5步:當主機A收到從主機B發來的ARP回覆消息時,會用主機B的IP和MAC地址映射更新ARP緩存。本機緩存是有生存期的,生存期結束後,將再次重複上面的過程。主機B的MAC地址一旦確定,主機A就能向主機B發送IP通信了。

4. 準備工作——服務器的ip分配

4.1 lvs

          eth0:      192.168.188.108
          eth0:2    192.168.188.120     (vip)
          mac:       00:0c:29:50:d5:63 

4.2 realeserver

第一臺(cenvm71):
     eno16777736 :      192.168.188.107
     mac :                     00:0c:29:e4:4d:1f
     lo:0                        192.168.188.120    (vip)

第二臺(cenvm72):
       eth0:                  192.168.188.110
       mac:                  00:0c:29:2c:a5:a0
       lo:0                     192.168.188.120      (vip)

4.3 在兩臺 rs 主機安裝nginx

yum install  -y  nginx

安裝完nginx 服務後,最好將nginx 的默認html 文件修改一下輸出內容,讓它們能夠區分就可以了。

5. 搭建過程

5.1 DR 安裝ipvsadm 和配置 lvs_dr.sh 文件

安裝ipvsadm 軟件:
yum   install   -y   ipvsadm 

配置文件:
[root 18:40:39 @CentOS3 sbin] cat /usr/local/sbin/lvs_dr.sh 
#! /bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
ipv=/sbin/ipvsadm
vip=192.168.188.120
rs1=192.168.188.107
rs2=192.168.188.110
#注意這裏的網卡名字
ifdown eth0
ifup eth0
ifconfig eth0:2 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip dev eth0:2
$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

5.2 realeserver 配置 lvs_rs.sh 文件

[root@cenvm72 network-scripts]# cat /usr/local/sbin/lvs_rs.sh 
#/bin/bash
vip=192.168.188.120
#把vip綁定在lo上,是爲了實現rs直接把結果返回給客戶端
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
#以下操作爲更改arp內核參數,目的是爲了讓rs順利發送mac地址給客戶端
#參考文檔www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

兩臺realeserver 主機的 lvs_rs.sh 配置文件都一樣

6. 測試過程

6.1 啓動 lvs

現在 rs1 和 rs2 上運行 lvs_rs.sh 腳本,啓動nginx

/bin/bash    /usr/local/sbin/lvs_rs.sh

systemctl   start   nginx

然後,在 lvs 上運行lvs_dr.sh 腳本,啓動nginx

/bin/bash    /usr/local/sbin/lvs_dr.sh

systemctl    start   nginx

在 lvs 查看:

[root 18:58:10 @CentOS3 sbin] ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.188.120:80 wrr
  -> 192.168.188.107:80           Route   1      0          0         
  -> 192.168.188.110:80           Route   1      0          0     

說明lvs 功能已經啓動

6.2 lvs dr 模式請求過程

整個請求過程如下:

client在發起請求之前,會發一個arp廣播的包,在網絡中找“誰是vip”,由於所有的服務器,lvs和rs都有vip,爲了讓client的請求送到lvs上,所以必須讓rs不能響應client發出的arp請求,(這也是爲什麼要禁止rs上arp的請求和響應)下面就是lvs轉發的事情了:

  1. client向目標vip發送請求,lvs接收;此時ip包和數據信息如下:
src mac dst mac src ip dst ip
00:0c:29:f3:1f:de 00:0c:29:50:d5:63 192.168.188.111 192.168.188.120
  1. lvs根據負載均衡的算法,選擇一臺realserver,然後把realserver1的mac地址作爲目的mac地址,發送到局域網中
src mac dst mac src ip dst ip
00:0c:29:50:d5:63 00:0c:29:e4:4d:1f 192.168.188.111 192.168.188.120

3 . realserver1在局域網中收到這個請求以後,發現目的ip和本地匹配,於是進行處理,處理完成以後,直接把源ip和目的ip直接對調,然後經過網關直接返回給用戶;

src mac dst mac src ip dst ip
00:0c:29:e4:4d:1f 00:0c:29:f3:1f:de 192.168.188.120 192.168.188.111

6.3 抓包分析驗證

  1. lvs 轉發到 realeserver

lvs_dr 負載均衡模式分析

從抓包中可以看到,客戶端發送請求給 lvs,lvs 馬上就會將請求轉發給後端的 rs2 (mac 地址: 00:0c:29:2c:a5:a0);

  1. realserver 直接會應客戶端數據
    lvs_dr 負載均衡模式分析
    從抓到的數據包分析,rs2 處理請求後,直接就把數據發回給客戶端了。源ip 是 vip,目標ip 是客戶端的ip。

    7. 重要的補充,關於arp 抑制

    lvs dr 模式中,lvs 和 rs 處於同一個網絡中,而且他們都配置相同的 vip。所以,當客戶端要向vip 發送網絡請求的時候,它會先在整個網絡廣播一條 arp 請求,詢問 vip 對應的mac 地址是什麼。arp 廣播有可能被lvs 響應,也有可能被realeserver 響應。如果這條請求 vip 的廣播被realeserver 服務器響應了,那麼客戶端的 arp 緩存表就記錄了vip 的mac 地址是realserver 的了。這樣會導致客戶端直接可以將數據請求發送到realserser ,lvs 的負載均衡作用就完全失效,其他的realserver 服務器也不會被請求。

    由於存在以上的問題,lvs dr 模式的架構中,需要將realserver 的arp 協議響應和宣告功能進行限制。具體來說就是在 rs 裏的 lvs_rs.sh 配置腳本的以下幾條操作:

    echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
    echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
    echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
    echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

    說明:

    7.1 arp_ignore =1

    作用就是,限制rs 對arp 廣播的響應。當 arp 請求的目的 ip 是本機的網絡入口設備的ip 時才響應。所以,當arp_ignore設爲1後,rs 對網絡中詢問vip 的 arp 廣播包都不再響應。因爲rs 的vip 設置在lo:0 虛擬網卡上,不是rs這臺機器的網絡流入設備。

    7.2 arp_announce = 2

    作用就是,限制rs 在對外宣告arp 廣播時所使用的源ip 地址。因爲,rs 要直接返回客戶的請求數據。我們從本文的第6節抓包分析裏,就知道rs 需要知道客戶機的mac地址,數據包才能發送到網絡中,且能準確找到客戶機的網卡。
    rs 在廣播arp 請求時,默認如果arp_announce=0時,發出請求的ip是什麼,arp 請求裏的源ip就應該是什麼。即如果arp_announce=0,那麼rs 的arp 廣播的源ip 就會是vip。當rs 發出這個源ip是vip ,源mac地址是 eth0 的請求包後,客戶機就會更新自己的arp 緩存表裏vip 的mac 地址,這樣之前記錄的lvs 的mac 地址就失效了。

    所以,需要將 arp_announce設置爲2。這樣,rs 發出arp 廣播請求查詢客戶機的mac地址時,它的arp 報文裏使用的源ip 就會選擇出口設備,也就是eth0 的mac 地址。當客戶機收到rs 的這個arp 請求時,就會迴應自己mac 地址。這樣,客戶機也不會更新自己arp 緩存表裏的vip 的mac地址。

    arp 協議有一個特點,它不會記住自己詢問過的ip地址和mac主機。所以,當有接收到新的arp廣播請求,如果發現有新的mac 地址,他就會更新。而不會驗證發送方是不是自己曾經詢問過的ip 。這個缺陷也引起了arp ***,就是我們常說的arp 欺騙。有些中間代理機器,不斷地發arp 請求,讓你的機器arp 緩存表裏的mac 地址混亂。

    8. 總結

    在lvs dr 模式中,通過抓包理解請求發送的流轉方向,清晰地理解爲什麼lvs 調度器不會成爲網絡性能的瓶頸。在理解arp 抑制時,理解arp_ignore 和 arp_announce 兩個參數的作用,最爲重要。

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