lvs(linux virtual server)是工做在netfiler之上的,netfilter是在內核中tcp/Ip協議棧上選擇了5個位置看成卡鉤: PREROUTING --> INPUT --> FORWARD --> OUTPUT --> POSTROUTINGhtml
lvs代碼也分爲兩段,跟iptables同樣,一段工做在內核中的一個框架ipvs,根據你所定義的規則可以實現轉發,一段工做在用戶空間中的程序ipvsadm,寫入規則後能夠送到內核空間上去。前端
ipvs不是工做在prerouting上,而是工做在input鏈上,ipvs會發現用戶請求是一個集羣服務,是一個向後端轉發的服務,因此ipvs在此處強行把請求轉走,送往postrouting出去,進而轉發到後端主機上。node
http://www.netfilter.org/documentation/HOWTO//netfilter-hacking-HOWTO-3.htmllinux
lvs的術語:算法
IP:windows
ViP: virtual ip 爲虛擬服務器提供虛擬服務的ip後端
Dip:director ip 用於實現跟內部主機通訊的ip緩存
Rip:realserver ip 後端真實服務器的ipbash
Cip:client ip 客戶端ip服務器
Director中內核tcp/ip協議棧簡單網絡轉發結構
lvs按照其工做架構有三種不一樣的工做類型
lvs-nat Network Address Translation 網絡地址轉換
lvs-dr Direct Routing 直接路由
lvs-tun tunneling 隧道
nat類型的特性:修改請求報文的目標ip地址(ip和port)
請求ip段的狀態
CIP:VIP -> CIP:RIP1(挑選出來)
響應ip段的狀態
RIP:CIP -> VIP:CIP
1.RS(realserver)應用使用私有地址;RS的網關必須指向DIP
2.請求和響應都要通過Director;高負載場景中,Director易成爲性能瓶頸
3.支持端口映射
4.RS可使用任意OS
解決Director壓力過大而使用的類型
dr類型的特性:只用來接收請求和分發,未改目標ip,只是修改了報文的目標mac地址改成了realserver網卡的mac地址,響應報文不通過Director,而是直接經過realserver響應給客戶端。
1. 保證前端路由將目標地址爲VIP的報文通通發往Director,而不能是RS;
解決方案:
(1) 靜態地址綁定:在前端路由器上操做 配置靜態VIP
存在的問題:未必有路由操做權限
(2) 使用arptables(arp解析時作防火牆規則的),須要寫規則
(3) 修改RS上內核參數,將RS上的VIP配置在lo接口的別名上,並限制其不能響應對VIP地址解析請求
2. RS可使用私有地址,但也可使用公網地址,此時可經過互聯網經過RIP對其直接訪問
3. RS跟Director必須在同一個物理網絡中
4. 請求報文經由Director,但響應報文不能通過Director
5. 不支持端口映射
6. RS能夠是大多數常見的OS
7. RS的網關決不容許指向Dip
tun類型的特性:隧道類型 ip隧道(在ip外部在封裝一個ip首部,存在的問題:會致使ip首部變大,各RIP須要支持隧道的功能)
1. RIP、VIP、DIP所有是公網地址
2. RS的網關不會也不可能指向DIP
3. 請求報文經由Director,但響應報文必須不能通過Director
4. 不支持端口映射
5. RS的OS必須支持隧道功能
其中nat在小規模場景中會使用;絕大部分都是選擇dr類型;隧道機制在異地容災中會是一種選擇;
lvs scheduler(lvs調度方法),挑選標準有10種
# grep -i 'vs' /boot/config-3.10.0-327.el7.x86_64
…
# IPVS transport protocol load balancing support 傳輸層協議負載均衡的支持
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y
# IPVS scheduler ipvs調度算法
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
…
靜態方法:僅根據調度算法自己進行調度,不考慮後端節點的負載
rr:round robin 輪詢、輪流、輪叫 根據添加RS的順序進行順序調度
wrr:weighted round robin 加權輪詢 對於性能更好的主機,設置權重大一些,將承擔更多負載
sh:source hashing 源地址hash 爲了session持久功能,表示來源於同一個cip的請求將始終被定向至同一個RS
dh:destination hashing 目標地址hash 通常是後端爲多個緩存服務器時,根據目標ip地址經過散列函數將目標ip與服務器創建映射關係,出現服務器不可用或負載太高的狀況下,發往該目標ip的請求會固定發給該服務器。
動態方法:根據算法以及各RS當前負載情況進行調度
lc:least connection 最少鏈接
overhead(當前的負載情況)=(全部鏈接中處於活動狀態的鏈接)active*256 + inactive(非活動狀態鏈接數) 根據overhead進行比較來作最少鏈接
wlc:weighted lc 加權最小鏈接
overhead=((活動鏈接數)active*256 + inactive)/weight(權重)
sed:shortest expection delay 最少指望延遲 第一次請求時必定是權重大的來處理
overhead = (active + 1)*256/weight
nq:never queue 永不排隊 第一次請求來了後,前後端主機各一個,然後再計算
lblc:locality-based least connection 基於局部性最少鏈接調度算法 動態dh,請求數據包目標ip地址的一種調度算法,該算法先根據請求的目標IP地址尋找最近該目標IP地址所使用的服務器,若是這臺服務器依然可用,而且有能力處理該請求,調度器會盡可能選擇相同的服務器,不然會繼續選擇其餘可行的服務器。
lblcr:replicated lblc 帶複製功能的lblc 記錄的不是一個目標ip一臺服務器之間鏈接記錄,它會維護一個目標ip到一組服務器之間的映射關係,防止單點服務器負載太高。
這裏以lvs的dr類型舉例
安裝ipvsadm程序
# yum install –y ipvsadm # base源已經提供了
# rpm -ql ipvsadm |less
/etc/rc.d/init.d/ipvsadm
/etc/sysconfig/ipvsadm-config
/sbin/ipvsadm
/sbin/ipvsadm-restore
/sbin/ipvsadm-save
。。。。
定義集羣服務或修改集羣服務
ipvsadm - Linux Virtual Server administration
詳細使用可用
man ipvsadm
ipvsadm –A|E –t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine] 調度器默認是wlc
添加或修改一個集羣服務
ipvsadm –a|e –t|u|f service-address –r server-address [options] 定義好的集羣服務中添加或修改realserver
查看已經定義的集羣服務及RS:
ipvsadm –L –n(數字格式顯示) -c: 查看各鏈接
--stats: 統計數據 --rate: 速率
--exact: 精確值
從集羣服務中刪除RS:
ipvsadm –d –t|u|f service-address –r server-address
刪除集羣服務
ipvsadm –D –t|u|f service-address
清空全部的集羣服務
ipvsadm –C
保存集羣服務定義:
ipvsadm –S > /path/to/some_rule_file
ipvsadm-save > /path/to/some_rule_file
service ipvsadm save
讓規則文件中的規則生效:
ipvsadm –R < /path/to/some_rule_file
ipvsadm-restore < /path/to/some_rule_file
session持久機制:
1. session綁定:始終未來自同一個源ip的請求定向至同一個RS;沒有容錯能力;有損均衡效果;(若是RS故障了,那麼此前在RS上的會話都會丟失)
2. session複製:在RS之間同步session,每一個RS擁有集羣中的全部session;對大規模集羣不適用;
3. session服務器:利用單獨部署的服務器統一管理集羣中的session;
lvs dr:Director和realserver在同一個物理網絡中,轉發時Director上修改目標mac爲rip的mac,rip和dip不在同一個網絡中時,須要配置路由信息,讓各rip經過路由訪問互聯網
Director配置兩個地址:dip、VIP
RS須要配置:rip、VIP
RS配置內核參數
arp_ignore:如何響應ARP地址的廣播請求;默認0所有響應;1表示僅在請求的地址配置在請求報文的接口進行響應;全部接口都要這樣配置
arp_announce:如何響應通告本地地址;默認0全部地址都會通告;2表示僅通告網絡直連的接口的地址;全部接口都要這樣的配置
# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
# echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
注意:須要先配置內核參數再改ip地址
Director和realserver安裝好httpd而且啓動
node4提供的訪問頁面爲
<h1>node4</h1>
node5提供的訪問頁面爲
<h1>node5</h1>
RS:首先配置內核參數
配置VIP時使用以下格式:
ifconfig lo:0 vip netmask 255.255.255.255 broadcast vip up (只廣播給本身不廣播給其餘任何人)
route add –host vip dev lo:0 若是請求的是realserver上的VIP,那麼必須通告lo:0出去
node3
# echo 1 > /proc/sys/net/ipv4/ip_forward
# ifconfig eth0:0 192.168.21.190/24 up
node4
# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
# echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
# ifconfig lo:0 192.168.21.190 netmask 255.255.255.255 broadcast 192.168.21.190 up
# route add –host 192.168.21.190 dev lo:0
node5
# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
# echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
# ifconfig lo:0 192.168.21.190 netmask 255.255.255.255 broadcast 192.168.21.190 up
# route add –host 192.168.21.190 dev lo:0
windows上操做
node3
# ipvsadm –A –t 192.168.21.190:80 –s rr
# ipvsadm –a –t 192.168.21.190:80 –r 192.168.21.230 –g –w 1
# ipvsadm –a –t 192.168.21.190:80 –r 192.168.21.222 –g –w 2
# 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.21.190:80 rr
-> 192.168.21.222:80 Route 2 0 0
-> 192.168.21.230:80 Route 1 0 0
由於是rr模型的,給定權重也不起做用的
讓DIP和VIP不在統一網段,中間須要加一個路由設備
Director腳本:
#!/bin/bash
#
# LVS script for VS/DR
#
. /etc/rc.d/init.d/functions
#
VIP=192.168.0.210
RIP1=192.168.0.221
RIP2=192.168.0.222
PORT=80
#
case "$1" in
start)
/sbin/ifconfig eth0:1 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev eth0:1
# Since this is the Director we must be able to forward packets
echo 1 > /proc/sys/net/ipv4/ip_forward
# Clear all iptables rules.
/sbin/iptables -F
# Reset iptables counters.
/sbin/iptables -Z
# Clear all ipvsadm rules/services.
/sbin/ipvsadm -C
# Add an IP virtual service for VIP 192.168.0.219 port 80
# In this recipe, we will use the round-robin scheduling method.
# In production, however, you should use a weighted, dynamic scheduling method.
/sbin/ipvsadm -A -t $VIP:80 -s wlc
# Now direct packets for this VIP to
# the real server IP (RIP) inside the cluster
/sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -g -w 1
/sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w 2
/bin/touch /var/lock/subsys/ipvsadm &> /dev/null
;;
stop)
# Stop forwarding packets
echo 0 > /proc/sys/net/ipv4/ip_forward
# Reset ipvsadm
/sbin/ipvsadm -C
# Bring down the VIP interface
/sbin/ifconfig eth0:1 down
/sbin/route del $VIP
/bin/rm -f /var/lock/subsys/ipvsadm
echo "ipvs is stopped..."
;;
status)
if [ ! -e /var/lock/subsys/ipvsadm ]; then
echo "ipvsadm is stopped ..."
else
echo "ipvs is running ..."
ipvsadm -L -n
fi
;;
*)
echo "Usage: $0 {start|stop|status}"
;;
esac
RealServer腳本:
#!/bin/bash
#
# Script to start LVS DR real server.
# description: LVS DR real server
#
. /etc/rc.d/init.d/functions
VIP=192.168.0.219
host=`/bin/hostname`
case "$1" in
start)
# Start LVS-DR real server on this machine.
/sbin/ifconfig lo down
/sbin/ifconfig lo 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
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev lo:0
;;
stop)
# Stop LVS-DR real server loopback device(s).
/sbin/ifconfig lo:0 down
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
;;
status)
# Status of LVS-DR real server.
islothere=`/sbin/ifconfig lo:0 | grep $VIP`
isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
if [ ! "$islothere" -o ! "isrothere" ];then
# Either the route or the lo:0 device
# not found.
echo "LVS-DR real server Stopped."
else
echo "LVS-DR real server Running."
fi
;;
*)
# Invalid entry.
echo "$0: Usage: $0 {start|status|stop}"
exit 1
;;
esac