keepalived介绍
- keepalived最开始研究出来是为了提升lvs的高可用性。
- 可以检测后端Real server的健康状态,以及调度器在发生故障时可以完成资源转移。
工作模式:
keepalived是基于VRRP(虚拟路由器冗余协议)实现的,简单来说VRRP就是将一堆路由整合成一个虚拟路由器,并将它们虚拟出来一个ip地址,如果其中一个路由器坏掉,可以自动让其它路由顶上。具体工作方式如下:
- 心跳层:在路由器组中,存在一个Master和N个BACKUP,MASTER通过组播方式不断的向备发送自己的心跳信息以及优先级,如果发现Master没有了心跳,则交由下一层资源监听
- 资源监听:根据心跳层发送来的消息,MASTER挂掉了,则要把MASTER的所有财产全部夺过来据为己有,要启动MASTER上应该有的服务,比如nginx等等。。。启动任务要交给下一层本地资源管理器
- 本地资源管理器:把所需要启动的本地服务全部启动起来,但是一个个启动太麻烦,所以将资源做成脚本形式启动。比如需要启动httpd服务,本地资源只要去调用写有httpd的服务脚本即可,例如unitfile等。
- 资源代理层:就是代理各个服务的脚本。
这就是一个大概的每个层次应该做的工作。下面介绍一些名词:
虚拟路由: 就是Master和Backup集合的统称。无论backup有多少个,统一都叫一个虚拟路由。它存在虚拟ip和虚拟mac,这两个作用是虚拟ip用来接收外部的请求,虚拟mac用来回应ARP的广播。
MASTER: 它 是通过虚拟ip进行外部服务的一个服务器,而且虚拟路由里面只能有一个Master,而且是根据各个优先级选举出来的。它拥有虚拟路由的虚拟ip以便接受外来的访问服务。
BACKUP: 只做备机,不断接收主机发来的心跳以及优先级。只有当Master服务器心跳断了,才能接管MASTER所服务的一切。
网络分区: 假如BACKUP检测不到MASTER的心跳信息,怎么判断肯定是MASTER的问题,而不是BACKUP的问题呢,所以一般冗余应该在3台或3台以上的基数配置。比如说有ABC三台机器,A没有心跳,BC都检测不到A了,这样可以准确判断是A的问题。像这种变成了BC一组,A一组的情况就叫网络分区。
隔离方式: 隔离方式有两种,一种是直接将设备隔离出去,类似于剔除。一种是隔离对关键资源的访问。
选举机制: 用来判断谁来当master,谁来当backup
- 1、根据组中的优先级来判断,优先级大的当master
- 2、虚拟路由的IP和组中的某一个服务器ip一样,则此为master
- 3、如果前两个都不符合,地址范围大的充当master
抢占模式: master和backup的优先级进行比较,谁的优先级大,谁充当master的角色
非抢占模式: 只要master存在,并且没有故障,不管backup的优先级是否大于,都会充当master的角色
** 安全认证:** 如果虚拟路由组 当中临时添加了一个backup,而且我们也不知道它是否安全,所以我们要对添加进来的做一个安全认证。有三种方式:无认证,简单字符(不超过8个字符且官方推荐),MD5。
Failover: 故障切换,即某资源的主节点故障时,将资源转移至其它节点的操作
Failback: 故障移回,即某资源的主节点故障后重新修改上线后,将转移至其它节点的资源重新切回的过程
keepalived组件
- watch dog:主要用来检测VRRP STACK和Checkers进程
- Checkers:检测服务器端的状态以及故障隔离,可以基于 TCP 、HTTP等。
- VRRP STACK:用来实现master和backup之间的自动转换
- IPVS wrapper:直接向内核中的IPVS写入规则
- Netlink Reflector:主要实现资源转移以及虚拟ip的配置
keepalived配置
keepalived在centos6.4版本之后就已经加入了base仓库。可以直接从base仓库进行安装
安装完成之后,它只有一个配置文件:keepalived.conf。
对于配置文件有3个段落:
GLOBAL CONFIGURATION
:主要用来定义全局变量、静态路由以及静态规则。VRRPD CONFIGURATION
:针对VRRP进行的配置LVS CONFIGURATION
:虚拟服务器的配置
单主模式配置示例:
所谓单主就是两台或者两台以上的机器,只有MASTER主机有虚拟ip,BACKUP都在看着,只有MASTER挂了,才会将MASTER的虚拟ip地址进行转移。
#安装keepalived
[root@keepalived2 keepalived]# yum info keepalived
源 :installed
#编辑keepalive文件,以下为更改好的示例,查看帮助文档可以man keepalived.conf
[root@keepalived2 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email { #出问题时向谁发送邮件,这里是root本地上发。
root@localhost
}
smtp_server 127.0.0.1 #邮件服务器地址
smtp_connect_timeout 30 #连接超时时间
router_id keepalived2 #虚拟路由标识符,
vrrp_mcast_group4 224.1.2.3 #虚拟路由虚拟出来的ip地址
}
vrrp_instance keepalived { #定义vrrp的配置,keepalived为标识符,此标识唯一。
state MASTER #当前节点为master,一旦定义了此处,则其它所有的都为BACKUP
interface ens33 #绑定虚拟路由对应的物理网络接口
virtual_router_id 33 #虚拟路由标识,此也是唯一,同一个路由的标识应该是一样。
priority 100 #优先级,数字范围1-255,数字越大,优先级越高
advert_int 1 #vrrp通告的时间间隔,单位s。 也就是心跳
preempt #抢占模式,非抢占模式为nopreempt。 默认为非抢占模式。此处为了演示效果
authentication { #为防止混进来企图不轨的服务器,所设定的安全认证
auth_type PASS #简单字符串认证
auth_pass bda541hu #不超过8个字符的密码
}
virtual_ipaddress { # 定义虚拟路由ip
192.168.199.18/24 dev ens33 label ens33:0 #虚拟路由地址/掩码 设备 网卡名称 别名 名称
}
}
#备机的配置和主机基本上一样,下面只标记修改的地方
global_defs {
notification_email {
root@localhost
}
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepalived1 #修改名称
vrrp_mcast_group4 224.1.2.3
}
vrrp_instance keepalived {
state BACKUP #修改为backup
interface ens33
virtual_router_id 33
priority 90 #设定优先级, 要比master的低
advert_int 1
preempt
authentication {
auth_type PASS
auth_pass dhdow222 #修改密码
}
virtual_ipaddress {
192.168.199.18/24 dev ens33 label ens33:0
}
}
#分别启动两台的服务,先启动keepalived1的,backup。
[root@keepalived1 ~]# systemctl start keepalived.service
[root@keepalived1 ~]# ifconfig
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.199.18 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:d4:00:fc txqueuelen 1000 (Ethernet)
#然后在重启keepalived2,master,由于是抢占模式,当master启动之后,会直接夺走backup的ip
[root@keepalived2 ~]# systemctl start keepalived.service
[root@keepalived2 ~]# ifconfig
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.199.18 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:e0:c8:e9 txqueuelen 1000 (Ethernet)
双主模型配置示例:
双主模式就是在两个主机上全部运行keepalived,但是区别于单主模式,需要定义两个VIP(虚拟路由的ip地址)。如上图。
这样做的好处也可以分担director的压力。
#keepalive1上的配置
[root@keepalived1 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepalived2
vrrp_mcast_group4 224.1.2.3
}
vrrp_instance keepalived {
state BACKUP
interface ens33
virtual_router_id 33
priority 90
advert_int 1
preempt
authentication {
auth_type PASS
auth_pass bda541hu
}
virtual_ipaddress {
192.168.199.18/24 dev ens33 label ens33:0
}
}
vrrp_instance keepalived2 { #多添加一个虚拟路由。
state MASTER
interface ens33
virtual_router_id 44
priority 100
advert_int 1
preempt
authentication {
auth_type PASS
auth_pass bda541hu
}
virtual_ipaddress {
192.168.199.38/24 dev ens33 label ens33:1
}
}
#keepalive2上的配置
[root@keepalived2 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepalived2
vrrp_mcast_group4 224.1.2.3
}
vrrp_instance keepalived {
state MASTER
interface ens33
virtual_router_id 33
priority 100
advert_int 1
preempt
authentication {
auth_type PASS
auth_pass bda541hu
}
virtual_ipaddress {
192.168.199.18/24 dev ens33 label ens33:0
}
}
vrrp_instance keepalived2 {
state BACKUP
interface ens33
virtual_router_id 44
priority 90
advert_int 1
preempt
authentication {
auth_type PASS
auth_pass bda541hu
}
virtual_ipaddress {
192.168.199.38/24 dev ens33 label ens33:1
}
}
#查看执行结果,只启动keepalived2上的服务
root@keepalived2 ~]# systemctl start keepalived.service
[root@keepalived2 ~]# ifconfig
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.199.18 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:e0:c8:e9 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.199.38 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:e0:c8:e9 txqueuelen 1000 (Ethernet)
#可以看到keepalived2上的虚拟ip地址变成了两个。如果keepalived1启动之后,它就会抢走在它主机上定义的master虚拟路由IP
#启动keepalived1的主机
[root@keepalived1 ~]# systemctl start keepalived.service
[root@keepalived1 ~]# ifconfig
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.199.38 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:d4:00:fc txqueuelen 1000 (Ethernet)
#可以看到ens33:1的ip地址回来了。
虚拟服务器配置示例:
此处主要用来定义检测后端real server的健康状况, 可以完成自动添加和去除。下面以DR类型来演示。
首先说一下搭建环境:
keepalived服务使用单主模式 ,方便演示
主机 | ip地址 |
---|---|
keepalived1 | 192.168.199.243,充当keepalived主角色 |
keepalived2 | 192.168.199.145,充当keepalived备角色 |
R1 | 192.168.199.152,real server1,httpd服务 |
R2 | 192.168.199.152,real server2,httpd服务 |
#先配置两台real server的网址以及vip。两台全部是使用桥接网络,lo:0放置vip,并对vip的arp相应限制,跟之前lvs的dr设置一模一样,只不过这里的vip换成了虚拟路由的vip,下面只显示了一台,两台都一样。除了ens33的地址不一样
[root@r1 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.199.152 netmask 255.255.255.0 broadcast 192.168.199.255
inet6 fe80::ab2b:853e:cad4:9246 prefixlen 64 scopeid 0x20<link>
inet6 fe80::a18e:b9a0:6926:d8ba prefixlen 64 scopeid 0x20<link>
inet6 fe80::9e21:527f:7cc4:a533 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:81:a9:7c txqueuelen 1000 (Ethernet)
RX packets 33183 bytes 25672940 (24.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13881 bytes 2048366 (1.9 MiB)
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 1000 (Local Loopback)
RX packets 81 bytes 13908 (13.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 81 bytes 13908 (13.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 192.168.199.38 netmask 255.255.255.255
loop txqueuelen 1000 (Local Loopback)
#开始配置keepalived.conf
[root@keepalived1 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepalived2
vrrp_mcast_group4 224.1.2.3
}
vrrp_instance keepalived2 {
state MASTER
interface ens33
virtual_router_id 44
priority 100
advert_int 1
preempt
authentication {
auth_type PASS
auth_pass bda541hu
}
virtual_ipaddress {
192.168.199.38/24 dev ens33 label ens33:1
}
}
virtual_server 192.168.199.38 80 { #虚拟路由的配置
delay_loop 3 #多长时间轮询一次
lb_algo wrr #使用什么算法
lb_kind DR #使用什么类型
protocol TCP #支持的协议
sorry_server 127.0.0.1 80 #当后端服务器都挂掉之后用哪个响应
real_server 192.168.199.152 80 { #后端真是服务器ip地址,端口
weight 1 #权重
HTTP_GET { #基于http层检测
url {
path / #请求的时候请求哪个资源
status_code 200 #请求的资源响应状态是多少才正常
}
connect_timeout 1 # 连接请求的超时时长
nb_get_retry 3 #重试次数
delay_before_retry 1 #两次重试之间的间隔
}
}
real_server 192.168.199.200 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
nb_get_retry 3
delay_before_retry 1
}
}
}
[root@keepalived1 keepalived]# 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.199.38:80 rr
-> 192.168.199.152:80 Route 1 0 0
-> 192.168.199.200:80 Route 1 0 0
#可以看到已经给将两个后端服务器加进来了,而且两台keepadlived服务的主机都一直存在这两个规则。
nginx+keepalived实现高可用
keepalived当初设计出来只是为了实现lvs的高可用,但是我们可以使用它拥有运行脚本的能力来实现nginx的故障转移以及高可用性。
配置环境:
主机 | ip地址 |
---|---|
keepalived1 | 192.168.199.243,内网接口192.168.179.131 包含nginx服务,MASTER |
keepalived2 | 192.168.199.145,内网接口192.168.179.128 包含nginx服务 ,BACKUP |
r1 | 192.168.179.130,httpd服务 |
r2 | 192.168.179.129,httpd服务 |
#配置keepalived2,BACKUP
[root@keepalived2 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepalived2 #在keepalived1上需要改成keepalived1
vrrp_mcast_group4 224.1.2.3
}
vrrp_script chk_down { #提供脚本的配置块
script "[[ -f /etc/keepalived/down ]]&& exit1 || exit0" #脚本可以使用“”来写,也可以使用路径下的脚本,意思是如果/keppalived下有down这个文件,就错误退出,反之正常退出
weight -20 #当发生问题的时候,权重减多少,如果是抢占模式,余下的值一定要比BAKCUP的低
interval 3 #多长时间运行一次脚本
}
vrrp_script chk_nginx {
script " killall -0 nginx && exit0 || exit1" # 测试能否全部杀死nignx进程,如果可以表示nginx存在,反之不正常退出
interval 3
weight -5
fall 2 #执行几次失败
rise 1 #执行成功几次。对于要上线的设备要执行几次成功才能正式上线
}
vrrp_instance keepalived2 {
state BACKUP #此处在keepalived1上该MASTER
interface ens33
virtual_router_id 44
priority 90 #keepalived1优先级要大于90
advert_int 1
preempt
authentication {
auth_type PASS
auth_pass bda541hu
}
virtual_ipaddress {
192.168.199.38/24 dev ens33 label ens33:1
}
track_script{ #监测脚本
chk_down
chk_nginx
}
notify_master "/etc/keepalived/notify.sh master" #当前节点成为主节点的时候之行动的脚本
notify_backup "/etc/keepalived/notify.sh backup" #当前节点成为备节点的时候之行动的脚本
notify_fault "/etc/keepalived/notify.sh fault" #当前节点成为fault的时候之行动的脚本
}
#在keepalived1和keepalived2上各自安装nginx服务,并且反代至后端两台web服务器
#在http处加上upstream,将后端编成一组
...
upstream webservers {
server 192.168.179.130;
server 192.168.179.129;
}
...
location / {
proxy_pass http://webservers;
}
...、
#都配置好后,直接访问192.168.199.28
[root@localhost ~]# curl http://192.168.199.38/index.html
<h1>r2 192.168.179.129</h1>
[root@localhost ~]# curl http://192.168.199.38/index.html
<h1>r1 192.168.179.130</h1>