Docker 搭建簡單 LVS


LVS簡介

       LVS(Linux Virtual Server)即Linux虛擬服務器,是由章文嵩博士主導的開源負載均衡項目,目前LVS已經被集成到Linux內核模塊中。該項目在Linux內核中實現了基於IP的數據請求負載均衡調度方案,其體系結構如圖1所示,終端互聯網用戶從外部訪問公司的外部負載均衡服務器,終端用戶的Web請求會發送給LVS調度器,調度器根據自己預設的算法決定將該請求發送給后端的某台Web服務器,比如,輪詢算法可以將外部的請求平均分發給后端的所有服務器,終端用戶訪問LVS調度器雖然會被轉發到后端真實的服務器,但如果真實服務器連接的是相同的存儲,提供的服務也是相同的服務,最終用戶不管是訪問哪台真實服務器,得到的服務內容都是一樣的,整個集群對用戶而言都是透明的。最后根據LVS工作模式的不同,真實服務器會選擇不同的方式將用戶需要的數據發送到終端用戶,LVS工作模式分為NAT模式、TUN模式、以及DR模式。

三種工作模式的解析

基於NAT的LVS模式負載均衡

      NAT(Network Address Translation)即網絡地址轉換,其作用是通過數據報頭的修改,使得位於企業內部的私有IP地址可以訪問外網,以及外部用用戶可以訪問位於公司內部的私有IP主機。VS/NAT工作模式拓撲結構如圖2所示,LVS負載調度器可以使用兩塊網卡配置不同的IP地址,eth0設置為私鑰IP與內部網絡通過交換設備相互連接,eth1設備為外網IP與外部網絡聯通。

       第一步,用戶通過互聯網DNS服務器解析到公司負載均衡設備上面的外網地址,相對於真實服務器而言,LVS外網IP又稱VIP(Virtual IP Address),用戶通過訪問VIP,即可連接后端的真實服務器(Real Server),而這一切對用戶而言都是透明的,用戶以為自己訪問的就是真實服務器,但他並不知道自己訪問的VIP僅僅是一個調度器,也不清楚后端的真實服務器到底在哪里、有多少真實服務器。

   第二步,用戶將請求發送至124.126.147.168,此時LVS將根據預設的算法選擇后端的一台真實服務器(192.168.0.1~192.168.0.3),將數據請求包轉發給真實服務器,並且在轉發之前LVS會修改數據包中的目標地址以及目標端口,目標地址與目標端口將被修改為選出的真實服務器IP地址以及相應的端口。

    第三步,真實的服務器將響應數據包返回給LVS調度器,調度器在得到響應的數據包后會將源地址和源端口修改為VIP及調度器相應的端口,修改完成后,由調度器將響應數據包發送回終端用戶,另外,由於LVS調度器有一個連接Hash表,該表中會記錄連接請求及轉發信息,當同一個連接的下一個數據包發送給調度器時,從該Hash表中可以直接找到之前的連接記錄,並根據記錄信息選出相同的真實服務器及端口信息。

基於TUN的LVS負載均衡

       在LVS(NAT)模式的集群環境中,由於所有的數據請求及響應的數據包都需要經過LVS調度器轉發,如果后端服務器的數量大於10台,則調度器就會成為整個集群環境的瓶頸。我們知道,數據請求包往往遠小於響應數據包的大小。因為響應數據包中包含有客戶需要的具體數據,所以LVS(TUN)的思路就是將請求與響應數據分離,讓調度器僅處理數據請求,而讓真實服務器響應數據包直接返回給客戶端。VS/TUN工作模式拓撲結構如圖3所示。其中,IP隧道(IP tunning)是一種數據包封裝技術,它可以將原始數據包封裝並添加新的包頭(內容包括新的源地址及端口、目標地址及端口),從而實現將一個目標為調度器的VIP地址的數據包封裝,通過隧道轉發給后端的真實服務器(Real Server),通過將客戶端發往調度器的原始數據包封裝,並在其基礎上添加新的數據包頭(修改目標地址為調度器選擇出來的真實服務器的IP地址及對應端口),LVS(TUN)模式要求真實服務器可以直接與外部網絡連接,真實服務器在收到請求數據包后直接給客戶端主機響應數據。

基於DR的LVS負載均衡

在LVS(TUN)模式下,由於需要在LVS調度器與真實服務器之間創建隧道連接,這同樣會增加服務器的負擔。與LVS(TUN)類似,DR模式也叫直接路由模式,其體系結構如圖4所示,該模式中LVS依然僅承擔數據的入站請求以及根據算法選出合理的真實服務器,最終由后端真實服務器負責將響應數據包發送返回給客戶端。與隧道模式不同的是,直接路由模式(DR模式)要求調度器與后端服務器必須在同一個局域網內,VIP地址需要在調度器與后端所有的服務器間共享,因為最終的真實服務器給客戶端回應數據包時需要設置源IP為VIP地址,目標IP為客戶端IP,這樣客戶端訪問的是調度器的VIP地址,回應的源地址也依然是該VIP地址(真實服務器上的VIP),客戶端是感覺不到后端服務器存在的。由於多台計算機都設置了同樣一個VIP地址,所以在直接路由模式中要求調度器的VIP地址是對外可見的,客戶端需要將請求數據包發送到調度器主機,而所有的真實服務器的VIP地址必須配置在Non-ARP的網絡設備上,也就是該網絡設備並不會向外廣播自己的MAC及對應的IP地址,真實服務器的VIP對外界是不可見的,但真實服務器卻可以接受目標地址VIP的網絡請求,並在回應數據包時將源地址設置為該VIP地址。調度器根據算法在選出真實服務器后,在不修改數據報文的情況下,將數據幀的MAC地址修改為選出的真實服務器的MAC地址,通過交換機將該數據幀發給真實服務器。整個過程中,真實服務器的VIP不需要對外界可見。

​LVS/NAT 的實現

首先為了能夠使用 IPVS 內核模塊,我們將在宿主機中安裝 ipvsadm,並嘗試能否使用:

sudo apt-get update # 更新源 
sudo apt-get install ipvsadm # 安裝 ipvsadm 工具
sudo ipvsadm -L # 嘗試使用 ipvsadm

使用 docker 創建所需 container,使用以下命令創建

docker run --privileged --name=RealServer1 -tdi ubuntu
docker run --privileged --name=RealServer2 -tdi ubuntu

RealServer 部署 Nginx 來提供 Web 服務,RealServer1 和 RealServer2 操作步驟相同,此處以 RealServer1 為示

docker attach RealServer1
apt-get update
apt-get install vim -y 
apt-get install nginx -y
service nginx start

#RealServer1 container 環境 sudo vi /var/www/html/index.nginx-debian.html(不同的安裝方式路徑不同)  修改默認頁面移區分2台服務器

至此我們完成兩台 Web 服務器的配置,我們可以打開宿主機 firefox 瀏覽器,地址欄分別輸入兩個 IP 地址,來檢驗我們的配置成功:

LoadBalancer(宿主) 的對外 IP 地址為 VIP,即 VIP 地址為 10.2.10.10( 10.2.10.10 是虛擬出來的,我的外網是10.2.0.xx )開啟 LoadBalancer 的內核路由轉發

echo '1' | sudo tee /proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward #1 1 說明此機器已開啟內核路由轉發

.使用 ipvsadm 添加 ipvs 規則。定義集群服務:

sudo ipvsadm -A -t 10.2.10.10:80 -s rr         #定義集群服務
sudo ipvsadm -a -t 10.2.10.10:80 -r 172.17.0.6 -m #添加 RealServer1
sudo ipvsadm -a -t 10.2.10.10:80 -r 172.17.0.7 -m #添加 RealServer2
sudo ipvsadm -l                 #查看 ipvs 定義的規則
# 添加集群服務
-A:添加一個新的集群服務
-t: 使用 TCP 協議
-s: 指定負載均衡調度算法
rr:輪詢算法(LVS 實現了 8 種調度算法)
192.168.100.5:8888  定義集群服務的 IP 地址(VIP) 和端口

# 添加 Real Server 規則
-a:添加一個新的 RealServer 規則
-t:tcp 協議
-r:指定 RealServer IP 地址
-m:定義為 NAT 
上面命令添加了兩個服務器 RealServer1 和 RealServer2

測試結果(如果強制刷新沒有變化 就把對應的nginx關閉再看看)

LVS/DR 的搭建

由於我實在同一個環境里面測試,所以現在需要刪除上面的東西

sudo ipvsadm -C #清除 ipvsadm 的規則
docker stop RealServer1
docker stop RealServer2
docker rm RealServer1
docker rm RealServer2

通過 docker 創建三個 container 來模擬服務器池中的成員

docker run --privileged --name=LoadBalancer -tid ubuntu
docker run --privileged --name=RealServer1 -tid ubuntu
docker run --privileged --name=RealServer2 -tid ubuntu

配置兩台 RealServer 的環境,已RealServer1為例

docker attach RealServer1
apt-get update
apt install net-tools
apt-get install vim -y 
apt-get install nginx -y
#vi /usr/share/nginx/html/index.html
vi /var/www/html/index.nginx-debian.html
service nginx start

修改內核參數,抑制 arp,以 RealServer1 為例,登錄 container,執行下列命令:

# 設置只回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求 
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore

# 為了保險自己可以查看一下是否成功修改
cat /proc/sys/net/ipv4/conf/lo/arp_ignore

# 設置對查詢目標使用最適當的本地地址.在此模式下將忽略這個IP數據包的源地址並嘗試選擇與能與該地址通信的本地地址.首要是選擇所有的網絡接口的子網中外出訪問子網中包含該目標IP地址的本地地址. 如果沒有合適的地址被發現,將選擇當前的發送網絡接口或其他的有可能接受到該ARP回應的網絡接口來進行發送.
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce

# 使得上面的配置立即生效
sysctl -p

創建網卡別名與添加路由

只有目的 IP 是本機器中的一員時才會做相應的處理,所以需要添加網卡別名(172.17.0.10是虛擬出來,和我docker容器的ip是通一段 2個server的docker ip是172.17.0.6/7)

apt-get install network-manager
# 配置虛擬IP
ifconfig lo:0 172.17.0.10 broadcast 172.17.0.10 netmask 255.255.255.255 up
#172.17.0 和docker0 相同網段
# 添加路由,因為本就是相同的網段所以可以不添加該路由
route add -host 172.17.0.10 dev lo:0
service network-manager restart

配置一台 LoadBalancer 環境:

docker attach LoadBalancer
apt-get update
apt install net-tools
apt-get install ipvsadm
ifconfig eth0:0  172.17.0.10:80 netmask 255.255.255.0 up
ipvsadm -A -t 172.17.0.10:80 -s rr         # 定義集群服務
ipvsadm -a -t 172.17.0.10:80 -r 172.17.0.6 -g # 添加 RealServer1
ipvsadm -a -t 172.17.0.10:80 -r 172.17.0.7 -g # 添加 RealServer2
ipvsadm -l                  # 查看 ipvs 定義的規則
#-g:定義為 DR 模式

測試結果(如果強制刷新沒有變化 就把對應的nginx關閉再看看)

參考:

LVS負載均衡(LVS簡介、三種工作模式、十種調度算法)

Docker 的簡單使用&LVSNAT&LVSDR 的實現


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM