今天,主要想講一下如何利用Linux內核功能,搭建與市面上十幾萬的商用產品(F5、RADWARE等)功能相同的多互聯網線路負載均衡設備。

負載均衡,相信各位是瞭解的。主要包括兩大類,一類是應用負載均衡,另一類是鏈路負載均衡。應用負載均衡,包括了軟負載均衡如nginx、LVS,硬負載均衡如F5、RADWARE等大廠的產品。應用負載均衡利用了反向代理和DNS解析,在於同一套業務系統中多臺應用伺服器間分攤負載,一來便於擴展應用性能,二來通過反向代理等功能保護後面實際的應用伺服器。

而鏈路負載均衡,廣泛應用於自建機房且有面向互聯網業務的公司,主要目的是在多條互聯網出口間分攤網路流量,利用NAT映射功能為內網伺服器提供多家運營商的互聯網出口以保證訪問體驗。使用鏈路負載均衡:

一是可以提高互聯網出口利用效率。

二是如果在防火牆實現訪問控制表、路由表、NAT映射表都需要CPU計算,對於內網規模較大、業務系統多的公司來說使用負載均衡可以減輕防火牆CPU負載。

三是負載均衡、防火牆、網關路由器承擔各自角色,使各項功能模塊化,發生單點故障時,僅需尋求該功能模塊的替換方案即可,而不影響其他功能。

四是防火牆與鏈路負載均衡分開可以提高網路安全性,如果防火牆放開埠但負載均衡沒有做映射便無法訪問,反之亦然。

目前市面上的鏈路負載均衡設備,以商用產品為主,國際大廠包括F5、RADWARE,國內包括深信服、H3C等,其價格動輒十幾萬,而部分廠商售後政策也十分壟斷,價格令人嗔目。

近期我司原本雙機互備的兩臺鏈路負載均衡設備,使用年限長了,掛了一臺。而新採購設備耗時較長,為了保證在此期間剩下那臺發生故障能夠有所準備。我研究起了能否用Linux做免費的鏈路負載均衡。

通過查找,最終在百度文庫找了一篇論文有所提及,用iproute2、 ip rule和iptables如何實現。而順著這條思路查找,網上各種資料、書籍僅僅是簡單講解了基本使用方法。而我寫這篇文章,就是為了搞大事——演示如何實現更複雜的鏈路負載均衡。

首先說下基本條件:

1.當前共有移動、電信、聯通三家運營商的互聯網出口。

2.移動互聯網,公網地址60.1.1.0/28,網關60.1.1.1,有14個公網地址可用。

3.聯通互聯網,公網地址232.5.5.64/28,網232.5.5.65,有14個公網地址可用。

4.電信互聯網,公網地址58.7.7.128/28,網關58.7.7.129,有14個公網地址可用。

6.公司內網用於負載均衡的路由口為10.100.1.1/30,下一跳為防火牆10.100.1.2/30,內網網段包括172.16.11.0/24,172.16.56.0/24,172.16.210.0/24,10.201.1.0/24,192.168.200.0/24,共計5個網段。

7.內部辦公區及伺服器訪問互聯網的動態映射地址為移動60.1.1.14、聯通232.5.5.78、電信58.7.7.142。各出口其餘13各公網地址備案後給機房有互聯網業務的伺服器使用。

拓撲示意圖如下:

介紹完基本情況,我開始正式講解鏈路負載均衡的做法。雖然看似複雜,但是搞清楚邏輯概念,外加自己動手做個三四遍後,相信大家做的會比我更好的。

物理設備方面,找臺PC主機,有條件的直接上伺服器,由於路由表和NAT表都需要網卡與CPU通信、以及CPU的算力,想要延遲小,當然主板和CPU的性能越高越好。然後需要4個千兆網口(網卡也是,性能越高越好),伺服器一般自帶,而PC需要額外購置一塊4口網卡。

軟體方面,由於所需功能都是linux系統自帶,僅需要裝一個系統即可。我選用的是CentOS7,如果有redhat儘管用。

裝好了系統,先接網線:

eth0:內網埠

eth1:移動口

eth2:聯通口

eth3:電信口

網線接好後,開始進行配置:

一、配置IP地址

配置IP地址可以使用ifconfig或者ip addr。我使用是ip addr,主要是因為各互聯網出口如果想把所有的公網ip都使用上,需要在同一個網口上配置多個IP地址。相較ifconfig而言,我個人認為還是ip addr好理解一些:

#首先配置內網口:
ip addr add 10.200.1.1/30 brd 10.200.1.3 dev eth0
#配置移動地址,建議將內網的互聯網出口映射地址作為第一個配置:
ip addr add 60.1.1.14/28 brd 60.1.1.15 dev eth1
ip addr add 60.1.1.2/28 brd 60.1.1.15 dev eth1
ip addr add 60.1.1.3/28 brd 60.1.1.15 dev eth1
# 。。。 。。。省略10條
ip addr add 60.1.1.13/28 brd 60.1.1.15 dev eth1

#配置聯通地址
ip addr add 232.5.5.78/28 brd 232.5.5.79 dev eth2
ip addr add 232.5.5.66/28 brd 232.5.5.79 dev eth2
ip addr add 232.5.5.67/28 brd 232.5.5.79 dev eth2
# 。。。 。。。省略10條
ip addr add 232.5.5.77/28 brd 232.5.5.79 dev eth2

#配置電信地址
ip addr add 58.7.7.142/28 brd 58.7.7.143 dev eth3
ip addr add 58.7.7.130/28 brd 58.7.7.143 dev eth3
ip addr add 58.7.7.131/28 brd 58.7.7.143 dev eth3
# 。。。 。。。省略10條
ip addr add 58.7.7.141/28 brd 58.7.7.143 dev eth3

#可以通過輸入下面的命令查看配置情況
ip addr

配置完成後,先不要急著進行下一步。應該檢查一下配置上的所有ip地址是否能夠ping通。我在內網做實驗過程中發現,有時候由於網關獲取arp表中MAC地址較慢,同一網卡中的部分ip地址跨三層ping不通。如果路由不可達那麼後續配置埠映射就會發生故障。

對於公網地址,推薦使用「ping & DNS」這款手機app,手機可以在流量模式下自由檢測公網中IP地址和各種埠的通斷情況,在各大應用商店都可以搜索下載的。

二、添加內網路由

在所有IP地址都確保可以ping通的情況下,先配置內網靜態路由,使用ip route命令:

ip route add 172.16.11.0/24 via 10.200.1.2
ip route add 172.16.56.0/24 via 10.200.1.2
ip route add 172.16.210.0/24 via 10.200.1.2
ip route add 10.201.1.0/24 via 10.200.1.2
ip route add 192.168.100.0/24 via 10.200.1.2

#通過如下命令檢查配置情況
ip route show

三、配置table及檢查路由轉發功能

1.配置table

首先,在路由表中添加三個分表,用於對移動、電信、聯通三家運營商實現負載均衡策略。路由表文件路徑在/etc/iproute2/rt_tables。

打開rt_tables文件,添加如下三行:

#移動線路
101 CMCC
#聯通線路
102 CNC
#電信線路
103 CTC

2.開啟路由轉發功能:

命令如下:

echo "1" >/proc/sys/net/ipv4/ip_forward

四、配置ip rule

由於主要講負載均衡配置,ip rule在這裡不做過多的闡述。只簡單提一句,我們可以通過ip rule來實現在多條線路負載均衡的情況下,控制流量從哪條線路出入。舉個例子,訪問淘寶的流量直走電信線路、訪問天貓的直走聯通線路等等,還可以結合iptables的mark功能——要求某一特定的內網用戶只走聯通線路(例如,現在銀行系統一般會檢查IP地址變動情況,而負載均衡會造成地址檢測異常影響對銀行網路的訪問)。

我這裡實驗需求比較簡單,僅確保聯通進來的流量再從聯通返回,類似這樣的要求即可。代碼如下:

#移動規則
ip rule add from 60.1.1.2 table CMCC
#省略12條... ...
ip rule add from 60.1.1.14 table CMCC

#聯通規則
ip rule add from 232.5.5.66 table CNC
#省略12條... ...
ip rule add from 232.5.5.78 table CNC

#電信規則
ip rule add from 58.7.7.130 table CTC
#省略12條... ...
ip rule add from 58.7.7.142 table CTC

五、配置分表路由策略

分表路由策略比較簡單,主要CMCC、CNC、CTC三個表中配置一條默認路由和一條相對應網段的路由即可:

#移動:
ip route add 60.1.1.0/28 dev eth1 table CMCC
ip route add default via 60.1.1.1 dev eth1 table CMCC

#聯通:
ip route add 232.5.5.64/28 dev eth2 table CNC
ip route add default via 232.5.5.65 dev eth2 table CNC

#電信:
ip route add 58.7.7.128/28 dev eth3 table CTC
ip route add default via 58.7.7.129 dev eth3 table CTC

#可通過下列命令查看分表路由:
ip route show table CMCC
ip route show table CNC
ip route show table CTC

六、設置默認路由負載均衡

在路由主表中配置三個出口的負載均衡策略:

ip route replace default
nexthop via 60.1.1.1 dev eth1 weight 1
nexthop via 232.5.5.65 dev eth2 weight 1
nexthop via 58.7.7.129 dev eth3 weight 1

七、配置動態映射做內網互聯網出口

下面主要用到iptables的SNAT功能,為移動60.1.1.14、聯通232.5.5.78、電信58.7.7.142做動態映射,原則上每個內網網段都需要配置一條SNAT,當然也可以收斂為192.168.0.0/16,172.16.0.0/12,10.0.0.0/8三個網段做:

#移動:
iptables -t nat -A POSTROUTING -o eth1 -s 172.16.11.0/24 -j SNAT --to 60.1.1.14
iptables -t nat -A POSTROUTING -o eth1 -s 172.16.56.0/24 -j SNAT --to 60.1.1.14
iptables -t nat -A POSTROUTING -o eth1 -s 172.16.210.0/24 -j SNAT --to 60.1.1.14
iptables -t nat -A POSTROUTING -o eth1 -s 10.201.1.0/24 -j SNAT --to 60.1.1.14
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.100.0/24 -j SNAT --to 60.1.1.14

#聯通:
iptables -t nat -A POSTROUTING -o eth2 -s 172.16.11.0/24 -j SNAT --to 232.5.5.78
iptables -t nat -A POSTROUTING -o eth2 -s 172.16.56.0/24 -j SNAT --to 232.5.5.78
iptables -t nat -A POSTROUTING -o eth2 -s 172.16.210.0/24 -j SNAT --to 232.5.5.78
iptables -t nat -A POSTROUTING -o eth2 -s 10.201.1.0/24 -j SNAT --to 232.5.5.78
iptables -t nat -A POSTROUTING -o eth2 -s 192.168.100.0/24 -j SNAT --to 232.5.5.78

#電信:
iptables -t nat -A POSTROUTING -o eth3 -s 172.16.11.0/24 -j SNAT --to 58.7.7.142
iptables -t nat -A POSTROUTING -o eth3 -s 172.16.56.0/24 -j SNAT --to 58.7.7.142
iptables -t nat -A POSTROUTING -o eth3 -s 172.16.210.0/24 -j SNAT --to 58.7.7.142
iptables -t nat -A POSTROUTING -o eth3 -s 10.201.1.0/24 -j SNAT --to 58.7.7.142
iptables -t nat -A POSTROUTING -o eth3 -s 192.168.100.0/24 -j SNAT --to 58.7.7.142

#通過下述命令查看配置情況:
iptables -t nat -nL

#如果想刪除其中的某一條,首先通過下面命令查看相關配置的序號:
iptables -t nat -nL --line-number
#然後跟編號刪除,例如:
iptables -t nat -D POSTROUTING 1

經過上面諸多配置,到這一步,我們內網的用戶們便可以輕鬆的訪問互聯網,愉快的玩耍了。

結合iptables的mark與ip rule,可以實現更加智能的負載均衡策略。在這裡不多贅述。下面,將介紹伺服器映射。

八、伺服器映射

完成上述工作,內部用戶能夠成功訪問互聯網後,剩下的工作就是簡單的在iptables上做DNAT映射,唯一的區別就是同一臺內網伺服器,我們要做多條線路的DNAT映射,例如在本文中每個運營商,我們有14個公網地址,拿來做一對一、多對一的NAT都可以。簡單舉一個例子如下:

#為10.201.1.155的80埠web服務提供移動、聯通、電信三條線路的公網映射:
iptables -t nat -A PREROUTING -i eth1 -d 60.1.1.4 -p tcp --dport 80 -j DNAT --to 10.201.1.155:80
iptables -t nat -A PREROUTING -i eth2 -d 232.5.5.72 -p tcp --dport 80 -j DNAT --to 10.201.1.155:80
iptables -t nat -A PREROUTING -i eth3 -d 58.7.7.134 -p tcp --dport 80 -j DNAT --to 10.201.1.155:80

這樣一來,我們就可以通過60.1.1.4/232.5.5.72/58.7.7.134這三個地址的80埠訪問同一臺伺服器的web了。為了得到更好的訪問體驗,現在如阿里雲等各大域名解析平臺都可以根據運營商線路來解析對應的IP地址。

九、總結

本文,僅僅是講述了linux搭建負載均衡的最基本的一些套路。動輒幾十萬的商業級鏈路負載均衡那些高級功能,同樣可以利用iptables和iproute2的高級配置進行組合得以實現

至於性能方面,實際上商業產品也是用的伺服器,甚至有些產品用的是低端的伺服器。只是內部操作系統是自研、經過優化的。Linux雖然優化可能沒有商業產品好,但是可以通過高性能硬體多少彌補。

至於交互界面複雜這種事情,對於我來說,可以通過perl或python寫一個web端彌補。

所以,各位同仁們,鏈路負載均衡壞了不要怕,可以快速搭一個linux先頂著。


推薦閱讀:
相關文章