前篇文章我們主要講解了LVS-DR模型的架構方式以及如何實現,想了解的小伙伴點這個LVS-NAT模型實現負載均衡 ,今天我們來進行實踐的LVS中三種模型中的DR模型的架構以及實現方式。(實驗環境還以Web集群作為實驗對象)
此處我們LVS-DR模型環境架構也用四台Linux服務器,都有以下配置。
基於DR機制實現。當用戶請求到達director之後,此時Director知道client請求的為一個集群服務(Director有一塊網卡,此塊網卡配置了DIP【對內】,又配置了一個網卡別名VIP【對外公網訪問】),那麼director不會改變原有的IP頭部,通過指定的調度算法,選擇任意一台RealServer,通過DIP和RealServer的RIP在同一個物理網絡內進行AIP廣播請求,請求到此台RealServer的MAC之後,再將MAC地址封裝為此台RealServer的MAC,然後發給此台RealServer,注意此時的源地址和目標地址沒有改變,RealServer進行解包發現目標地址為VIP(RealServer有一塊網卡:此塊網卡配置了RIP【對內】,還在本地回環接口lookback口配置了一個隱藏網卡別名的VIP),自己有一個VIP,那麼進行解封裝,再將源地址為VIP目標地址為Client的CIP進行封裝然後把數據發送給用戶(此時不在經過Director,直接發給客戶端),完成整個負載調度過程。
使用軟件VMware WorkStation 11,Director的DIP和RealServer的RS1、RS2為橋接模式,讓其在同一個物理局域網內。(只作為測試環境)
一台Director:這裡我們為了模擬的更切合真實環境,所以Client請求的和RealServer的RIP不在同一網段,那麼就需要一個Route設備,這裡可選,你也可以使用全部都在一個物理網絡內
一台Route:搭建LVS集群只需要在Director服務器上安裝ipvsadmin工具,此處我們使用RedHat自帶的rpm包進行安裝
版本:ipvsadm-1.25-10.el6.x86_64.rpm
[root@route ~]# service ntpd restart # 重啟ntp服務器
Shutting down ntpd: [ OK ]
Starting ntpd: [ OK ]
[root@Director ~]# ntpdate 192.168.40.254 # 客戶端同步三台都要同步這裡我們就不多說了
查看內核版本
現在LVS已經是Linux標准內核的一部分,在Linux2.4內核以前,使用LVS時必須要重新編譯內核以支持LVS功能模塊,但是從Linux2.4內核以後,已經完全內置了LVS的各個功能模塊,無需給內核打任何補丁,可以直接使用LVS提供的各種功能。
[root@Director Packages]# uname -r # 此處我們環境內核版本為2.6.32-358.el6.x86_64,所以不需要再打補丁,如果你的內核低於2.4那麼則需要提前打補丁
2.6.32-358.el6.x86_64
查看內核是否支持ipvs
[root@Director ~]# modprobe -l | grep ipvs # 以下有之前所解釋的十個內核所支持的算法(如果能有以下搜索到那麼你的內核就支持ipvs)
kernel/net/netfilter/ipvs/ip_vs.ko
kernel/net/netfilter/ipvs/ip_vs_rr.ko
kernel/net/netfilter/ipvs/ip_vs_wrr.ko
kernel/net/netfilter/ipvs/ip_vs_lc.ko
kernel/net/netfilter/ipvs/ip_vs_wlc.ko
kernel/net/netfilter/ipvs/ip_vs_lblc.ko
kernel/net/netfilter/ipvs/ip_vs_lblcr.ko
kernel/net/netfilter/ipvs/ip_vs_dh.ko
kernel/net/netfilter/ipvs/ip_vs_sh.ko
kernel/net/netfilter/ipvs/ip_vs_sed.ko
kernel/net/netfilter/ipvs/ip_vs_nq.ko
kernel/net/netfilter/ipvs/ip_vs_ftp.ko
配置本地YUM源
我們使用本地光盤來作為YUM源
掛載本地光盤
[root@Director ~]# mount /dev/sr0 /media # 掛載本地光盤到本地目錄
mount: block device /dev/sr0 is write-protected, mounting read-only
配置編輯YUM源的配置文件
三台服務器我們都需要配置,因為後面兩台RealServer我們還需要安裝web服務來作為集群服務。
[root@Director ~]# vim /etc/yum.repos.d/rhel-source.repo
[localhost] # 庫名稱(可隨意)
name=localhost # 名稱描述 (自定義)
baseurl=file:///media # yum源目錄,源地址
enabled=1 # 是否用該yum源,0為禁用,1為使用
gpgcheck=0 # 檢查GPG-KEY,0為不檢查,1為檢查
到此我們安裝前准備就做好了,來下面進行下一步
配置RouteServer
配置兩個網卡的IP地址
[root@route ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=192.168.40.254
NETMASK=255.255.255.0
[root@route ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth2
DEVICE=eth2
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=172.16.0.254
NETMASK=255.255.0.0
[root@route ~]# service network restart # 重啟network服務
Shutting down interface eth1: [ OK ]
Shutting down interface eth2: [ OK ]
Shutting down loopback interface: [ OK ]
Bringing up loopback interface: [ OK ]
Bringing up interface eth1: [ OK ]
Bringing up interface eth2: [ OK ]
[root@route ~]# ifconfig # 查看是否配置生效
eth1 Link encap:Ethernet HWaddr 00:0C:29:22:E7:C7
inet addr:192.168.40.254 Bcast:192.168.40.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe22:e7c7/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:609 errors:0 dropped:0 overruns:0 frame:0
TX packets:292 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:57640 (56.2 KiB) TX bytes:22985 (22.4 KiB)
eth2 Link encap:Ethernet HWaddr 00:0C:29:22:E7:D1
inet addr:172.16.0.254 Bcast:172.16.255.255 Mask:255.255.0.0
inet6 addr: fe80::20c:29ff:fe22:e7d1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:5316 errors:0 dropped:0 overruns:0 frame:0
TX packets:4282 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:493923 (482.3 KiB) TX bytes:598669 (584.6 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:16436 Metric:1
RX packets:9965 errors:0 dropped:0 overruns:0 frame:0
TX packets:9965 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1049774 (1.0 MiB) TX bytes:1049774 (1.0 MiB)
開啟本地路由轉發
[root@route ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1 # 將0更改為1即可
[root@route ~]# sysctl -p # 刷新重新生效
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
配置DirecotrServer
安裝ipvsadm工具
[root@Director Packages]# yum install -y ipvsadm-1.25-10.el6.x86_64.rpm
配置網卡,並設置IP
配置內網網卡DIP
[root@Director ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1 # 此處我們不指定GATEWAY(真實生產跟其環境架構而定)
DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=192.168.40.11
NETMASK=255.255.255.0
配置外網網卡別名VIP
[root@Director ~]# cp /etc/sysconfig/network-scripts/ifcfg-eth1 /etc/sysconfig/network-scripts/ifcfg-eth1:0 # 拷貝DIP的配置文件
[root@Director ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1:0 # 此內網網卡可不指定GATEWAY,因為和後台RealServer在同一個局域網(但也要根據真實環境而定)
DEVICE=eth1:0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=172.16.21.10
NETMASK=255.255.0.0
重啟網卡服務
[root@Director ~]# service network restart
Shutting down interface eth1: [ OK ]
Shutting down loopback interface: [ OK ]
Bringing up loopback interface: [ OK ]
Bringing up interface eth1: [ OK ]
[root@Director ~]# ifconfig # 查看配置是否生效
eth1 Link encap:Ethernet HWaddr 00:0C:29:E5:9A:47
inet addr:192.168.40.11 Bcast:192.168.40.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fee5:9a47/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3289 errors:0 dropped:0 overruns:0 frame:0
TX packets:2421 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:305233 (298.0 KiB) TX bytes:324497 (316.8 KiB)
eth1:0 Link encap:Ethernet HWaddr 00:0C:29:E5:9A:47
inet addr:172.16.21.10 Bcast:172.16.255.255 Mask:255.255.0.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:16436 Metric:1
RX packets:17 errors:0 dropped:0 overruns:0 frame:0
TX packets:17 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1284 (1.2 KiB) TX bytes:1284 (1.2 KiB)
清空本地防火牆策略
[root@Director ~]# iptables -F
配置RealServer服務器
配置RealServer1網卡的RIP
[root@RS1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1 # 根據我們此時的環境一定要將網關指向RouteServer的192.168.40.254,因為ReaServer響應Client的時候不在一個網絡不能直接路由
DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.40.12
NETMASK=255.255.255.0
GATEWAY=192.168.40.254
NM_CONTROLLED=yes
配置內核參數
由於我們Director和兩台RealServer都配置VIP地址,那麼客戶在請求VIP時,都有配置VIP,都會響應,這樣的話網絡就亂了,不知道包應該發給誰了,也就達不到我們所說的負載均衡的作用了,下面我們需要只要Client請求VIP時,只能Director來響應,那麼我們有以下三個方案來解決這麼問題。
讓前段路由將請求發往VIP時,只能是Dirctor上的VIP響應
解決方案
靜態地址綁定:有時候我們未必有ISP路由器的配置權限,Director調用時靜態地址綁定將難以使用(Director做HA的時候那麼一台壞了,還得重新綁定) arptables:設定arptables規則來實現 修改linux內核參數:將RS上的VIP配置在lo接口的別名上,限制linux僅對對應接口的ARP請求做相應
第三種方法是我們最常用的,也是最實用的:
[root@RS1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS1 ~]# echo 1 > /proc/sys/net/ipv4/conf/eth1/arp_ignore
[root@RS1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@RS1 ~]# echo 2 > /proc/sys/net/ipv4/conf/eth1/arp_announce
配置RealServer1的隱藏的VIP
此配置步驟一定要在上一步配置完內核參數之後再進行配置,如果明白arp原理的小伙伴你懂的
[root@RS1 ~]# cp /etc/sysconfig/network-scripts/ifcfg-eth1 /etc/sysconfig/network-scripts/ifcfg-lo:0
[root@RS1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-lo:0 # NETMASK要為三個255,自己在一個廣播域裡,此網絡只有自己
DEVICE=lo:0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=172.16.21.10
NETMASK=255.255.255.255
GATEWAY=172.16.0.254
重啟網卡配置
[root@RS1 ~]# service network restart
Shutting down interface eth1: [ OK ]
Shutting down loopback interface: [ OK ]
Bringing up loopback interface: [ OK ]
Bringing up interface eth1: [ OK ]
[root@RS1 ~]# ifconfig # 查看配置是否生效
eth1 Link encap:Ethernet HWaddr 00:0C:29:41:4A:CC
inet addr:192.168.40.12 Bcast:192.168.40.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe41:4acc/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2749 errors:0 dropped:0 overruns:0 frame:0
TX packets:1871 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:265901 (259.6 KiB) TX bytes:241716 (236.0 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:16436 Metric:1
RX packets:2320 errors:0 dropped:0 overruns:0 frame:0
TX packets:2320 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:293374 (286.4 KiB) TX bytes:293374 (286.4 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.21.10 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
添加路由條目
此路由條目必須要添加的,意思就是只要是訪問本地VIP地址的,都從本地lo:0口進行轉發給eth1(因為只有eth1才是對外出去的,lo口只是本地回環地址,不能直接和外界通信) 記得是轉發給eth1,在從eth1進行傳出去,這樣eth1只是轉發,不會作為源地址。
[root@RS1 ~]# route add -host 172.16.21.10 dev lo:0
[root@RS1 ~]# route -n # 查看添加路由條目
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.16.21.10 0.0.0.0 255.255.255.255 UH 0 0 0 lo
192.168.40.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth1
0.0.0.0 192.168.40.1 0.0.0.0 UG 0 0 0 eth1
安裝Web服務
[root@RS1 ~]# yum install -y httpd
[root@RS1 ~]# service httpd start # 啟動httpd服務
Starting httpd: httpd: apr_sockaddr_info_get() failed for RS1
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
[ OK ]
[root@RS1 ~]# service httpd status # 查看httpd是否啟動
httpd (pid 11249) is running...
[root@RS1 ~]# netstat -an | grep :80 # 查看web服務80端口是否監聽
tcp 0 0 :::80 :::* LISTEN
[root@RS1 ~]# echo "RS1.xuxingzhuang.com" > /var/www/html/index.html # 給web服務提供網頁界面
[root@RS1 ~]# curl http://localhost # 訪問本地web是否可以正常訪問
RS1.xuxingzhuang.com
清空本地防火牆策略
[root@RS1 ~]# iptables -F
配置RealServer2網卡的RIP
[root@RS2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=192.168.40.13
NETMASK=255.255.255.0
GATEWAY=192.168.40.254
配置內核參數
[root@RS2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS2 ~]# echo 1 > /proc/sys/net/ipv4/conf/eth1/arp_ignore
[root@RS2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@RS2 ~]# echo 2 > /proc/sys/net/ipv4/conf/eth1/arp_announce
配置RealServer1的隱藏的VIP
[root@RS2 ~]# cp /etc/sysconfig/network-scripts/ifcfg-eth1 /etc/sysconfig/network-scripts/ifcfg-lo:0
[root@RS2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-lo:0
DEVICE=lo:0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=172.16.21.10
NETMASK=255.255.255.255
GATEWAY=172.16.0.254
重啟網卡配置
[root@RS2 ~]# service network restart
Shutting down interface eth1: [ OK ]
Shutting down loopback interface: [ OK ]
Bringing up loopback interface: [ OK ]
Bringing up interface eth1: [ OK ]
[root@RS2 ~]# ifconfig # 查看配置是否生效
eth1 Link encap:Ethernet HWaddr 00:0C:29:9A:31:FB
inet addr:192.168.40.13 Bcast:192.168.40.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe9a:31fb/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3401 errors:0 dropped:0 overruns:0 frame:0
TX packets:3027 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:291858 (285.0 KiB) TX bytes:1029009 (1004.8 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:16436 Metric:1
RX packets:2242 errors:0 dropped:0 overruns:0 frame:0
TX packets:2242 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:273214 (266.8 KiB) TX bytes:273214 (266.8 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.21.10 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
添加路由條目
[root@RS2 ~]# route add -host 172.16.21.10 dev lo:0
[root@RS2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.16.21.10 0.0.0.0 255.255.255.255 UH 0 0 0 lo
192.168.40.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth1
0.0.0.0 192.168.40.254 0.0.0.0 UG 0 0 0 eth1
安裝Web服務
[root@RS2 ~]# yum install -y httpd
[root@RS2 ~]# service httpd start # 啟動httpd服務
Starting httpd: httpd: apr_sockaddr_info_get() failed for RS1
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
[ OK ]
[root@RS2 ~]# service httpd status # 查看httpd是否啟動
httpd (pid 10833) is running...
[root@RS2 ~]# netstat -an | grep :80 # 查看web服務80端口是否監聽
tcp 0 0 :::80 :::* LISTEN
[root@RS2 ~]# echo "RS2.xuxingzhuang.com" > /var/www/html/index.html # 給web服務提供網頁界面
[root@RS2 ~]# curl http://localhost # 訪問本地web是否可以正常訪問
RS2.xuxingzhuang.com
清空本地防火牆策略
[root@RS2 ~]# iptables -F
配置Driector,並將RealServer加入集群服務
ipvsadm命令的用法
管理集群服務
添加:-A -t|u|f service-address [-s scheduler]
-t: TCP協議的集群 -u: UDP協議的集群
service-address: IP:PORT -f: FWM: 防火牆標記
service-address: Mark Number 修改:
-E 刪除:
-D -t|u|f service-address
管理集群服務中的RealServer
添加:
-a -t|u|f service-address -r server-address [-g|i|m] [-w weight] -t|u|f service-address:事先定義好的某集群服務 -r server-address: 某RS的地址,在DR模型中,可使用IP:PORT實現端口映射; [-g|i|m]: LVS類型 -g: DR -i: TUN -m: DR [-w weight]: 定義服務器權重 修改:
-e 刪除:
d -t|u|f service-address -r server-address
集群服務後續管理
查看
-L|l -n: 數字格式顯示主機地址和端口 –stats:統計數據 –rate: 速率 –timeout: 顯示tcp、tcpfin和udp的會話超時時長 -c: 顯示當前的ipvs連接狀況
例:ipvsadm -L -n –stats 刪除所有集群服務
-C:清空ipvs規則
例:ipvsadm -C 保存規則
-S
例: ipvsadm -S > /etc/sysconfig/ipvsadm 載入此前的規則:
-R
例:ipvsadm -R < /etc/sysconfig/ipvsadm
將RealServer加入Web集群服務
我們此時使用內核的rr調度算法來作為實驗,還不明白LVS的內核調度算法的小伙伴,請查看我們上一篇LVS集群服務詳解
使用rr調度算法(輪叫)
[root@Director ~]# ipvsadm -A -t 172.16.21.10:80 -s rr
[root@Director ~]# ipvsadm -a -t 172.16.21.10:80 -r 192.168.40.12 -g -w 2 # 此處的-w指定權重是沒有意義的,因為我們使用的為rr調度算法(輪叫),不過你也可以指定,後邊我們改變算法時就不用重新定義了,省去了時間
[root@Director ~]# ipvsadm -a -t 172.16.21.10:80 -r 192.168.40.13 -g -w 1
[root@Director ~]# ipvsadm -L -n # 查看集群服務
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.21.10:80 rr
-> 192.168.40.12:80 Route 2 0 0
-> 192.168.40.13:80 Route 1 0 0
測試web集群服務rr算法
END
到底我們就基於LVS-DR模型就搭建好了一個web服務集群,DR模型在我們生活中用的還是比較多的,最主要的還是理解,後面我們還會繼續寫一下HA高可用集群。