一、測試環境說明
操作系統:CentOS6.7-X64
IP_VS版本:1.2.26
DR:10.10.10.130
VIP:10.10.10.140
RS1:10.10.10.131
RS2:10.10.10.132
二、LVS-DR模式原理
a)客戶端發送一個請求(源地址為CIP,目標地址為VIP,我們簡稱為CIP:VIP)到LVS的DR
b)通過在調度器上修改數據包的目的MAC地址來實現轉發(仍舊保持為CIP:VIP)
c)請求的報文經過調度器,而RS響應處理后的報文無需經過調度器,直接將返回請求給客戶端(VIP:CIP)
d)因為DR模式是通過MAC地址的改寫機制來實現的轉發,因此,所有RS節點和調度器只能在同一個LAN中
e)RS節點需要綁定VIP(如果有多個VIP地址,lo:vip,lo1:vip)以及配置ARP抑制問題
f)RS節點默認網關不需要是調度器的DIP,而直接是IDC機房分配的上級路由器的IP(這是RS帶有外網IP的情況),理論上:只要RS可以出網即可,不需要配置外網IP
h)由于DR模式的調度器僅進行了目的MAC地址的改寫,因此,調度器無法改變請求的報文的目的端口
i)調度器支持大多數UNIX及Linux(暫不支持windows),RS可以是windows
三、實際操作配置
1)DR上的配置:
關閉iptables: [root@DR1 ~]# iptables -X [root@DR1 ~]# iptables -F [root@DR1 ~]# iptables -Z [root@DR1 ~]# service iptables stop iptables:將鏈設置為政策 ACCEPT:filter [確定] iptables:清除防火墻規則: [確定] iptables:正在卸載模塊: [確定] [root@DR1 ~]# chkconfig iptables off 安裝配置http服務,并設置好軟鏈接: [root@DR1 ~]# yum -y install httpd [root@DR1 ~]# sevice httpd start [root@DR1 ~]# chkconfig httpd on [root@DR1 ~]# echo "網站維護中">/var/www/html/index.html [root@DR1 ~]# ln -s /usr/src/kernels/2.6.32-573.el6.x86_64/ /usr/src/linux [root@DR1 ~]# ll /usr/src/ 總用量 8 drwxr-xr-x. 2 root root 4096 9月 23 2011 debug drwxr-xr-x. 3 root root 4096 7月 5 23:49 kernels lrwxrwxrwx 1 root root 39 8月 31 08:49 linux -> /usr/src/kernels/2.6.32-573.el6.x86_64/ 安裝并加載ip_vs模塊: [root@DR1 ~]# yum -y install libnl* popt* [root@DR1 ~]# lsmod | grep ip_vs [root@DR1 ~]# cd /usr/local/src/ [root@DR1 src]# wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz root@DR1 src]# tar -zxvf ipvsadm-1.26.tar.gz [root@DR1 src]# cd ipvsadm-1.26 [root@DR1 ipvsadm-1.26]# make [root@DR1 ipvsadm-1.26]# make install [root@DR1 ipvsadm-1.26]# ipvsadm IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn 說明:也可以使用modprobe ip_vs [root@DR1 ipvsadm-1.26]# lsmod | grep ip_vs ip_vs 126534 0 libcrc32c 1246 1 ip_vs ipv6 335589 285 ip_vs,cnic,ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6 配置VIP地址: [root@DR1 ~]# ifconfig eth0:0 10.10.10.140/24 up [root@DR1 ~]# route add -host 10.10.10.140 dev eth0 [root@DR1 ~]# ifconfig -a eth0 Link encap:Ethernet HWaddr 00:0C:29:53:CF:52 inet addr:10.10.10.130 Bcast:10.10.10.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fe53:cf52/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2849 errors:0 dropped:0 overruns:0 frame:0 TX packets:955 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:268088 (261.8 KiB) TX bytes:112049 (109.4 KiB) eth0:0 Link encap:Ethernet HWaddr 00:0C:29:53:CF:52 inet addr:10.10.10.140 Bcast:10.10.10.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:6 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:344 (344.0 b) TX bytes:344 (344.0 b) 查看路由表信息: [root@DR1 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.10.10.140 0.0.0.0 255.255.255.255 UH 0 0 0 eth0 10.10.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 10.10.10.2 0.0.0.0 UG 0 0 0 eth0 手動配置LVS-ipvs規則: [root@DR1 ~]# ipvsadm -A -t 10.10.10.140:80 -s rr [root@DR1 ~]# ipvsadm -A -t 10.10.10.140:80 -s rr -p 20 可選:-p,是會話保持時間 [root@DR1 ~]# ipvsadm -a -t 10.10.10.140:80 -r 10.10.10.131 -g -w 1 [root@DR1 ~]# ipvsadm -a -t 10.10.10.140:80 -r 10.10.10.132 -g -w 1 -g:代表DR模式 -w 1:指的是設置權重為1 查看ipvs,可以看到使用rr算法,下面的real server分別是10.10.10.131和10.10.10.132 [root@DR1 ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.10.10.140:80 rr persistent 20 -> 10.10.10.131:80 Route 1 0 0 -> 10.10.10.132:80 Route 1 0 0 擴充選項: a) 刪除LVS [root@DR1 ~]# ipvsadm -D -t 10.10.10.140:80 -s rr -p 20 [root@DR1 ~]# ipvsadm -D -t 10.10.10.140:80 [root@DR1 ~]# ipvsadm -d -t 10.10.10.140:80 -r 10.10.10.131 [root@DR1 ~]# ipvsadm -d -t 10.10.10.140:80 -r 10.10.10.132 b) 查看連接狀態 [root@DR1 ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.10.10.140:80 rr -> 10.10.10.131:80 Route 1 0 194 -> 10.10.10.132:80 Route 1 0 194 [root@DR1 ~]# watch -n 2 ipvsadm -L -n [root@DR1 html]# watch -n 2 ipvsadm -L -n --stats
2)RS1的配置:
停用iptables規則: [root@C67-X64-A2 ~]# iptables -X [root@C67-X64-A2 ~]# iptables -F [root@C67-X64-A2 ~]# iptables -Z [root@C67-X64-A2 ~]# service iptables stop iptables:將鏈設置為政策 ACCEPT:filter [確定] iptables:清除防火墻規則: [確定] iptables:正在卸載模塊: [確定] [root@C67-X64-A2 ~]# chkconfig iptables off 綁定lo地址(注意網關為255.255.255.255): [root@RS1 ~]# ifconfig lo:0 10.10.10.140 netmask 255.255.255.255 up [root@RS1 ~]# route add -host 10.10.10.140 dev lo [root@RS1 ~]# ifconfig -a eth0 Link encap:Ethernet HWaddr 00:0C:29:38:73:A5 inet addr:10.10.10.131 Bcast:10.10.10.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fe38:73a5/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2794 errors:0 dropped:0 overruns:0 frame:0 TX packets:504 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:188141 (183.7 KiB) TX bytes:52385 (51.1 KiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:4 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:240 (240.0 b) TX bytes:240 (240.0 b) lo:0 Link encap:Local Loopback inet addr:10.10.10.140 Mask:255.255.255.255 UP LOOPBACK RUNNING MTU:65536 Metric:1 [root@RS1 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.10.10.140 0.0.0.0 255.255.255.255 UH 0 0 0 lo 10.10.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 10.10.10.2 0.0.0.0 UG 0 0 0 eth0 配置httpd服務: [root@RS1 ~]# yum -y install httpd [root@RS1 ~]# service httpd start [root@RS1 ~]# chkconfig httpd on [root@RS1 ~]# echo "10.10.10.131">/var/www/html/index 配置ARP抑制: [root@RS1 ~]# echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore [root@RS1 ~]# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore [root@RS1 ~]# echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce [root@RS1 ~]# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce 補充資料: arp_announce: 說明:對網絡接口上,本地IP地址的發出的,ARP回應,作出相應級別的限制: 確定不同程度的限制,宣布對來自本地源IP地址發出Arp請求的接口 0 - (默認) 在任意網絡接口(eth0,eth1,lo)上的任何本地地址 1 -盡量避免不在該網絡接口子網段的本地地址做出arp回應. 當發起ARP請求的源IP地址是被設置應該經由路由達到此網絡接口的時候很有用.此時會檢查來訪IP是否為所有接口上的子網段內ip之一.如果改來訪IP不屬于各個網絡接口上的子網段內,那么將采用級別2的方式來進行處理. 2 - 對查詢目標使用最適當的本地地址.在此模式下將忽略這個IP數據包的源地址并嘗試選擇與能與該地址通信 arp_ignore: 說明:定義對目標地址為本地IP的ARP詢問不同的應答模式0 0 - (默認值): 回應任何網絡接口上對任何本地IP地址的arp查詢請求 1 - 只回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求 2 -只回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求,且來訪IP必須在該網絡接口的子網段內 3 - 不回應該網絡界面的arp請求,而只對設置的唯一和連接地址做出回應 4-7 - 保留未使用 8 -不回應所有(本地地址)的arp查詢
RS2的配置:
清空iptables策略: [root@C67-X64-A3 ~]# iptables -X [root@C67-X64-A3 ~]# iptables -F [root@C67-X64-A3 ~]# iptables -Z [root@C67-X64-A3 ~]# service iptables stop iptables:將鏈設置為政策 ACCEPT:filter [確定] iptables:清除防火墻規則: [確定] iptables:正在卸載模塊: [確定] [root@C67-X64-A3 ~]# chkconfig iptables off 綁定lo地址(注意網關為255.255.255.255): [root@RS2 ~]# ifconfig lo:0 10.10.10.140 netmask 255.255.255.255 up [root@RS2 ~]# route add -host 10.10.10.140 dev lo [root@RS2 ~]# ifconfig -a eth0 Link encap:Ethernet HWaddr 00:0C:29:D7:1F:73 inet addr:10.10.10.132 Bcast:10.10.10.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fed7:1f73/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2671 errors:0 dropped:0 overruns:0 frame:0 TX packets:450 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:176939 (172.7 KiB) TX bytes:48342 (47.2 KiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:4 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:240 (240.0 b) TX bytes:240 (240.0 b) lo:0 Link encap:Local Loopback inet addr:10.10.10.140 Mask:255.255.255.255 UP LOOPBACK RUNNING MTU:65536 Metric:1 [root@RS2 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.10.10.140 0.0.0.0 255.255.255.255 UH 0 0 0 lo 10.10.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 10.10.10.2 0.0.0.0 UG 0 0 0 eth0 配置httpd服務: [root@RS2 ~]# yum -y install httpd [root@RS2 ~]# service httpd start [root@RS2 ~]# chkconfig httpd on [root@RS2 ~]# echo "10.10.10.132">/var/www/html/index 配置ARP抑制: [root@RS2 ~]# echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore [root@RS2 ~]# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore [root@RS2 ~]# echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce [root@RS2 ~]# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce 補充資料: arp_announce: 說明:對網絡接口上,本地IP地址的發出的,ARP回應,作出相應級別的限制: 確定不同程度的限制,宣布對來自本地源IP地址發出Arp請求的接口 0 - (默認) 在任意網絡接口(eth0,eth1,lo)上的任何本地地址 1 -盡量避免不在該網絡接口子網段的本地地址做出arp回應. 當發起ARP請求的源IP地址是被設置應該經由路由達到此網絡接口的時候很有用.此時會檢查來訪IP是否為所有接口上的子網段內ip之一.如果改來訪IP不屬于各個網絡接口上的子網段內,那么將采用級別2的方式來進行處理. 2 - 對查詢目標使用最適當的本地地址.在此模式下將忽略這個IP數據包的源地址并嘗試選擇與能與該地址通信 arp_ignore: 說明:定義對目標地址為本地IP的ARP詢問不同的應答模式0 0 - (默認值): 回應任何網絡接口上對任何本地IP地址的arp查詢請求 1 - 只回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求 2 -只回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求,且來訪IP必須在該網絡接口的子網段內 3 - 不回應該網絡界面的arp請求,而只對設置的唯一和連接地址做出回應 4-7 - 保留未使用 8 -不回應所有(本地地址)的arp查詢
到此LVS-DR模式的配置基本完成,實際工作中,我們大多不會手動進行配置,而是寫成配置腳本
編譯LVS報錯:(解決CentOS 6.7下編譯安裝ipvsadm-1.26報錯)
[root@DR1 ipvsadm-1.26]# make make -C libipvs make[1]: Entering directory `/usr/local/src/ipvsadm-1.26/libipvs' gcc -Wall -Wunused -Wstrict-prototypes -g -fPIC -DLIBIPVS_USE_NL -DHAVE_NET_IP_VS_H -c -o libipvs.o libipvs.c gcc -Wall -Wunused -Wstrict-prototypes -g -fPIC -DLIBIPVS_USE_NL -DHAVE_NET_IP_VS_H -c -o ip_vs_nl_policy.o ip_vs_nl_policy.c ar rv libipvs.a libipvs.o ip_vs_nl_policy.o ar: creating libipvs.a a - libipvs.o a - ip_vs_nl_policy.o gcc -shared -Wl,-soname,libipvs.so -o libipvs.so libipvs.o ip_vs_nl_policy.o make[1]: Leaving directory `/usr/local/src/ipvsadm-1.26/libipvs' gcc -Wall -Wunused -Wstrict-prototypes -g -DVERSION=\"1.26\" -DSCHEDULERS=\""rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq"\" -DPE_LIST=\""sip"\" -DHAVE_NET_IP_VS_H -c -o ipvsadm.o ipvsadm.c ipvsadm.c: 在函數‘print_largenum’中: ipvsadm.c:1383: 警告:域寬 的類型應該是‘int’,但實參 2 的類型為‘size_t’ gcc -Wall -Wunused -Wstrict-prototypes -g -DVERSION=\"1.26\" -DSCHEDULERS=\""rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq"\" -DPE_LIST=\""sip"\" -DHAVE_NET_IP_VS_H -c -o config_stream.o config_stream.c gcc -Wall -Wunused -Wstrict-prototypes -g -DVERSION=\"1.26\" -DSCHEDULERS=\""rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq"\" -DPE_LIST=\""sip"\" -DHAVE_NET_IP_VS_H -c -o dynamic_array.o dynamic_array.c gcc -Wall -Wunused -Wstrict-prototypes -g -o ipvsadm ipvsadm.o config_stream.o dynamic_array.o libipvs/libipvs.a -lnl ipvsadm.o: In function `parse_options': /usr/local/src/ipvsadm-1.26/ipvsadm.c:432: undefined reference to `poptGetContext' /usr/local/src/ipvsadm-1.26/ipvsadm.c:435: undefined reference to `poptGetNextOpt' /usr/local/src/ipvsadm-1.26/ipvsadm.c:660: undefined reference to `poptBadOption' /usr/local/src/ipvsadm-1.26/ipvsadm.c:502: undefined reference to `poptGetNextOpt' /usr/local/src/ipvsadm-1.26/ipvsadm.c:667: undefined reference to `poptStrerror' /usr/local/src/ipvsadm-1.26/ipvsadm.c:667: undefined reference to `poptBadOption' /usr/local/src/ipvsadm-1.26/ipvsadm.c:670: undefined reference to `poptFreeContext' /usr/local/src/ipvsadm-1.26/ipvsadm.c:677: undefined reference to `poptGetArg' /usr/local/src/ipvsadm-1.26/ipvsadm.c:678: undefined reference to `poptGetArg' /usr/local/src/ipvsadm-1.26/ipvsadm.c:679: undefined reference to `poptGetArg' /usr/local/src/ipvsadm-1.26/ipvsadm.c:690: undefined reference to `poptGetArg' /usr/local/src/ipvsadm-1.26/ipvsadm.c:693: undefined reference to `poptFreeContext' collect2: ld 返回 1 make: *** [ipvsadm] 錯誤 1 [root@DR1 ipvsadm-1.26]# echo $? 2
解決方法:
[root@DR1 ipvsadm-1.26]# yum -y install popt-static [root@DR1 ipvsadm-1.26]# make make -C libipvs make[1]: Entering directory `/usr/local/src/ipvsadm-1.26/libipvs' make[1]: Nothing to be done for `all'. make[1]: Leaving directory `/usr/local/src/ipvsadm-1.26/libipvs' gcc -Wall -Wunused -Wstrict-prototypes -g -o ipvsadm ipvsadm.o config_stream.o dynamic_array.o libipvs/libipvs.a -lpopt -lnl [root@DR1 ipvsadm-1.26]# echo $? 0
參考資料:
http://vqiao.blog.51cto.com/9368913/1571200
http://oldboy.blog.51cto.com/2561410/1240412
lvs-dr為前段調度器的腳本
lvs-rs為后端Real Server的腳本
原創文章,作者:Net21-冰凍vs西瓜,如若轉載,請注明出處:http://www.www58058.com/42589