一、Cluster概念
系統擴展方式:
Scale UP:向上擴展,增強
Scale Out:向外擴展,增加設備,調度分配問題,Cluster
Cluster
集羣,爲解決某個特定問題將多臺計算機組合起來形成的單個系統
Linux Cluster類型:
LB:Load Balancing,負載均衡
HA:High Availiablity,高可用,SPOF(single Point Of failure)(單點失敗)
MTBF:Mean Time Between Failure 平均無故障時間
MTTR:Mean Time To Restoration( repair)平均恢復前時間
A=MTBF/(MTBF+MTTR)
(0,1):99%, 99.5%, 99.9%, 99.99%, 99.999%, 99.9999%
HPC:High-performance computing,高性能 www.top500.org
分佈式系統:
分佈式存儲:雲盤
分佈式計算:hadoop,Spark
1、Cluster分類
LB Cluster的實現
硬件
F5 Big-IP
Citrix Netscaler
A10 A10
軟件
lvs:Linux Virtual Server
nginx:支持四層調度
haproxy:支持四層調度
ats:apache traffic server,yahoo捐助
perlbal:Perl 編寫
pound
基於工作的協議層次劃分
傳輸層(通用):DPORT
LVS:
nginx:stream(語法格式)
haproxy:mode tcp
應用層(專用):針對特定協議,自定義的請求模型分類
proxy server:
http:nginx, httpd, haproxy(mode http), ...
fastcgi:nginx, httpd, ...
mysql:mysql-proxy, ...(讀寫分離)
2、Cluster相關
會話保持:負載均衡
(1) session sticky(粘滯位):同一用戶調度固定服務器
Source IP:LVS sh算法(對某一特定服務而言,弊端就是基於SNAT模式訪問服務器的,對服務器造成負責較大)
Cookie
(2) session replication:每臺服務器擁有全部session
session multicast cluster
(3) session server:專門的session服務器(專門存儲session信息)
Memcached,Redis支持session server的軟件
HA集羣實現方案
keepalived:vrrp協議
ais:應用接口規範
heartbeat
cman+rgmanager(RHCS)
coresync_pacemaker
二、LVS介紹
1、LVS概念
LVS:Linux Virtual Server,負載調度器,現在已經集成內核中,章文嵩 阿里
官網:http://www.linuxvirtualserver.org/
VS: Virtual Server(虛擬服務器),負責調度
RS: Real Server,負責真正提供服務
L4:四層路由器或交換機(基於TCP、UDP端口號、基於ip地址調度)
工作原理:VS根據請求報文的目標IP和目標協議及端口將其調度轉發至某RS,根據調度算法來挑選RS
iptables/netfilter:
iptables:用戶空間的管理工具
netfilter:內核空間上的框架
流入:PREROUTING --> INPUT
流出:OUTPUT --> POSTROUTING
轉發:PREROUTING --> FORWARD --> POSTROUTING
DNAT:目標地址轉換; PREROUTING
2、LVS集羣體系結構
3、lvs集羣類型中的術語
VS:Virtual Server,Director Server(DS)(導演服務器)
Dispatcher(調度器),Load Balancer(負載均衡器)
RS:Real Server(lvs), upstream server(nginx)(上游服務器)
backend server(haproxy)(後端服務器)
CIP:Client IP
VIP: Virtual serve IP VS外網的IP
DIP: Director IP VS內網的IP
RIP: Real server IP
訪問流程:CIP <--> VIP == DIP <--> RIP
lvs: ipvsadm/ipvs
ipvsadm:用戶空間的命令行工具,規則管理器用於管理集羣服務及RealServer
ipvs:工作於內核空間netfilter的INPUT鉤子上的框架
三、lvs集羣的類型
1、lvs集羣的類型
lvs-nat:修改請求報文的目標IP,多目標IP的DNAT(端口映射)
lvs-dr:操縱封裝新的MAC地址
lvs-tun:在原請求IP報文之外新加一個IP首部
lvs-fullnat:修改請求報文的源和目標IP
2、lvs-nat模式
本質是多目標IP的DNAT,通過將請求報文中的目標地址和目標端口修改爲某挑出的RS的RIP和PORT實現轉發
(1)RIP和DIP應在同一個IP網絡,且應使用私網地址;RS的網關要指向DIP
(2)請求報文和響應報文都必須經由Director轉發,Director易於成爲系統瓶頸
(3)支持端口映射,可修改請求報文的目標PORT
(4)VS必須是Linux系統,RS可以是任意OS系統
#實驗:NAT模型實現http負載均衡集羣、NAT模型實現https負載均衡集羣
注意:RS: 都要提供同一個私鑰和同一個證書
#1、關閉防火牆、SElinux、VS和RS同步時間 #2、配置相關網絡 #VS網絡配置 [root@VSserver~]#ip a #注意,生產環境中,VS服務器要配置GW 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:14:fe:3c brd ff:ff:ff:ff:ff:ff inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:14:fe:46 brd ff:ff:ff:ff:ff:ff inet 172.18.68.100/16 brd 172.18.255.255 scope global eth1 [root@VSserver~]#route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1003 0 0 eth1 0.0.0.0 172.18.0.100 0.0.0.0 UG 0 0 0 eth1 #RS網絡配置 [root@RS1~]#nmcli nmcli connection modify ens32 connection.id ens33 #修改網卡名字 [root@RS1~]#nmcli connection modify ens33 ipv4.addresses 172.18.68.103/16 ipv4.method manual [root@RS1~]#nmcli connection modify ens33 ipv4.gateway 172.18.68.100 #指定網管爲VS服務器的DIP [root@RS1~]#nmcli connection up ens33 Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3) [root@RS1~]#route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.18.68.100 0.0.0.0 UG 100 0 0 ens32 172.18.0.0 0.0.0.0 255.255.0.0 U 100 0 0 ens32 [root@RS1~]#nmcli connection show NAME UUID TYPE DEVICE ens33 c96bc909-188e-ec64-3a96-6a90982b08ad 802-3-ethernet ens32 [root@RS2~]#route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 172.18.0.0 0.0.0.0 255.255.0.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 172.18.68.100 0.0.0.0 UG 0 0 0 eth0 #客戶端網絡配置 [root@Client~]#ip a 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:06:23:22 brd ff:ff:ff:ff:ff:ff inet 192.168.1.101/24 brd 192.168.1.255 scope global ens33 [root@Client~]#route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.100 0.0.0.0 UG 100 0 0 ens33 192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33 #之間網絡互相可以ping通 [root@VSserver~]#ping -c 2 172.18.68.103 PING 172.18.68.103 (172.18.68.103) 56(84) bytes of data. 64 bytes from 172.18.68.103: icmp_seq=1 ttl=64 time=2.15 ms [root@VSserver~]#ping -c 2 172.18.68.104 PING 172.18.68.104 (172.18.68.104) 56(84) bytes of data. 64 bytes from 172.18.68.104: icmp_seq=1 ttl=64 time=0.975 ms [root@VSserver~]#ping -c 2 192.168.1.101 PING 192.168.1.101 (192.168.1.101) 56(84) bytes of data. 64 bytes from 192.168.1.101: icmp_seq=1 ttl=64 time=90.9 ms [root@RS1~]#ping -c 2 172.18.68.100 PING 172.18.68.100 (172.18.68.100) 56(84) bytes of data. 64 bytes from 172.18.68.100: icmp_seq=1 ttl=64 time=0.518 ms [root@RS1~]#ping -c 2 172.18.68.104 PING 172.18.68.104 (172.18.68.104) 56(84) bytes of data. 64 bytes from 172.18.68.104: icmp_seq=1 ttl=64 time=0.759 ms [root@RS1~]#ping -c 2 192.168.1.101 PING 192.168.1.101 (192.168.1.101) 56(84) bytes of data. 64 bytes from 192.168.1.101: icmp_seq=1 ttl=63 time=103 ms #3、VS服務器要啓用ip_forward [root@VSserver~]#vim /etc/sysctl.conf net.ipv4.ip_forward = 1 [root@VSserver~]#sysctl -p #生效下 #4、RS服務器安裝相關服務http [root@RS1~]#echo RS1 > /var/www/html/index.html [root@RS2~]#echo RS2 > /var/www/html/index.html [root@VSserver~]#curl 172.18.68.103 RS1 [root@VSserver~]#curl 172.18.68.104 RS2 #5、配置IPVS-NAT [root@VSserver~]#ipvsadm -A -t 192.168.1.100:80 -s rr [root@VSserver~]#ipvsadm -a -t 192.168.1.100:80 -r 172.18.68.103 -m [root@VSserver~]#ipvsadm -a -t 192.168.1.100:80 -r 172.18.68.104 -m [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.100:80 rr -> 172.18.68.103:80 Masq 1 0 0 -> 172.18.68.104:80 Masq 1 0 0 [root@Client~]#for i in {1..10} ; do curl 192.168.1.100 ; done RS1 RS2 #6、修改爲WRR模式 [root@VSserver~]#ipvsadm -E -t 192.168.1.100:80 -s wrr [root@VSserver~]#ipvsadm -e -t 192.168.1.100:80 -r 172.18.68.103 -w 3 -m [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.100:80 wrr -> 172.18.68.103:80 Masq 3 0 0 -> 172.18.68.104:80 Masq 1 0 0 [root@Client~]#for i in {1..10} ; do curl 192.168.1.100 ; done RS1 RS1 RS1 RS2 [root@RS1~]#tail /var/log/httpd/access_log 192.168.1.101 - - [04/Mar/2018:16:07:21 +0800] "GET / HTTP/1.1" 200 4 "-" "curl/7.29.0" #7、修改爲WLC模式 [root@VSserver~]#ipvsadm -E -t 192.168.1.100:80 -s wlc #8、啓用長連接 [root@RS2~]#vim /etc/httpd/conf/httpd.conf KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 150 [root@centos7mini~]#telnet 192.168.1.100 80 Trying 192.168.1.100... Connected to 192.168.1.100. Escape character is '^]'. GET /test.html HTTP/1.1 HOST:192.168.1.101 HTTP/1.1 200 OK Date: Tue, 23 Jan 2018 21:56:19 GMT 。。。 </body> </html> GET /test.txt HTTP/1.1 HOST:192.168.1.101 HTTP/1.1 200 OK Date: Tue, 23 Jan 2018 21:56:52 GMT 。。。 </body> </html> q #9、修改RS服務器的端口號 [root@VSserver~]#ipvsadm -d -t 192.168.1.100:80 -r 172.18.68.103 -m [root@VSserver~]#ipvsadm -a -t 192.168.1.100:80 -r 172.18.68.103:8080 -m
#實現https服務的調度 #簡單模式,先安裝 mod_ssl 模塊 [root@RS2~]#yum install mod_ssl [root@RS1~]#ss -ntl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 :::80 :::* LISTEN 0 128 :::443 :::* [root@RS1~]#rpm -ql --scripts mod_ssl #安裝這個模塊,就會自簽名頒發證書 postinstall scriptlet (using /bin/sh): umask 077 if [ -f /etc/pki/tls/private/localhost.key -o -f /etc/pki/tls/certs/localhost.crt ]; then exit 0 fi /usr/bin/openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 2048 > /etc/pki/tls/private/localhost.key 2> /dev/null FQDN=`hostname` if [ "x${FQDN}" = "x" -o ${#FQDN} -gt 59 ]; then FQDN=localhost.localdomain fi cat << EOF | /usr/bin/openssl req -new -key /etc/pki/tls/private/localhost.key \ -x509 -sha256 -days 365 -set_serial $RANDOM -extensions v3_req \ -out /etc/pki/tls/certs/localhost.crt 2>/dev/null -- SomeState SomeCity SomeOrganization SomeOrganizationalUnit ${FQDN} root@${FQDN} EOF /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.modules.d/00-ssl.conf /usr/lib64/httpd/modules/mod_ssl.so /usr/libexec/httpd-ssl-pass-dialog /var/cache/httpd/ssl #添加新的集羣 [root@VSserver~]#ipvsadm -A -t 192.168.1.100:443 #不加 -s 選項,默認就是wlc算法 [root@VSserver~]#ipvsadm -a -t 192.168.1.100:443 -r 172.18.68.103 -m [root@VSserver~]#ipvsadm -a -t 192.168.1.100:443 -r 172.18.68.104 -m [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.100:80 rr -> 172.18.68.103:80 Route 1 0 0 -> 172.18.68.104:80 Masq 1 0 0 TCP 192.168.1.100:443 wlc -> 172.18.68.103:443 Masq 1 0 0 -> 172.18.68.104:443 Masq 1 0 0 [root@centos7mini~]#for i in {1..100} ; do curl -k https://192.168.1.100/ ; done #-k就是忽略證書檢測
3、LVS-DR模式
LVS-DR:Direct Routing,直接路由,LVS默認模式,應用最廣泛,通過爲請求報文重新封裝一個MAC首部進行轉發,源MAC是DIP所在的接口的MAC,目標MAC是某挑選出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目標IP/PORT均保持不變
Director和各RS都配置有VIP
(1) 確保前端路由器將目標IP爲VIP的請求報文發往Director
在前端網關做靜態綁定VIP和Director的MAC地址
在RS上使用arptables工具
arptables -A IN -d $VIP -j DROP
arptables -A OUT -s $VIP -j mangle --mangle-ip-s $RIP
在RS上修改內核參數以限制arp通告及應答級別
arp_announce
arp_ignore
幫助文檔可以看 yum install kernel-doc
[root@cenots7a~]#less /usr/share/doc/kernel-doc-3.10.0/Documentation/networking/ip-sysctl.txt
(2) RS的RIP可以使用私網地址,也可以是公網地址;RIP與DIP在同一IP網絡;RIP的網關不能指向DIP,以確保響應報文不會經由Director
(3) RS和Director要在同一個物理網絡
(4) 請求報文要經由Director,但響應報文不經由Director,而由RS直接發往Client
(5) 不支持端口映射(端口不能修改)
(6) RS可使用大多數OS系統
arp_ignore - INTEGER 定義不同的發送回覆以響應收到的解析本地目標IP地址的ARP請求的模式: 0 - (默認):回覆在任何接口上配置的任何本地目標IP地址 1 - 僅當目標IP地址是入站接口上配置的本地地址時纔回復 2 - 僅當目標IP地址是入站接口上配置的本地地址且同時具有發件人IP地址的部分來自此接口上相同子網 3 - 不回覆使用作用域主機配置的本地地址,只回復全局和鏈接地址的分辨率 4-7 - 保留 8 - 不要回復所有本地地址 在{interface}接收到ARP請求時,使用來自conf / {all,interface} / arp_ignore的最大值 arp_announce - INTEGER 爲接口上發送的ARP請求中的IP數據包通告本地源IP地址,定義不同的限制級別: 0 - (默認)使用在任何接口上配置的任何本地地址 1 - 儘量避免本接口不在目標子網中的本地地址。當通過此接口可達的目標主機要求ARP請求中的源IP地址成爲其在接收接口上配置的邏輯網絡的一部分時,此模式非常有用。當我們生成請求時,我們將檢查包含目標IP的所有子網,並保留來自此子網的源地址。如果沒有這樣的子網,我們根據第2級的規則選擇源地址。 2 - 始終使用該目標的最佳本地地址。在這種模式下,我們忽略IP數據包中的源地址,並嘗試選擇我們更喜歡與目標主機進行會談的本地地址。通過在出站接口上的所有子網上查找包含目標IP地址的主IP地址來選擇此類本地地址。如果找不到合適的本地地址,我們會選擇出站接口或所有其他接口上的第一個本地地址,希望我們能收到我們請求的回覆,有時甚至不管我們發佈的源IP地址。 使用來自conf / {all,interface} / arp_announce的最大值。 限制級別的增加爲從解析目標接收答案提供了更多機會,而降低級別宣佈更有效的發件人信息。
#實驗:
R模型實現http負載均衡集羣
DR模型實現https負載均衡集羣
注意:RS: 都要提供同一個私鑰和同一個證書
DR模型實現mysql負載均衡集羣
#1、搭建網絡 #設置路由器的配置 [root@Router~]#nmcli connection modify ens33 +ipv4.addresses 10.0.0.200/24 [root@Router~]#ip a 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:cb:db:c3 brd ff:ff:ff:ff:ff:ff inet 192.168.1.200/24 brd 192.168.1.255 scope global ens32 valid_lft forever preferred_lft forever inet 10.0.0.200/24 brd 10.0.0.255 scope global ens32 valid_lft forever preferred_lft forever 3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:cb:db:cd brd ff:ff:ff:ff:ff:ff inet 172.18.68.200/16 brd 172.18.255.255 scope global ens33 valid_lft forever preferred_lft forever [root@Router~]#route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32 172.18.0.0 0.0.0.0 255.255.0.0 U 100 0 0 ens33 192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32 客戶端設置 [root@Client~]#ip a 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:06:23:22 brd ff:ff:ff:ff:ff:ff inet 192.168.1.101/24 brd 192.168.1.255 scope global ens33 valid_lft forever preferred_lft forever [root@Client~]#route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.200 0.0.0.0 UG 100 0 0 ens33 192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33 [root@Client~]#ping 192.168.1.200 PING 192.168.1.200 (192.168.1.200) 56(84) bytes of data. 64 bytes from 192.168.1.200: icmp_seq=1 ttl=64 time=454 ms [root@Client~]#ping -c 2 10.0.0.200 PING 10.0.0.200 (10.0.0.200) 56(84) bytes of data. 64 bytes from 10.0.0.200: icmp_seq=1 ttl=64 time=10.6 ms [root@Client~]#ping -c 2 172.18.68.103 PING 172.18.68.103 (172.18.68.103) 56(84) bytes of data. 64 bytes from 172.18.68.103: icmp_seq=1 ttl=63 time=7.43 ms [root@Client~]#ping -c 2 172.18.68.104 PING 172.18.68.104 (172.18.68.104) 56(84) bytes of data. 64 bytes from 172.18.68.104: icmp_seq=1 ttl=63 time=16.4 ms #路由器設置 [root@Router~]#sysctl -p net.ipv4.ip_forward = 1 [root@Router~]#sysctl -a | grep ipv4.ip_forward net.ipv4.ip_forward = 1 [root@Router~]#ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:cb:db:c3 brd ff:ff:ff:ff:ff:ff inet 192.168.1.200/24 brd 192.168.1.255 scope global ens32 valid_lft forever preferred_lft forever inet6 fe80::6c28:30e9:3794:f2ae/64 scope link valid_lft forever preferred_lft forever 3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:cb:db:cd brd ff:ff:ff:ff:ff:ff inet 172.18.68.200/16 brd 172.18.255.255 scope global ens33 valid_lft forever preferred_lft forever inet 10.0.0.200/8 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::134d:608:9f85:bce3/64 scope link valid_lft forever preferred_lft forever [root@Router~]#route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32 172.18.0.0 0.0.0.0 255.255.0.0 U 100 0 0 ens33 192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32 #修改RS、VS的VIP地址 [root@VSserver~]#vim lvs_dr_vs.sh #!/bin/bash vip='10.0.0.100' iface='eth1:1' mask='255.0.0.0' port='80' rs1='172.18.68.103' rs2='172.18.68.104' scheduler='wrr' type='-g' case $1 in start) ifconfig $iface $vip netmask $mask #broadcast $vip up iptables -F ipvsadm -A -t ${vip}:${port} -s $scheduler ipvsadm -a -t ${vip}:${port} -r ${rs1} $type -w 3 ipvsadm -a -t ${vip}:${port} -r ${rs2} $type -w 1 ;; stop) ipvsadm -C ifconfig $iface down ;; *) echo "Usage $(basename $0) start|stop" exit 1 ;; esac [root@RS1~]#vim lvs_dr_rs.sh #!/bin/bash vip=10.0.0.100 mask='255.0.0.0' dev=lo:1 case $1 in start) echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig $dev $vip netmask $mask #broadcast $vip up #route add -host $vip dev $dev ;; stop) ifconfig $dev down echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce ;; *) echo "Usage: $(basename $0) start|stop" exit 1 ;; esac [root@VSserver~]#bash lvs_dr_vs.sh start [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.0.0.100:80 wrr -> 172.18.68.103:80 Route 3 0 0 -> 172.18.68.104:80 Route 1 0 0 [root@RS1~]#bash lvs_dr_rs.sh start [root@RS1~]#ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet 10.0.0.100/24 scope global lo:1 valid_lft forever preferred_lft forever 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:a2:83:cb brd ff:ff:ff:ff:ff:ff inet 172.18.68.103/16 brd 172.18.255.255 scope global ens32 valid_lft forever preferred_lft forever [root@Client~]#ping 10.0.0.100 PING 10.0.0.100 (10.0.0.100) 56(84) bytes of data. 64 bytes from 10.0.0.100: icmp_seq=1 ttl=63 time=1.35 ms [root@RS2~]#bash lvs_dr_rs.sh start [root@RS2~]#ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet 10.0.0.100/24 brd 10.0.0.255 scope global lo:1 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:d0:4d:a7 brd ff:ff:ff:ff:ff:ff inet 172.18.68.104/16 brd 172.18.255.255 scope global eth0 [root@Client~]#for i in {1..10} ; do curl 10.0.0.100 ; done RS1 RS1 RS1 RS2 #完成http及https的多集羣調度 [root@VSserver~]#ipvsadm -A -t 10.0.0.100:443 -s rr [root@VSserver~]#ipvsadm -a -t 10.0.0.100:443 -r 172.18.68.103:443 -g [root@VSserver~]#ipvsadm -a -t 10.0.0.100:443 -r 172.18.68.104:443 -g [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.0.0.100:80 wrr -> 172.18.68.103:80 Route 3 0 0 -> 172.18.68.104:80 Route 1 0 0 TCP 10.0.0.100:443 rr -> 172.18.68.103:443 Route 1 0 0 -> 172.18.68.104:443 Route 1 0 0 [root@Client~]#curl -k https://10.0.0.100 RS1 [root@Client~]#curl -k https://10.0.0.100 RS2
4、lvs-tun模式
轉發方式:不修改請求報文的IP首部(源IP爲CIP,目標IP爲VIP),而在原IP報文之外再封裝一個IP首部(源IP是DIP,目標IP是RIP),將報文發往挑選出的目標RS;RS直接響應給客戶端(源IP是VIP,目標IP是CIP)
(1) DIP, VIP, RIP都應該是公網地址
(2) RS的網關不能,也不可能指向DIP
(3) 請求報文要經由Director,但響應不能經由Director
(4) 不支持端口映射
(5) RS的OS須支持隧道功能
5、lvs-fullnat模式
lvs-fullnat:通過同時修改請求報文的源IP地址和目標IP地址進行轉發
CIP --> DIP
VIP --> RIP
(1) VIP是公網地址,RIP和DIP是私網地址,且通常不在同一IP網絡;因此,RIP的網關一般不會指向DIP
(2) RS收到的請求報文源地址是DIP,因此,只需響應給DIP;但Director還要將其發往Client
(3) 請求和響應報文都經由Director
(4) 支持端口映射
注意:此類型kernel默認不支持
6、LVS工作模式總結
VS/NAT | VS/TUN | VS/DR | |
Server | any | Tunneling(必須支持隧道模式) | Non-arp device |
Server network | private(局域網絡) | LAN/WAN | LAN(不能跨網段) |
Server number | low(10-20) | High(100) | High(100) |
Server gateway | load balancer | own router | own router |
lvs-nat與lvs-fullnat:請求和響應報文都經由Director
lvs-nat:RIP的網關要指向DIP
lvs-fullnat:RIP和DIP未必在同一IP網絡,但要能通信
lvs-dr與lvs-tun:請求報文要經由Director,但響應報文由RS直接發往Client
lvs-dr:通過封裝新的MAC首部實現,通過MAC網絡轉發
lvs-tun:通過在原IP報文外封裝新IP頭實現轉發,支持遠距離通信
四、FireWall Mark模式及持久連接
1、FireWall Mark
FWM:FireWall Mark
MARK target 可用於給特定的報文打標記
--set-mark value
其中:value 爲十六進制數字
藉助於防火牆標記來分類報文,而後基於標記定義集羣服務;可將多個不同的應用使用同一個集羣服務進行調度
實現方法:
在Director主機打標記:
iptables -t mangle -A PREROUTING -d $vip -p $proto –m multiport --dports $port1,$port2,… -j MARK --set-mark NUMBER
在Director主機基於標記定義集羣服務:
ipvsadm -A -f NUMBER [options]
#實驗:在DR模式下完成 Mark 的LVS多集羣服務
完成實驗的原理就是默認情況下,系統是根據端口號及IP地址組合區分不同的集羣服務的。
如果把http及https何爲一個集羣服務,就是修改 Mangle 表裏的 MARK target 的標籤(要在VS服務器上修改)。
#實驗基礎爲上訴的DR模式的實驗 #實驗前LVS配置信息 [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.0.0.100:80 wrr -> 172.18.68.103:80 Route 3 0 0 -> 172.18.68.104:80 Route 1 0 0 TCP 10.0.0.100:443 rr -> 172.18.68.103:443 Route 1 0 0 -> 172.18.68.104:443 Route 1 0 0 #在VS服務器上添加mangle表的標籤 [root@VSserver~]#iptables -t mangle -A PREROUTING -d 10.0.0.100 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 10 #10是十六進制數 [root@VSserver~]#iptables -nvL -t mangle Chain PREROUTING (policy ACCEPT 46 packets, 4048 bytes) pkts bytes target prot opt in out source destination 0 0 MARK tcp -- * * 0.0.0.0/0 10.0.0.100 multiport dports 80,443 MARK set 0xa Chain INPUT (policy ACCEPT 46 packets, 4048 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 24 packets, 3744 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 24 packets, 3744 bytes) pkts bytes target prot opt in out source destination #然後要修改原有的ipvsadm的配置 [root@VSserver~]#ipvsadm -C [root@VSserver~]#ipvsadm -A -f 10 -s rr #這裏的10是上面設置的十六進制的表情 [root@VSserver~]#ipvsadm -a -f 10 -r 172.18.68.103 -g [root@VSserver~]#ipvsadm -a -f 10 -r 172.18.68.104 -g [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn FWM 10 rr #FWM MARK標籤的模式 -> 172.18.68.103:0 Route 1 0 0 -> 172.18.68.104:0 Route 1 0 0 #測試 [root@Client~]#for i in {1..10} ; do sleep 0.5 ; curl -k https://10.0.0.100 ; curl http://10.0.0.100 ; done RS1 RS2 #因爲設置的算法是 rr ,所以統一調度的結果就是輪詢 RS1 RS2
2、持久連接
session 綁定:對共享同一組RS的多個集羣服務,需要統一進行綁定,lvs sh算法無法實現
持久連接( lvs persistence )模板:實現無論使用任何調度算法,在一段時間內(默認360s ),能夠實現將來自同一個地址的請求始終發往同一個RS
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
持久連接實現方式:
每端口持久(PPC):
每個端口對應定義爲一個集羣服務,每集羣服務單獨調度
每防火牆標記持久(PFWMC):
基於防火牆標記定義集羣服務;可實現將多個端口上的應用統一調度,即所謂的port Affinity
每客戶端持久(PCC):
基於0端口(表示所有服務)定義集羣服務,即將客戶端對所有應用的請求都調度至後端主機,必須定義爲持久模式
#實驗:一定時間內同一個地址的訪問,調度到同一個RS服務器上,在rr的算法下實現
#實驗基礎就是上訴MARK實驗的基礎配置 [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn FWM 10 rr -> 172.18.68.103:0 Route 1 0 0 -> 172.18.68.104:0 Route 1 0 0 #查詢默認持久連接的時間 [root@VSserver~]#ipvsadm -E -f 10 -s rr -p [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn FWM 10 rr persistent 360 #注意:默認時間爲360秒,官方的文檔寫的是300秒 -> 172.18.68.103:0 Route 1 0 0 -> 172.18.68.104:0 Route 1 0 0 #測試 [root@Client~]#for i in {1..10} ; do sleep 0.5 ; curl -k https://10.0.0.100 ; curl http://10.0.0.100 ; done RS2 RS2 RS2
#實驗:實現每端口持久(PPC)的調度
#實驗基礎的上述實驗的基礎 [root@VSserver~]#ipvsadm -C [root@VSserver~]#ipvsadm -A -t 10.0.0.100:80 -s rr -p [root@VSserver~]#ipvsadm -a -t 10.0.0.100:80 -r 172.18.68.103 -g [root@VSserver~]#ipvsadm -a -t 10.0.0.100:80 -r 172.18.68.104 -g [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.0.0.100:80 rr persistent 360 -> 172.18.68.103:80 Route 1 0 0 -> 172.18.68.104:80 Route 1 0 0 #測試 [root@Client~]#for i in {1..10} ; do sleep 0.5 ; curl http://10.0.0.100 ; done RS2 RS2
#實驗:實現每客戶端持久(PCC)的調度(這種情況使用非常少,因爲後續的所有服務都調度到同一個RS服務器上)
#實驗基礎的上述實驗的基礎 [root@VSserver~]#ipvsadm -C [root@VSserver~]#ipvsadm -A -t 10.0.0.100:0 -s rr -p [root@VSserver~]#ipvsadm -a -t 10.0.0.100:0 -r 172.18.68.104 -g [root@VSserver~]#ipvsadm -a -t 10.0.0.100:0 -r 172.18.68.103 -g [root@VSserver~]#ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.0.0.100:0 rr persistent 360 -> 172.18.68.103:0 Route 1 0 0 -> 172.18.68.104:0 Route 1 0 0 #測試 [root@Client~]#ssh 10.0.0.100 #之後的所有服務都是調度到同一個RS服務器 The authenticity of host '10.0.0.100 (10.0.0.100)' can't be established. RSA key fingerprint is 22:a0:0f:06:72:0e:31:28:0c:d9:4f:cd:45:92:64:42. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.0.0.100' (RSA) to the list of known hosts. [email protected]'s password: Last login: Sun Mar 11 12:12:39 2018 from 172.18.0.1 [root@RS1~]#exit logout Connection to 10.0.0.100 closed. [root@Client~]#curl 10.0.0.100 RS1