一、解决LVS server单点故障

如果集群中只有一台LVS server提供数据包分发服务,如果宕机,则会导致所有的业务重点,因为所有的请求都无法到达后面的Real server。

此时我们可以采用多台LVS server形成主备模型,来解决单点故障的问题。需要解决的细节有以下几个方面:

1)备机如何得知主机宕机

  要解决这个问题,有两种解决方案:

  • 一种是每台备机定期向主机询问,看主机是否宕机。
  • 第二种是主机定时进行广播,所有备机只要定期能收到广播包,就说明主机正常运行,连续多次未收到包,则说明主机宕机。

2)主机宕机后,哪台备机接替成为主机

  有两个策略:

  • 选举:推荐,得票最多的接替主机
  • 谦让:每台服务器都配一个数字,谁数字最大谁就接替主机

在Keepalived的方案中,我们选用主机广播和谦让两种模式来解决LVS server单点故障问题。

二、解决Real server宕机检测问题

Real server发生宕机时,必须动态的从LVS server上剔除该宕机的Real server。所以必须要有监控机制。

1)通过ping的方式查看主机状态:只能证明主机三层网络是否正常,而无法证明业务是否正常。

2)Real server提供一个专用页面,让一个第三方程序定时访问,如果返回200,则表示业务正常。

Keepalived提供第二种方案来确保业务的监控准确性。

三、Keepalived原理

  VRRP协议(虚拟路由冗余协议)—— Virtual Router Redundancy Protocol

  作用是在LVS server宕机时,将VIP漂移到备机上,可以实现短时间内的业务切换。

Keepalived是用户控件的程序,可以代替ipvsadm来直接调用内核LVS提供的接口,所以我们无需安装ipvsadm软件。但是ipvsadm可以提供一些方面的命令来查看LVS的运行状态,例如ipvsadm -lnc,所以建议安装。

yum install keepalived -y

Keepalived是通过配置文件来进行配置的,我们无需手工配置LVS,所以在启动keepalived后,所有LVS配置都会自动完成。

# 配置文件
vi /etc/keepalived/keepalived.conf
# 查看日志
tail /var/log/message

四、Keepalived实验

1.系统准备

准备四台干净的虚拟机位于同一局域网,网段为192.168.1.0。

四台虚拟机IP分别是:

  LVS server 1:192.168.1.199  (DIP)

  LVS server 2:192.168.1.200  (DIP)

  Real server 1:192.168.1.201  (RIP)

  Real server 2:192.168.1.202  (RIP)

2.为两台LVS server安装ipvsadm(也可以不安装)

yum install ipvsadm -y
# 如果之前手工配置过LVS,则清除配置
ipvsadm -C

3.配置两台Real server

修改配置使其可以隐藏VIP:

# 只响应询问自己地址的请求,不回应位于lo的VIP
echo > /proc/sys/net/ipv4/conf/eth0/arp_ignore
# 只主动播报与本接口地址匹配的信息
echo > /proc/sys/net/ipv4/conf/eth0/arp_announce # 为所有网卡添加同样配置,比如后续添加新的网卡
echo > /proc/sys/net/ipv4/conf/all/arp_ignore
echo > /proc/sys/net/ipv4/conf/all/arp_announce

给lo配置VIP:

ifconfig lo: 192.168.1.10 netmask 255.255.255.255

安装httpd:

yum install httpd -y

在httpd的发布目录下写一个简单的页面index.html:

cd /var/www/html
vi index.html from real-server-1

启动httpd服务:

systemctl start httpd

4.安装keepalived

为两台LVS server都安装keepalived:

yum install keepalived -y

5.配置keepalived

备份配置文件:

cd /etc/keepalived
cp keepalived.conf keepalived.conf.bak

查看配置文件:

[root@lvs-server- keepalived]# more keepalived.conf
! Configuration File for keepalived global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval
vrrp_gna_interval
} vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id
priority
advert_int
authentication {
auth_type PASS
auth_pass
}
virtual_ipaddress {
192.168.200.16
192.168.200.17
192.168.200.18
}
} virtual_server 192.168.200.100 {
delay_loop
lb_algo rr
lb_kind NAT
persistence_timeout
protocol TCP real_server 192.168.201.100 {
weight
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout
nb_get_retry
delay_before_retry
}
}
}

我们可以看到,配置文件中是按模块配置的,主要有三大模块:

  global_defs:全局配置,配置一些邮件信息,出现问题的时候可以发邮件给管理者。

  vrrp_instance:VRRP冗余协议配置。

  virtual_server:虚拟服务配置(也就是配置LVS server的冗余,其中包含后端的多个Real server配置)

vrrp_instance配置部分:

# 这是模板
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id
priority
advert_int
authentication {
auth_type PASS
auth_pass
}
virtual_ipaddress {
192.168.200.16
192.168.200.17
192.168.200.18
}
}

解释:

1.state可以有MASTER和BACKUP两种,例如企业中多台LVS的主备配置不一样,配置最好的设置为MASTER,其他设为BACKUP。当Master宕机,则有某台BACKUP接替,能MASTER抢修好了,MASTER会抢回主机角色。

  注意:这种主修复好后立刻抢回主机角色的模式,主要用于LVS这种四层负载,因为LVS无需保存业务上下文,主备切换的成本很低。主备机器除了一个拥有VIP,一个没有VIP的区别意外,其他都是一样的,主备都是随时监测Real server的状态,实时更新Real server的列表,所以无论是主机还是备机,他们都能提供正确的服务。

  而像nginx那种基于7层业务的负载均衡,则在主备切换的前后需要进行大量元数据的同步,如果主机修复好后,马上抢回主机的角色,则需要在抢回之前锁定备机,进行元数据同步,此时会导致备机无法提供业务。切换成本很高。

2.interface配置的是心跳广播使用哪个网卡,可以和业务公用一个网卡,例如eth0,也可以单独走一个网络(使用eth1)。

3.virtual_router_id是一套keepalived的ID,例如一个企业可能有多套keepalived,使用该ID区分,以免混淆。

4.priority就是优先级,每台机器不管主备都应该是不一样的,例如主机是100,备机是99、98、97......,用于备机接替主机时谦让选举。

5.advert_int、authentication 是用作验证,无需关心。

6.virtual_ipaddress:192.168.1.10/24 dev eth0 label eth0:8

virtual_ipaddress {
192.168.1.10/ dev eth0 label eth0:
}

如果配置不知道怎么配,可以使用man查看帮助文档:

man  keepalived.conf

在帮助文档中搜索关键字,例如 virtual_ipaddress。

配置完后如下:

# 这是当前实验的配置(LVS server )
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id
priority
advert_int
authentication {
auth_type PASS
auth_pass
}
virtual_ipaddress {
192.168.1.10/ dev eth0 label eth0:
}
}

以上配置提供给Keepalived自动去配置LVS server的VIP,当然只有MASTER才会被真正配置VIP,因为配有VIP的LVS就是提供服务的LVS。

virtual_server配置部分:

virtual_server 192.168.200.100  {
delay_loop
lb_algo rr
lb_kind NAT
persistence_timeout
protocol TCP real_server 192.168.201.100 {
weight
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout
nb_get_retry
delay_before_retry
}
}
}

解释:

以下几项是对LVS内核的配置:

1.virtual_server 后面的IP地址就是VIP地址以及端口,例如我们配为192.168.1.10 80。

2.lb_algo是转发模式,rr为轮询。

3.lb_kind负载均衡的模式,我们选择DR。

4.persistence_timeout:例如某个用户频繁访问,如果该timeout设置为0,则每次访问都可能被分配到不同的Real server,一次访问Real server可能会为该用户分配内存空间和创建一些对象。如果每次访问都被分配到不同的Real server,则意味着这些Real server都要为该用户分配一些内存空间和创建一些对象,这样回造成服务器资源的浪费。所以我们设置该timeout为长一点的时间,在这个时间范围会,一个用户重复访问资源,都将其分到同一个Real server(也就是在LVS上记录他上次分到的Real server,一段时间内的其他请求也发给那个Real server)。正常业务时可以设置为180s。我们这里配置为0,用于测试。

至此LVS就算配置完了,后面的real_server是对Real server的配置:

1.real_server后面的IP和端口就是真实提供服务的real server的IP以及Httpd的端口,这里是192.168.1.201 80。

2.weight是Real server的权重,如果一台为1,一台为2,则第二台被分配到的链接数量是第一台的两倍。

3. SSL_GET开始,就是Real server的健康检查部分,这里的SSL是对应https协议。我们这里采用的是http协议,所以修改为HTTP_GET。

4.url是提供给keepalived访问的一个页面,专门用来判断Real server的业务是否正常。这里用index.html页面代替。用返回状态200所谓判断依据。

url {
path /
status_code
}

5.connect_timeout是访问测试页面超时的时间,nb_get_retry是重试次数,delay_before_retry是重试前延迟时间,可以保持默认。

配置完如下:

virtual_server 192.168.1.10  {
delay_loop
lb_algo rr
lb_kind DR
persistence_timeout
protocol TCP real_server 192.168.1.201 {
weight
HTTP_GET {
url {
path /
status_code
}
connect_timeout
nb_get_retry
delay_before_retry
}
}
real_server 192.168.1.202 {
weight
HTTP_GET {
url {
path /
status_code
}
connect_timeout
nb_get_retry
delay_before_retry
}
}
}

这样就将LVS内核以及需要健康检查的两台Real server都配置好了。

除了以上三个主要部分的配置,后面的配置模板可以全部删除了

配置另一台LVS server:

将配置好的配置文件拷贝到另外一台需要配置得LVS server,只需要修改vrrp_instance 模块中的state,将其修改为BACKUP。并将priority修改为99。

6.启动keepalived

启动MASTER机器的keepalive:

systemctl start httpalived

启动后,我们查看ifconfig:

[root@lvs-server- keepalived]# ifconfig
eth0: flags=<UP,BROADCAST,RUNNING,MULTICAST> mtu
inet 192.168.1.199 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 240e::c0:ddc0:20c:29ff:fe86:f385 prefixlen scopeid 0x0<global>
inet6 fe80::20c:29ff:fe86:f385 prefixlen scopeid 0x20<link>
ether :0c:::f3: txqueuelen (Ethernet)
RX packets bytes (62.5 MiB)
RX errors dropped overruns frame
TX packets bytes (601.2 KiB)
TX errors dropped overruns carrier collisions eth0:8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.10 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:86:f3:85 txqueuelen 1000 (Ethernet) lo: flags=<UP,LOOPBACK,RUNNING> mtu
inet 127.0.0.1 netmask 255.0.0.0
inet6 :: prefixlen scopeid 0x10<host>
loop txqueuelen (Local Loopback)
RX packets bytes (0.0 B)
RX errors dropped overruns frame
TX packets bytes (0.0 B)
TX errors dropped overruns carrier collisions

发现keepalive为我们自动创建了VIP(MASTER上)。

启动备机BACKUP的keepalive:

systemctl start keepalived
[root@lvs-server- keepalived]# ifconfig
eth0: flags=<UP,BROADCAST,RUNNING,MULTICAST> mtu
inet 192.168.1.200 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 240e::c0:ddc0:20c:29ff:fea5: prefixlen scopeid 0x0<global>
inet6 fe80::20c:29ff:fea5: prefixlen scopeid 0x20<link>
ether :0c::a5:: txqueuelen (Ethernet)
RX packets bytes (22.7 MiB)
RX errors dropped overruns frame
TX packets bytes (653.6 KiB)
TX errors dropped overruns carrier collisions lo: flags=<UP,LOOPBACK,RUNNING> mtu
inet 127.0.0.1 netmask 255.0.0.0
inet6 :: prefixlen scopeid 0x10<host>
loop txqueuelen (Local Loopback)
RX packets bytes (0.0 B)
RX errors dropped overruns frame
TX packets bytes (0.0 B)
TX errors dropped overruns carrier collisions

我们发现备机BACKUP启动keepalived后,并没有创建VIP,符合我们的预期。

7.验证负载均衡

使用ipvsadm -ln分别在主备LVS server上查看负载均衡情况:

查询结果一致:

[root@lvs-server- keepalived]# ipvsadm -ln
IP Virtual Server version 1.2. (size=)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.10: rr
-> 192.168.1.201: Route
-> 192.168.1.202: Route

我们发现VIP和下挂的Real server都被正确监控。

此时使用浏览器来访问VIP:

发现无法打开页面,我们ping一下VIP:

发现也无法ping通。

检查keepalived配置文件,发现在global_defs中有一行为vrrp_strict,在两台LVS server上都将其注释掉:

global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval
vrrp_gna_interval
}

然后再次尝试ping,就能够ping通了,再次尝试浏览器访问VIP:

此时,发现能够正常访问了。。

8.测试异常情况

测试四种情况:

  1)MASTER宕机时

  2)MASTER恢复时

  3)Real server宕机时

  4)Real server恢复时

当LVS server的MASTER机器宕机时(使用down掉网卡来模拟):

检查备机BACKUP也就是LVS server 2的网卡信息:

[root@lvs-server- ~]# ifconfig
eth0: flags=<UP,BROADCAST,RUNNING,MULTICAST> mtu
inet 192.168.1.200 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 240e::c0:ddc0:20c:29ff:fea5: prefixlen scopeid 0x0<global>
inet6 fe80::20c:29ff:fea5: prefixlen scopeid 0x20<link>
ether :0c::a5:: txqueuelen (Ethernet)
RX packets bytes (407.8 KiB)
RX errors dropped overruns frame
TX packets bytes (285.6 KiB)
TX errors dropped overruns carrier collisions eth0:8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.100 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:a5:77:56 txqueuelen 1000 (Ethernet) lo: flags=<UP,LOOPBACK,RUNNING> mtu
inet 127.0.0.1 netmask 255.0.0.0
inet6 :: prefixlen scopeid 0x10<host>
loop txqueuelen (Local Loopback)
RX packets bytes (0.0 B)
RX errors dropped overruns frame
TX packets bytes (0.0 B)
TX errors dropped overruns carrier collisions

发现备机被自动添加了VIP,说明keepalived运行正常。

当LVS MASTER恢复时(使网卡UP):

检查备机BACKUP的网卡信息:

[root@lvs-server- ~]# ifconfig
eth0: flags=<UP,BROADCAST,RUNNING,MULTICAST> mtu
inet 192.168.1.200 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 240e::c0:ddc0:20c:29ff:fea5: prefixlen scopeid 0x0<global>
inet6 fe80::20c:29ff:fea5: prefixlen scopeid 0x20<link>
ether :0c::a5:: txqueuelen (Ethernet)
RX packets bytes (439.2 KiB)
RX errors dropped overruns frame
TX packets bytes (308.5 KiB)
TX errors dropped overruns carrier collisions lo: flags=<UP,LOOPBACK,RUNNING> mtu
inet 127.0.0.1 netmask 255.0.0.0
inet6 :: prefixlen scopeid 0x10<host>
loop txqueuelen (Local Loopback)
RX packets bytes (0.0 B)
RX errors dropped overruns frame
TX packets bytes (0.0 B)
TX errors dropped overruns carrier collisions

发现eth:8消失。

检查恢复的主机MASTER的网卡信息:

[root@lvs-server- ~]# ifconfig
eth0: flags=<UP,BROADCAST,RUNNING,MULTICAST> mtu
inet 192.168.1.199 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 240e::c0:ddc0:20c:29ff:fe86:f385 prefixlen scopeid 0x0<global>
inet6 fe80::20c:29ff:fe86:f385 prefixlen scopeid 0x20<link>
ether :0c:::f3: txqueuelen (Ethernet)
RX packets bytes (306.6 KiB)
RX errors dropped overruns frame
TX packets bytes (268.0 KiB)
TX errors dropped overruns carrier collisions eth0:7: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.100 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:86:f3:85 txqueuelen 1000 (Ethernet) lo: flags=<UP,LOOPBACK,RUNNING> mtu
inet 127.0.0.1 netmask 255.0.0.0
inet6 :: prefixlen scopeid 0x10<host>
loop txqueuelen (Local Loopback)
RX packets bytes (2.4 KiB)
RX errors dropped overruns frame
TX packets bytes (2.4 KiB)
TX errors dropped overruns carrier collisions

发现eth0:7被重新设置,也就是VIP漂移回MASTER了。keepalived运行正常。

当Real server 1的Httpd服务宕掉时:

[root@real-server- ~]# systemctl stop httpd

检查两个LVS的负载信息:

# MASTER
[root@lvs-server- ~]# ipvsadm -ln
IP Virtual Server version 1.2. (size=)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.100: rr
-> 192.168.1.202: Route
# BACKUP
[root@lvs-server- ~]# ipvsadm -ln
IP Virtual Server version 1.2. (size=)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.100: rr
-> 192.168.1.202: Route

我们发现两个LVS server上Real server列表中都将Real server 1剔除,keepalived运行正常。

当Real server 1的Httpd服务恢复时:

[root@real-server- ~]# systemctl start httpd  

检查两个LVS的负载信息:

# MASTER
[root@lvs-server- ~]# ipvsadm -ln
IP Virtual Server version 1.2. (size=)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.100: rr
-> 192.168.1.201: Route
-> 192.168.1.202: Route
# BACKUP
[root@lvs-server- ~]# ipvsadm -ln
IP Virtual Server version 1.2. (size=)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.100: rr
-> 192.168.1.201: Route
-> 192.168.1.202: Route

我们发现Real server 1又被正确的添加进了列表中,keepalived运行正常。

最新文章

  1. Java Enumeration接口
  2. 运维之Centos apache vsftpd配置
  3. IOS APP的所有图标尺寸规范
  4. [Java] Java 获取数据库所有表基本信息和表中的所有列基本信息代码
  5. mootools upgrate from 1.2 to 1.3 or 1.4
  6. CSS的魔法和魅力
  7. protocol buffer介绍(protobuf)
  8. DataGridView很详细的用法
  9. 【WebStorm】前端工具开发利器webstrom专篇...更新中
  10. python 接口自动化测试(一)
  11. Alpha 版本测试和发布说明
  12. SQL查询一个表里面某个字段值相同的数据记录
  13. 自己动手编译Android(LineageOS)源码
  14. 再谈AbstractQueuedSynchronizer1:独占模式
  15. Java_面向对象
  16. git -分支管理(创建、推送、删除)
  17. Uboot USB模式(RK3288变砖头的解决办法)
  18. Codeforces Round #513 by Barcelona Bootcamp C. Maximum Subrectangle(双指针+思维)
  19. IBATIS+ORACLE(一)
  20. 笔记-django学习链接

热门文章

  1. Python globals()和locals()比较
  2. mysql拆分逗号一列变多行
  3. Git和Github的使用
  4. Hive 教程(三)-DDL基础
  5. BASH的保护性编程技巧
  6. thinkphp3.2.3 自定义路由实践
  7. java实现spark常用算子之mapPartitions
  8. k8s的一些基本命令
  9. Scala新版本学习(1):
  10. 【转载】Linux GCC常用命令