前言
集羣:將多臺主機組織起來統一調度,滿足某一特定需求。
集羣類型:
1)LB:Load Balancing 負載均衡集羣;
2)HA:High Availability 高可用集羣;
3)HP:High Performance 高性能集羣;
4)DS:Distributed System 分佈式系統;
LB集羣的軟件實現:lvs
lvs:Linux Virtual Server(四層交換,四層路由)
根據調度算法將請求報文的目標IP和目標PORT轉發至後端主機集羣中的某臺服務器;
lvs集羣的術語:
vs:Virtul Server
rs:Real Server
CIP:Client IP
VIP:Director Virtual IP
DIP:Director IP
RIP:Real Server IP
lvs的實現:
ipvsadm:用戶空間的命令行工具,用於管理集羣服務及集羣服務上的RS等;
ipvs:工作於內核上的netfilter INPUT鉤子之上的程序代碼;
(其集羣的功能依賴於ipvsadm定義的集羣服務器規則)
LVS-TYPE:
(1)lvs-nat:MASQUERADE
多目標的DNAT:通過將請求報文的目標地址和目標端口修改爲挑選出的某RS的RIP和PORT來實現
①RIP和DIP應該使用私網地址,RS的網關應該指向DIP;
②請求和響應報文都要經由director轉發;極高負載的場景中,Director可能會成爲系統瓶頸
③支持端口映射;
④vs必須爲Linux,RS可以爲任意OS;
⑤RS的RIP與Director的DIP必須在同一IP網絡中;
(2)lvs-dr:GATEWAY
通過修改請求報文的MAC地址進行轉發,IP首部不會發生變化(源IP始終爲CIP,目標IP始終爲VIP);
①確保前端路由器將目標IP爲VIP的請求報文一定會送給Director;
解決方案:靜態綁定;
禁止RS響應VIP的ARP請求;
a)arptables;
b)修改各RS的內核參數,並把VIP配置在特定的接口上實現禁止其響應;
②RS的RIP可以使用私有地址,也可以使用公網地址;
③RS跟Director必須在同一物理網絡中;
④請求報文必須由Director調度,但響應報文必須不能經過Director;
⑤不支持端口映射;
⑥各RS支持大多數的OS;
(3) lvs-tun:IPIP
不修改請求報文的ip首部,而是在原有的ip首部之外再次封裝一個ip首部;
①RIP,DIP,VIP必須都是公網地址;
②RS網關不能指向DIP
③請求報文經由Director調度,但響應報文將直接發給CIP;
④不支持端口映射;
⑤RS的OS必須支持ip隧道功能;
(4)lvs-fullnat
通過同時修改請求報文的源ip和目標ip實現轉發;
①VIP是公網地址;RIP和DIP是私網地址,且可以不在同一IP網絡中,但需要通過路由互相通信;
②RS收到請求報文的源IP爲DIP,因此其響應報文將發送給DIP;
③請求報文和響應報文都必須經由DIrector;
④支持端口映射;
⑤RS可使用任意OS;
lvs scheduler(lvs的調度方法):當用戶請求到達時必須調度請求到後端的real server
(1)靜態方法:僅根據算法本身調度,而不考慮當前的RS的負載狀態;
1)RR:round robin,輪調;
2)WRR:weighted rr,加權輪調;(根據RS負載能力進行調度,權重大的負載多;)
3)SH:source ip hash,源地址哈希;(session綁定的方式,在director上維護一張鍵值對hash表,源ip地址爲鍵,RS的IP爲值,當請求到達時,可以根據hash表來查找源ip曾經到達的RSip,並將請求發往同一個RS,當請求到達時沒有hash記錄就使用加權輪調的算法調度RS;缺點:粒度過大,過於粗糙,久而久之會損壞負載均衡的效果)
4)DH:desination ip hash,目標地址哈希;(正向web代理,負載內網用戶對互聯網的請求;Client-->Director-->Web Cache Server)
(2)動態方法:根據算法及各RS當前的負載狀態進行評估;
基於Overhead(負載值),值小的優先調度;
1)LC:least connection(最少連接)
Overhead=Active*256+Inactive
2)WLC:weighted LC
Overhead=(Active*256+Inactive)/weight
3)SED:Shortest Expection Delay(最短期望延遲)
Overhead=(Active+1)*256/weight
4)NQ:Nerver Queue(永不排隊,SED算法的改進)
先按照權重由高到低各調度一個請求,再使用SED算法進行統一調度
5)LBLC:Locality-Based LC(基於本地的最少連接)
動態的DH算法;
Client-->Director-->Web Cache Server(正向代理)
6)LBLCR:LBLC with Replication,帶複製功能的LBLC;
(每個算法的出現都是爲了彌補上一個算法的缺陷)
lvs-nat的架構:
(1)配置負載均衡器
[root@Director ~]# ifconfig #準備一臺負載均衡器,一個網卡模擬外網地址VIP,一個網卡是DIP,分別接到兩個不同的交換機上 eth0 Link encap:Ethernet HWaddr 00:0C:29:1D:BA:F1 inet addr:172.16.100.123 Bcast:172.16.255.255 Mask:255.255.0.0 inet6 addr: fe80::20c:29ff:fe1d:baf1/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:7285 errors:0 dropped:0 overruns:0 frame:0 TX packets:456 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:588563 (574.7 KiB) TX bytes:52419 (51.1 KiB) eth1 Link encap:Ethernet HWaddr 00:0C:29:1D:BA:FB #後端遠程節點的交換機要和此網卡連接到一起 inet addr:192.168.16.3 Bcast:192.168.16.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fe1d:bafb/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:7 errors:0 dropped:0 overruns:0 frame:0 TX packets:28 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:420 (420.0 b) TX bytes:1848 (1.8 KiB) [root@Director ~]# echo 1 > /proc/sys/net/ipv4/ip_forward #開啓負載均衡器的轉發功能 [root@Director ~]# cat /proc/sys/net/ipv4/ip_forward 1
(2)配置兩臺後端遠程節點
[root@node1 ~]# ifconfig #第一臺遠程節點ip地址 eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.61.2 netmask 255.255.255.0 broadcast 192.168.61.255 inet6 fe80::20c:29ff:fe70:e227 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:70:e2:27 txqueuelen 1000 (Ethernet) RX packets 4791 bytes 393497 (384.2 KiB) RX errors 0 dropped 10 overruns 0 frame 0 TX packets 283 bytes 33580 (32.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@node1 ~]# route -n #配置路由指向負載均衡器的DIP Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.61.3 0.0.0.0 UG 100 0 0 eno16777736 [root@node2 ~]# ifconfig #第二臺遠程節點ip地址 eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.61.1 netmask 255.255.255.0 broadcast 192.168.61.255 inet6 fe80::20c:29ff:fefe:9633 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:fe:96:33 txqueuelen 1000 (Ethernet) RX packets 4718 bytes 387058 (377.9 KiB) RX errors 0 dropped 10 overruns 0 frame 0 TX packets 195 bytes 24091 (23.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@node2 ~]# route -n #配置路由指向負載均衡器的DIP Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.61.3 0.0.0.0 UG 100 0 0 eno16777736 192.168.61.0 0.0.0.0 255.255.255.0 U 0 0 0 eno16777736
(3)配置負載均衡器
[root@Director ~]# ipvsadm -A -t 172.16.100.123:80 -s rr #配置負載均衡的VIP爲172.16.100.123,並設置調度算法爲rr ,並指明調度80端口的服務 [root@Director ~]# ipvsadm -a -t 172.16.100.123:80 -r 192.168.61.1:80 -m #增加兩臺遠程調度節點,並指明類型爲nat [root@Director ~]# ipvsadm -a -t 172.16.100.123:80 -r 192.168.61.2:80 -m [root@Director ~]# ipvsadm IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.123:http rr -> 192.168.61.1:http Masq 1 0 0 -> 192.168.61.2:http Masq 1 0 0
(4)測試:
[root@node1 ~]# systemctl start httpd #開啓遠程節點的http服務 [root@node1 ~]# vim /var/www/html/index.html #配置httpd主頁 <h1>192.168.61.1</h1> [root@node2 ~]# systemctl start httpd [root@node2 ~]# vim /var/www/html/index.html <h1>192.168.61.1</h1> [root@localhost ~]# curl 172.16.100.123 #在測試主機上請求http服務 <h1>192.168.61.2</h1> [root@localhost ~]# curl 172.16.100.123 <h1>192.168.61.1</h1> [root@localhost ~]# curl 172.16.100.123 <h1>192.168.61.2</h1>
lvs-dr模型架構:
(1)配置負載均衡器(VIP、RIP在同一網段內):
注:負載均衡器和後端服務器都要配置一個VIP地址,爲了能夠接收請求,但掩碼必須爲255,255,255,255,廣播地址也必須爲自己,同時後端服務器的網卡內核參數的arp_ignore設置爲1,arp_announce設置爲2,使後端節點增加VIP時不會廣播該地址,避免客戶端請求直接發送到後端節點。
[root@Director ~]# ifconfig #負載均衡器配置 eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 #此爲DIP inet 172.16.61.100 netmask 255.255.0.0 broadcast 172.16.255.255 inet6 fe80::20c:29ff:feb7:d79d prefixlen 64 scopeid 0x20<link> ether 00:0c:29:b7:d7:9d txqueuelen 1000 (Ethernet) RX packets 23828 bytes 1886786 (1.7 MiB) RX errors 0 dropped 38 overruns 0 frame 0 TX packets 942 bytes 97487 (95.2 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eno16777736:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 #此爲VIP inet 172.16.61.9 netmask 255.255.255.255 broadcast 172.16.61.9 ether 00:0c:29:b7:d7:9d txqueuelen 1000 (Ethernet) [root@Director ~]# ipvsadm -A -t 172.16.61.9:80 -s rr #配置集羣服務,調度算法爲rr [root@Director ~]# ipvsadm -a -t 172.16.61.9:80 -r 172.16.61.2:80 -g #配置RS類型爲gateway [root@Director ~]# ipvsadm -a -t 172.16.61.9:80 -r 172.16.61.3:80 -g
(2)配置後端RS
[root@node1 ~]# cat /proc/sys/net/ipv4/conf/all/arp_ignore #增加vip時要先更改此兩項內核參數 1 [root@node1 ~]# cat /proc/sys/net/ipv4/conf/all/arp_announce 2 [root@node1 ~]# ifconfig eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.16.61.2 netmask 255.255.0.0 broadcast 172.16.255.255 inet6 fe80::20c:29ff:fefe:9633 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:fe:96:33 txqueuelen 1000 (Ethernet) RX packets 9373 bytes 784171 (765.7 KiB) RX errors 0 dropped 22 overruns 0 frame 0 TX packets 856 bytes 132887 (129.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 0 (Local Loopback) RX packets 1228 bytes 107680 (105.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1228 bytes 107680 (105.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 #VIP要配置在本地環回地址 inet 172.16.61.9 netmask 255.255.255.255 loop txqueuelen 0 (Local Loopback) [root@node1 ~]# route -n #配置路由vip路由 Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 172.16.0.0 0.0.0.0 255.255.0.0 U 100 0 0 eno16777736 172.16.61.9 0.0.0.0 255.255.255.255 UH 0 0 0 lo [root@node1 ~]# vim /var/www/html/index.html <h1>172.16.61.2</h1> [root@node1 ~]# systemctl start httpd [root@node2 ~]# cat /proc/sys/net/ipv4/conf/all/arp_ignore 1 [root@node2 ~]# cat /proc/sys/net/ipv4/conf/all/arp_announce 2 [root@node2 ~]# ifconfig eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.16.61.3 netmask 255.255.0.0 broadcast 172.16.255.255 inet6 fe80::20c:29ff:fe70:e227 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:70:e2:27 txqueuelen 1000 (Ethernet) RX packets 11479 bytes 948089 (925.8 KiB) RX errors 0 dropped 25 overruns 0 frame 0 TX packets 1063 bytes 168820 (164.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 0 (Local Loopback) RX packets 1188 bytes 103452 (101.0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1188 bytes 103452 (101.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 172.16.61.9 netmask 255.255.255.255 loop txqueuelen 0 (Local Loopback) [root@node2 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 172.16.0.0 0.0.0.0 255.255.0.0 U 100 0 0 eno16777736 172.16.61.9 0.0.0.0 255.255.255.255 UH 0 0 0 lo [root@node2 ~]# vim /var/www/html/index.html <h1>172.16.61.3</h1> [root@node2 ~]# systemctl start httpd
(3)測試:
[root@CentOS_6 ~]# curl 172.16.61.9 <h1>172.16.61.3</h1> [root@CentOS_6 ~]# curl 172.16.61.9 <h1>172.16.61.2</h1>
基於防火牆標記定義集羣服務:
[root@Director ~]# iptables -t mangle -A PREROUTING -d 172.16.61.9 -p tcp --dport 80 -j MARK --set-mark 3 #先在防火牆的mangle表的PREROUTING鏈上爲到達vip的請求打上標記 [root@Director ~]# ipvsadm -A -f 3 -s rr #基於防火牆標記定義集羣服務 [root@Director ~]# ipvsadm -a -f 3 -r 172.16.61.2 -g #增加RS [root@Director ~]# ipvsadm -a -f 3 -r 172.16.61.3 -g [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 FWM 3 rr -> 172.16.61.2:0 Route 1 0 0 -> 172.16.61.3:0 Route 1 0 0
lvs persistence:持久連接
功能:無論ipvs使用何種調度算法,其都能實現在指定時間範圍內始終將來自於同一個ip地址的請求發往同一個RS;此功能是通過lvs持久連接模版(持久連接hash表)實現,其與調度算法無關;
模式:
每端口持久(ppc)
每客戶端持久(pcc)
每FWM持久(PFWMC)
[root@Director ~]# ipvsadm -A -t 172.16.61.9:80 -s rr -p #基於端口持久,默認時間360s [root@Director ~]# ipvsadm -a -t 172.16.61.9:80 -r 172.16.61.2 -g [root@Director ~]# ipvsadm -a -t 172.16.61.9:80 -r 172.16.61.3 -g [root@Director ~]# ipvsadm IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.61.9:http rr persistent 360 -> 172.16.61.2:http Route 1 0 0 -> 172.16.61.3:http Route 1 0 0 [root@CentOS_6 ~]# curl 172.16.61.9 #測試 <h1>172.16.61.3</h1> [root@CentOS_6 ~]# curl 172.16.61.9 <h1>172.16.61.3</h1> [root@CentOS_6 ~]# curl 172.16.61.9 <h1>172.16.61.3</h1> [root@CentOS_6 ~]# curl 172.16.61.9 <h1>172.16.61.3</h1>