LVS(Linux Virtual Server)即Linux 虛擬服務器,是一個的開源負載均衡項目,目前LVS 已經被集成到Linux 內核模塊中。LVS 是四層負載均衡,也就是說建立在OSI 模型的第四層——傳輸層之上,傳輸層上有我們熟悉的TCP/UDP,LVS 支持TCP/UDP 的負載均衡。
一 環境
192.168.132.120 VIP
192.168.132.123 LVS01,keepalived
192.168.132.124 LVS02,keepalived
192.168.132.121 MySQL 主
192.168.132.122 MySQL 主
在192.168.132.123和192.168.132.124安裝lvs的管理軟件,以及安裝keepalive(參考上篇)
[root@lvs01 ~]# yum install ‐y ipvsadm*
LVS 安裝完成,查看當前LVS 集群
[root@lvs01 ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn
二 LVS介紹
2.1 LVS 工作模式
NAT 模式
TUN 模式
DR 模式
2.2 LVS 負載均衡調度算法
輪詢調度(Round Robin 簡稱'RR')算法就是按依次循環的方式將請求調度到不同的服務器上,該算法最大的特點就是實現簡單。輪詢算法假設所有的服務器處理請求的能力都一樣的,調度器會將所有的請求平均分配給每個真實服務器。
加權輪詢(Weight Round Robin 簡稱'WRR')算法主要是對輪詢算法的一種優化與補充,LVS 會考慮每台服務器的性能,並給每台服務器添加一個權值,如果服務器A 的權值為1,服務器B 的權值為2,則調度器調度到服務器B 的請求會是服務器A 的兩倍。權值越高的服務器,處理的請求越多。
最小連接調度(Least Connections 簡稱'LC')算法是把新的連接請求分配到當前連接數最小的服務器。最小連接調度是一種動態的調度算法,它通過服務器當前活躍的連接數來估計服務器的情況。調度器需要記錄各個服務器已建立連接的數目,當一個請求被調度到某台服務器,其連接數加1;當連接中斷或者超時,其連接數減1。
加權最少連接(Weight Least Connections 簡稱'WLC')算法是最小連接調度的超集,各個服務器相應的權值表示其處理性能。服務器的缺省權值為1,系統管理員可以動態地設置服務器的權值。加權最小連接調度在調度新連接時盡可能使服務器的已建立連接數和其權值成比例。調度器可以自動問詢真實服務器的負載情況,並動態地調整其權值。
基於局部性的最少連接調度算法lblc
復雜的基於局部性最少的連接算法lblc目標地址散列調度算法 dh
源地址散列調度算法 sh
固定調度算法:rr,wrr,dh,sh
動態調度算法:wlc,lc,lblc,lblcr
NAT 模式:網絡地址轉換
DR 模式:直接路由
2.3 配置
LVS01配置:
[root@lvs01 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs { router_id lvs01 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 100 nopreempt advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.132.120 } } virtual_server 192.168.132.120 3306 { delay_loop 6 protocol TCP lb_algo rr lb_kind DR real_server 192.168.132.121 3306 { TCP_CHECK { connect_timeout 3 nb_get_retry 3 connect_port 3306 delay_before_retry 3 } } real_server 192.168.132.122 3306 { TCP_CHECK { connect_timeout 3 nb_get_retry 3 connect_port 3306 delay_before_retry 3 } } }
LVS02配置
[root@lvs02 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs { router_id lvs02 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 90 nopreempt advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.132.120 } } virtual_server 192.168.132.120 3306 { delay_loop 6 protocol TCP lb_algo rr lb_kind DR real_server 192.168.132.121 3306 { TCP_CHECK { connect_timeout 3 nb_get_retry 3 connect_port 3306 delay_before_retry 3 } } real_server 192.168.132.122 3306 { TCP_CHECK { connect_timeout 3 nb_get_retry 3 connect_port 3306 delay_before_retry 3 } } }
數據庫配置腳本
master1和master2都操作
[root@master1 ~]# vim /opt/realserver.sh
#!/bin/bash #description: Config realserver VIP=192.168.132.120 /etc/rc.d/init.d/functions case "$1" in start) /sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP /sbin/route add -host $VIP dev lo:0 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 sysctl -p >/dev/null 2>&1 echo "RealServer Start OK" ;; stop) /sbin/ifconfig lo:0 down /sbin/route del $VIP >/dev/null 2>&1 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 echo "RealServer Stoped" ;; *) echo "Usage: $0 {start|stop}" exit 1 esac
Realserver 配置:
arp_ignore
arp:請求包,響應包
0:響應任意網卡上接收到的對本機IP 地址的arp 請求(包括環回網卡上的地址),而不管該目的IP 是否在接收網卡上。
1:只響應目的IP 地址為接收網卡上的本地地址的arp 請求。
當arp_ignore 參數配置為0 時,eth1 網卡上收到目的IP 為環回網卡IP 的arp 請求,但是eth1 也會返回arp 響應,把自己的mac 地址告訴對端。
當arp_ignore 參數配置為1 時,eth1 網卡上收到目的IP 為環回網卡IP 的arp 請求,發現請求的IP 不是自己網卡上的IP,不會回arp 響應。
當arp_announce 參數配置為0 時,系統要發送的IP 包源地址為eth1 的地址,IP 包目的地址根據路由表查詢判斷需要 從eth2 網卡發出,這時會先從eth2 網卡發起一個arp 請求,用於獲取目的IP 地址的MAC 地址。該arp 請求的源MAC 自然是eth2 網卡的MAC 地址,但是源IP 地址會選擇eth1 網卡的地址。當arp_announce 參數配置為2 時,eth2 網卡發起arp 請求時,源IP 地址會選擇eth2 網卡自身的IP 地址。
arp_announce
0:允許使用任意網卡上的IP 地址作為arp 請求的源IP,通常就是使用數據包的源IP。
1:盡量避免使用不屬於該發送網卡子網的本地地址作為發送arp 請求的源IP 地址。
2:忽略IP 數據包的源IP 地址,選擇該發送網卡上最合適的本地地址作為arp 請求的源IP 地址。源IP,源MAC,目的IP,目的MAC
arp_ignore 和arp_announce 參數在DR 模式下的作用
1. arp_ignore
因為DR 模式下,每個真實服務器節點都要在環回網卡上綁定虛擬服務IP。這時候,如果客戶端對於虛擬服務IP 的arp請求廣播到了各個真實服務器節點,如果arp_ignore 參數配置為0,則各個真實服務器節點都會響應該arp 請求,此時客戶端就無法正確獲取LVS 節點上正確的虛擬服務IP 所在網卡的MAC 地址。所以DR 模式下要求arp_ignore 參數要求配置為1。
2. arp_announce
每個機器或者交換機中都有一張arp 表,該表用於存儲對端通信節點IP 地址和MAC 地址的對應關系。當收到一個未知IP 地址的arp 請求,就會再本機的arp 表中新增對端的IP 和MAC 記錄;當收到一個已知IP 地址(arp 表中已有記錄的地址)的arp 請求,則會根據arp 請求中的源MAC 刷新自己的arp 表。
如果arp_announce 參數配置為0,則網卡在發送arp 請求時,可能選擇的源IP 地址並不是該網卡自身的IP 地址,這時候收到該arp 請求的其他節點或者交換機上的arp 表中記錄的該網卡IP 和MAC 的對應關系就不正確,可能會引發一些未知的網絡問題,存在安全隱患。所以DR 模式下要求arp_announce 參數要求配置為2。
[root@master1 ~]# chmod +x /opt/realserver.sh
[root@master1 ~]# chmod +x /opt/realserver.sh
[root@master1 ~]# /opt/realserver.sh start
[root@master1 ~]# chmod +x /etc/rc.d/init.d/functions
[root@master1 ~]# /opt/realserver.sh start
/etc/rc.d/init.d/functions: line 690: return: can only `return' from a function or sourced script SIOCADDRT: File exists RealServer Start OK
把這個腳本加入開機自啟動
[root@master1 ~]# vim /etc/rc.d/rc.local
/opt/realserver.sh start
[root@master1 ~]# chmod +x /etc/rc.d/rc.local
master2相同配置方法
lvs啟動keepalived
[root@lvs01 ~]# systemctl start keepalived
[root@lvs01 ~]# systemctl status keepalived
keepalived.service - LVS and VRRP High Availability Monitor Loaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2019-07-11 10:05:21 EDT; 12s ago
四 驗證
4.1 查看虛擬IP
[root@lvs02 ~]# ip addr
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:f0:04:c9 brd ff:ff:ff:ff:ff:ff inet 192.168.132.123/24 brd 192.168.132.255 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::a6b5:aa2c:b3c7:3415/64 scope link valid_lft forever preferred_lft forever 3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:f0:04:d3 brd ff:ff:ff:ff:ff:ff inet 192.168.254.123/24 brd 192.168.254.255 scope global ens34 valid_lft forever preferred_lft forever inet6 fe80::c37e:949c:9d3:d204/64 scope link valid_lft forever preferred_lft forever
[root@lvs01 ~]# ip addr
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:ac:6a:38 brd ff:ff:ff:ff:ff:ff inet 192.168.132.124/24 brd 192.168.132.255 scope global ens33 valid_lft forever preferred_lft forever inet 192.168.132.120/32 scope global ens33 #虛擬IP valid_lft forever preferred_lft forever inet6 fe80::2333:c431:914d:1a31/64 scope link valid_lft forever preferred_lft forever 3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:ac:6a:42 brd ff:ff:ff:ff:ff:ff inet 192.168.254.124/24 brd 192.168.254.255 scope global ens34 valid_lft forever preferred_lft forever inet6 fe80::d4b5:199b:3d5a:ff0f/64 scope link valid_lft forever preferred_lft forever
4.2 使用192.168.132.125連接數據庫
[root@localhost ~]# mysql -uroot -h192.168.132.120 -p1234567
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| master1 |
| master2 |
| mysql |
| performance_schema |
| sys |
+--------------------+
4.3 查看192.168.132.120所在服務器
[root@lvs02 ~]# 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.132.120:3306 rr -> 192.168.132.121:3306 Route 1 0 1 -> 192.168.132.122:3306 Route 1 1 0
則keepalived+lvs實現負載均衡高可用配置完成
4.4 負載均衡驗證
LVS負載均衡,在發現如果后端的mysql不能連接,就不會把數據發送給服務器
[root@master1 ~]# systemctl stop mysqld
[root@lvs02 ~]# tail -f /var/log/messages
Jul 11 10:25:46 lvs02 Keepalived_healthcheckers[1386]: Removing service [192.168.132.121]:tcp:3306 to VS [192.168.132.120]:tcp:3306
Jul 11 10:25:52 lvs02 Keepalived_healthcheckers[1386]: Received EPOLLHUP for fd 8 #同時一直看狀態
[root@master1 ~]# systemctl start mysqld
[root@lvs02 ~]# tail -f /var/log/messages
Jul 11 10:27:52 lvs02 Keepalived_healthcheckers[1386]: TCP connection to [192.168.132.121]:tcp:3306 success. Jul 11 10:27:52 lvs02 Keepalived_healthcheckers[1386]: Adding service [192.168.132.121]:tcp:3306 to VS [192.168.132.120]:tcp:3306
4.5 高可用驗證
當lVS的其中一台宕機,虛擬盤就會跳到另一台上去
[root@lvs02 ~]# systemctl stop keepalived
[root@lvs02 ~]# ip addr
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:ac:6a:38 brd ff:ff:ff:ff:ff:ff inet 192.168.132.124/24 brd 192.168.132.255 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::2333:c431:914d:1a31/64 scope link valid_lft forever preferred_lft forever 3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:ac:6a:42 brd ff:ff:ff:ff:ff:ff inet 192.168.254.124/24 brd 192.168.254.255 scope global ens34 valid_lft forever preferred_lft forever inet6 fe80::d4b5:199b:3d5a:ff0f/64 scope link valid_lft forever preferred_lft forever
[root@lvs01 ~]# ip addr
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:f0:04:c9 brd ff:ff:ff:ff:ff:ff inet 192.168.132.123/24 brd 192.168.132.255 scope global ens33 valid_lft forever preferred_lft forever inet 192.168.132.120/32 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::a6b5:aa2c:b3c7:3415/64 scope link valid_lft forever preferred_lft forever 3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:f0:04:d3 brd ff:ff:ff:ff:ff:ff inet 192.168.254.123/24 brd 192.168.254.255 scope global ens34 valid_lft forever preferred_lft forever inet6 fe80::c37e:949c:9d3:d204/64 scope link valid_lft forever preferred_lft forever
繼續連接數據庫
[root@localhost ~]# mysql -uroot -h192.168.132.120 -p1234567
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| master1 |
| master2 |
| mysql |
| performance_schema |
| sys |
+--------------------+