Linux核心引數之arp_ignore和arp_announce

語言: CN / TW / HK

arp_ignore和arp_announce引數都和ARP協議相關,主要用於控制系統返回arp響應和傳送arp請求時的動作。這兩個引數很重要,特別是在LVS的DR場景下,它們的配置直接影響到DR轉發是否正常。

一、arp_ignore 和 arp_announce 介紹

1. arp_ignore

arp_ignore的作用是控制系統在收到外部的arp請求時,是否要返回arp響應。
arp_ignore引數常用的取值主要有 0、1、2、3-8 較少用到:
0:響應任意網絡卡上接收到的對本機IP地址的arp請求(包括環回網絡卡上的地址),而不管該目的IP是否在接收網絡卡上。
1:只響應目的IP地址為接收網絡卡上的本地地址的arp請求。
2:只響應目的IP地址為接收網絡卡上的本地地址的arp請求,並且arp請求的源IP必須和接收網絡卡同網段。
3:如果ARP請求資料包所請求的IP地址對應的本地地址其作用域(scope)為主機(host),則不迴應ARP響應資料包,如果作用域為全域性(global)或鏈路(link),則迴應ARP響應資料包。
4~7:保留未使用
8:不迴應所有的arp請求

/etc/sysctl.conf 檔案中包含 all 和 eth/lo(具體網絡卡)的 arp_ignore 引數,取其中較大的值生效。

2. arp_announce

arp_announce的作用是控制系統在對外發送arp請求時,如何選擇arp請求資料包的源IP地址。 arp_announce引數常用的取值有0,1,2。
0:允許使用任意網絡卡上的IP地址作為arp請求的源IP,通常就是使用資料包a的源IP。
1:儘量避免使用不屬於該傳送網絡卡子網的本地地址作為傳送arp請求的源IP地址。
2:忽略IP資料包的源IP地址,選擇該傳送網絡卡上最合適的本地地址作為arp請求的源IP地址。

sysctl.conf中包含all和eth/lo(具體網絡卡)的arp_ignore引數,取其中較大的值生效。

二、arp_ignore和arp_announce引數示例

1. arp_ignore

若 arp_ignore = 0,eth1網絡卡上收到目的IP為環回網絡卡IP的arp請求,但是eth1也會返回arp響應,把自己的mac地址告訴對端。 image.png \ \ \ \ \ 若 arp_ignore = 1,eth1網絡卡上收到目的IP為環回網絡卡IP的arp請求,發現請求的IP不是自己網絡卡上的IP,不會回arp響應。 image.png

2. arp_announce

若 arp_announce = 0,系統要傳送的IP包源地址為eth1的地址,IP包目的地址根據路由表查詢判斷需要從eth2網絡卡發出,這時會先從eth2網絡卡發起一個arp請求,用於獲取目的IP地址的MAC地址。該arp請求的源MAC自然是eth2網絡卡的MAC地址,但是源IP地址會選擇eth1網絡卡的地址。

image.png \ \ \ \ \ 若 arp_announce = 2,eth2網絡卡發起arp請求時,源IP地址會選擇eth2網絡卡自身的IP地址。 image.png

三、arp_ignore 和 arp_announce 引數在LVS DR 模式下的作用

1. arp_ignore

因為DR模式下,每個真實伺服器節點都要在環回網絡卡上繫結虛擬服務IP。這時候,如果客戶端對於虛擬服務IP的arp請求廣播到了各個真實伺服器節點,如果arp_ignore引數配置為0,則各個真實伺服器節點都會響應該arp請求,此時客戶端就無法正確獲取LVS節點上正確的虛擬服務IP所在網絡卡的MAC地址。假如某個真實伺服器節點A的網絡卡eth1響應了該arp請求,客戶端把A節點的eth1網絡卡的MAC地址誤認為是LVS節點的虛擬服務IP所在網絡卡的MAC,從而將業務請求訊息直接發到了A節點的eth1網絡卡。這時候雖然因為A節點在環回網絡卡上也綁定了虛擬服務IP,所以A節點也能正常處理請求,業務暫時不會受到影響。但時此時由於客戶端請求沒有發到LVS的虛擬服務IP上,所以LVS的負載均衡能力沒有生效。造成的後果就是,A節點一直在單節點執行,業務量過大時可能會出現效能瓶頸。

所以DR模式下要求arp_ignore引數要求配置為1。

2. arp_announce

每個機器或者交換機中都有一張arp表,該表用於儲存對端通訊節點IP地址和MAC地址的對應關係。當收到一個未知IP地址的arp請求,就會再本機的arp表中新增對端的IP和MAC記錄;當收到一個已知IP地址(arp表中已有記錄的地址)的arp請求,則會根據arp請求中的源MAC重新整理自己的arp表。

如果arp_announce引數配置為0,則網絡卡在傳送arp請求時,可能選擇的源IP地址並不是該網絡卡自身的IP地址,這時候收到該arp請求的其他節點或者交換機上的arp表中記錄的該網絡卡IP和MAC的對應關係就不正確,可能會引發一些未知的網路問題,存在安全隱患。

例如: HOST上有多個網絡卡,卻在不同一網段,例如 eth0:net0    eth1:net1    eth2:net2 ..... ,這時 如果 net0 網段的主機 發起ARP請求,那麼HOST 會把 eth0,eth1,eth2... 這些在HOST的網絡卡裝置的 IP 與MAC 都發給 net0 裡的請求端,但是 請求端 拿到了3個 裝置的IP與MAC (eth0:IP MAC , eth1:IP MAC  eth2 : IP MAC)  以為這3個 IP 都能通訊,而實際上 ,只有net0 內的eth0 網絡卡給他的IP和MAC 才能通訊 , 而 eth1,eth2 給的IP與MAC 對於 請求端來說 是沒有意義。

所以DR模式下要求arp_announce引數要求配置為2。

四、arp_ignore 和 arp_announce引數的配置方法

arp_ignore和arp_announce引數分別有all,default,lo,eth1,eth2...等對應不同網絡卡的具體引數。當all和具體網絡卡的引數值不一致時,取較大值生效。

一般只需修改all和某個具體網絡卡的引數即可(取決於你需要修改哪個網絡卡)。下面以修改lo網絡卡為例:

方式1. 修改/etc/sysctl.conf檔案,然後sysctl -p重新整理到記憶體。

net.ipv4.conf.all.arp_ignore=1

net.ipv4.conf.lo.arp_ignore=1

net.ipv4.conf.all.arp_announce=2

net.ipv4.conf.lo.arp_announce=2

方式2. 使用sysctl -w直接寫入記憶體:

sysctl -w net.ipv4.conf.all.arp_ignore=1

sysctl -w net.ipv4.conf.lo.arp_ignore=1

sysctl -w net.ipv4.conf.all.arp_announce=2

sysctl -w net.ipv4.conf.lo.arp_announce=2

方式3. 修改/proc檔案系統:

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

五、常用指令碼

js /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up VIP(虛擬IP):跟物理網絡卡是繫結的,它實際上就是繫結在物理網絡卡上的別名,如lo:x ,x為0-255的任意數字,你可以在一塊網絡卡上繫結多個別名。這個VIP可以看作是你上網的QQ網名、暱稱、外號等。
lo:0 表示這個VIP繫結的目標網絡卡裝置
10.122.130.125 就是VIP的值
廣播地址為10.122.130.125
子網掩碼為:255.255.255.255
up表示立即啟用這個VIP

```shell

!/bin/bash

VIP=10.122.130.125

case "$1" in start)

echo "Start REAL Server"
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
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

;;

stop)

/sbin/ifconfig lo:0 down
echo "Stop REAL Server"
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce

;;

restart)

$0 stop
$0 start

;;

*)

```

image.png

六、 DR模式工作原理:

image.png

``` Client傳送請求 -->prerouting --> INPUT— DS(排程器) --> -->postrouting –>RS(真正的伺服器)–>lo迴環介面 --> 網絡卡eth0 -->Client

整個過程的資料流向如下: 使用者(client)傳送請求給排程器(DS),DS排程器先把請求發往prerouting鏈(核心空間kernal space),確定請求的是不是VIP 到了INPUT鏈之後,如果請求的是叢集服務,會在這裡修改MAC地址,把源MAC地址改為DS的MAC地址,把目的MAC地址改為RS的MAC地址,此時IP仍然不變 處理完成後把請求發往postrouting鏈,檢測請求的是否為RS(會檢測請求的MAC地址),如果是,接受請求,把請求通過迴環介面發給出口的網絡卡,再發回給客戶端

資料在系統內的交流用的是迴環介面,與外部的交流用的是網絡卡eth0

DR模式高效的原因就是RS伺服器會直接響應客戶端的請求,傳送的請求一直往前傳送資料包,不會再返回資料包給排程器

注意:這裡的prerouting,input,postrouting都是iptables防火牆裡面的鏈,

```

參考

Linux核心引數之arp_ignore和arp_announce\ LVS 之 DR model arp_announce arp_ignore\ LVS DR 模式後端RS lo網絡卡必須繫結VIP\ LVS/DR模式(直接路由模式)(ipvsadm+ipvs)