1. keepalived介绍
- 在这里我们使用keepalived来实现高可用集群,因为heartbeat在centos6上有一些问题,影响实验效果(比如,切换不及时)
- keepalived通过 VRRP(Virtual Router Redundancy Protocl)虚拟路由冗余协议 来实现高可用。
- 在这个协议里会将多台功能相同的路由器组成一个小组,这个小组里会有1个master角色和N(N>=1)个backup角色。
- master会通过组播的形式向各个backup发送VRRP协议的数据包,当backup收不到master发来的VRRP数据包时,就会认为master宕机了。此时就需要根据各个backup的优先级来决定谁成为新的mater。
- Keepalived要有三个模块,分别是core、check和vrrp。其中core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析,check模块负责健康检查,vrrp模块是来实现VRRP协议的。
2. 用keepalived配置高可用集群
2.1 准备
- 两台机器 192.168.2.180(Master/yt-01)、192..168.2.183(backupyt-02)
- keepalived的VIP设为192.168.2.100(在keepalived配置里面设置)。关于VIP,即Vitrual IP。当我们有主从两台机器,我们需要绑定域名到指定的IP,如果绑定在主上面。如果主宕机,我们就无法提供服务,所以Vitrual IP就起到了关键性作用。默认配置在主服务器上面,但是一旦宕机,从服务器就会立即启动,并且把这个IP绑定在从上面从而不会影响业务的状态!
- 机器都要联网
- 两台机器都要安装keepalived
# yum install -y keepalived
- 两台机器都安装nginx 安装nginx作为实验对象,其中因为180上之前已经源码包安装过nginx,所以只需要181上安装就可以了
# yum install -y nginx
- 两台机器都要关闭防火墙
# iptables -nvL
# systemctl stop firewalld
# getenforce
# setenforce 0
2..2 配置主keepalived服务器
更改配置文件
- 编辑180上keepalived配置文件
# > /etc/keepalived/keepalived.conf #清空原始配置文件
# vim /etc/keepalived/keepalived.conf #复制下面代码,代替原配置文件
# 全局定义参数
global_defs {
notification_email { #出现问题后接收提示的邮箱
test@test.com
}
notification_email_from test@test.com #发件人邮箱
smtp_server 127.0.0.1 #邮件服务器
smtp_connect_timeout 30 #延时
router_id LVS_DEVEL #运行keepalived机器的一个标识
}
vrrp_script chk_nginx { #检测vrrp服务是否正常
script "/usr/local/sbin/check_ng.sh" #检测脚本的路径
interval 3 #检测间断是3s
}
vrrp_instance VI_1 { #定义相关Master的东西
state MASTER #设定角色
interface ens33 #指定ens33这块网卡,通过vrrp协议去发广播
virtual_router_id 51 #指定虚拟路由器的ID,一定要和从上的保持一致
priority 100 #指定权重,数字越大优先级越高
advert_int 1
authentication { #认证的相关信息
auth_type PASS #定义认证数据类型为密码
auth_pass 123456 #密码暂定123456
}
virtual_ipaddress { #定义VIP,VIP指的是高可用指定的固定IP地址,不论主从切换后IP都是这个
192.168.2.100
}
track_script {
chk_nginx #加载定义的chk_nginx脚本
}
}
写监控脚本
[root@yt-01 ~]# vim /usr/local/sbin/check_ng.sh #keepalived的监控脚本,把下面代码粘贴进去
#!/bin/bash
#时间变量,用于记录日志
d=`date --date today +%Y%m%d_%H:%M:%S`
#计算nginx进程数量
n=`ps -C nginx --no-heading|wc -l`
#如果进程为0,则启动nginx,并且再次检测nginx进程数量,
#如果还为0,说明nginx无法启动,此时需要关闭keepalived
if [ $n -eq "0" ]; then
/etc/init.d/nginx start
n2=`ps -C nginx --no-heading|wc -l`
if [ $n2 -eq "0" ]; then
echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log
#杀掉keepalived,是为了防止脑裂。脑裂指的是高可用集群中,当主从切换时,主上的keepalived还在启动,会和从争抢VIP,导致后台链接服务器时,不知道连接哪台服务器好,导致出错。
systemctl stop keepalived
fi
fi
[root@yt-01 ~]# chmod 755 /usr/local/sbin/check_ng.sh ##给脚本755权限
脚本解读: 如果进程里面没发现nginx那就代表着服务宕机了,然后脚本自动的再次启动nginx服务。 如果服务还是不可以启动,就把启动报错日志输入到指定的位置,然后把keepalived也关闭。
为什么需要关闭keepalived呢? 行业里面有个名词叫做“脑裂”,如果主服务宕机,从服务势必会马上启动顶替主服务再次服务,如果主服务的keepalived没有关闭,一定会造成混乱,两台机器都争抢服务。
在高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体、动作协调的HA系统,就分裂成为2个独立的个体。由于相互失去了联系,都以为是对方出了故障。两个节点上的HA软件像“裂脑人”一样,争抢“共享资源”、争起“应用服务”,就会发生严重后果——或者共享资源被瓜分、2边服务都起不来了;或者2边服务都起来了,但同时读写“共享存储”,导致数据损坏。
高可用中,绝对不可以发生的脑裂问题!
启动keepalived服务
[root@yt-01 ~]# systemctl start keepalived
[root@yt-01 ~]# ps aux |grep keep
root 3887 0.0 0.1 120724 1400 ? Ss 15:57 0:00 /usr/sbin/keepalived -D
root 3888 0.0 0.2 120724 2748 ? S 15:57 0:00 /usr/sbin/keepalived -D
root 3889 0.0 0.2 124980 2744 ? S 15:57 0:00 /usr/sbin/keepalived -D
root 3914 0.0 0.0 112680 972 pts/1 R+ 15:57 0:00 grep --color=auto keep
[root@yt-01 ~]# ps aux |grep nginx
root 3866 0.0 0.0 20500 628 ? Ss 15:54 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody 3867 0.0 0.3 22944 3216 ? S 15:54 0:00 nginx: worker process
nobody 3868 0.0 0.3 22944 3216 ? S 15:54 0:00 nginx: worker process
root 3946 0.0 0.0 112680 972 pts/1 R+ 15:57 0:00 grep --color=auto nginx
停掉keepalived,测试是否会重新加载
[root@yt-01 ~]# /etc/init.d/nginx stop
[root@yt-01 ~]# ps aux |grep nginx
root 4093 0.0 0.0 20500 628 ? Ss 15:58 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody 4097 0.0 0.3 22944 3216 ? S 15:58 0:00 nginx: worker process
nobody 4098 0.0 0.3 22944 3216 ? S 15:58 0:00 nginx: worker process
root 4106 0.0 0.0 112680 968 pts/1 R+ 15:58 0:00 grep --color=auto nginx
还是会再加载
#查看日志#
[root@yt-01 ~]# tail /var/log/messages
[root@yt-01 ~]# ifconfig -a ##这个命令查看不到VIP
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.2.180 netmask 255.255.255.0 broadcast 192.168.2.255
inet6 fe80::6b0e:c2eb:de7a:3662 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:14:f6:1b txqueuelen 1000 (Ethernet)
RX packets 16608 bytes 11284525 (10.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10439 bytes 3068832 (2.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 1 (Local Loopback)
RX packets 617885 bytes 308269731 (293.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 617885 bytes 308269731 (293.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@yt-01 ~]# ip add ##查看到的到VIP xxx/32
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:14:f6:1b brd ff:ff:ff:ff:ff:ff
inet 192.168.2.180/24 brd 192.168.2.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.2.100/32 scope global ens33 ##VIP为192.168.2.100/32##
valid_lft forever preferred_lft forever
inet6 fe80::6b0e:c2eb:de7a:3662/64 scope link
valid_lft forever preferred_lft forever
2.3 配置keepalived从
更改配置文件
[root@yt-02 ~]# > /etc/keepalived/keepalived.conf ##清空原始配置文件
[root@yt-02 ~]# vim /etc/keepalived/keepalived.conf ##复制下面代码,代替原配置文件
global_defs {
notification_email {
test@test.com
}
notification_email_from test@test.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script chk_nginx {
script "/usr/local/sbin/check_ng.sh"
interval 3
}
vrrp_instance VI_1 {
state BACKUP #指定角色为从
interface ens33
virtual_router_id 51
priority 90 #指定权重为90,低于主
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.2.100
}
track_script {
chk_nginx
}
}
编辑监控脚本
[root@yt-02 ~]# vim /usr/local/sbin/check_ng.sh ##keepalived监控脚本路径是在keepalived配置文件中指定的,把下面代码粘贴进去
#!/bin/bash
#时间变量,用于记录日志
d=`date --date today +%Y%m%d_%H:%M:%S`
#计算nginx进程数量
n=`ps -C nginx --no-heading|wc -l`
#如果进程为0,则启动nginx,并且再次检测nginx进程数量,
#如果还为0,说明nginx无法启动,此时需要关闭keepalived
if [ $n -eq "0" ]; then
systemctl start nginx ##因为是yum安装,启动有点不一样
n2=`ps -C nginx --no-heading|wc -l`
if [ $n2 -eq "0" ]; then
echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log
systemctl stop keepalived
fi
fi
[root@yt-02 ~]# chmod 755 /usr/local/sbin/check_ng.sh ##给脚本755权限
启动keepalived
[root@yt-02 ~]# systemctl start keepalived
[root@yt-02 ~]# ps aux |grep keep
root 7174 0.0 0.1 120720 1404 ? Ss 20:46 0:00 /usr/sbin/keepalived -D
root 7175 0.0 0.2 120720 2752 ? S 20:46 0:00 /usr/sbin/keepalived -D
root 7176 0.0 0.2 124976 2740 ? S 20:46 0:00 /usr/sbin/keepalived -D
root 7218 0.0 0.0 112632 660 pts/0 D+ 20:46 0:00 grep --color=auto keep
[root@yt-02 ~]# ps aux |grep nginx
root 7199 0.0 0.2 122904 2108 ? Ss 20:46 0:00 nginx: master process /usr/sbin/nginx
nginx 7200 0.0 0.3 123368 3152 ? S 20:46 0:00 nginx: worker process
root 7232 0.0 0.0 112676 976 pts/0 S+ 20:47 0:00 grep --color=auto nginx
停掉keepalived,测试是否会重新加载
[root@yt-02 ~]# systemctl stop nginx
[root@yt-02 ~]# ps aux |grep nginx
root 7413 0.0 0.2 122904 2108 ? Ss 20:48 0:00 nginx: master process /usr/sbin/nginx
nginx 7414 0.0 0.3 123368 3152 ? S 20:48 0:00 nginx: worker process
root 7485 0.0 0.0 112676 972 pts/0 S+ 20:48 0:00 grep --color=auto nginx
还是会再加载
[root@yt-02 ~]# ifconfig -a ##查看不到VIP
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.2.183 netmask 255.255.255.0 broadcast 192.168.2.255
inet6 fe80::62d6:aa12:bb83:d01a prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:0d:54:47 txqueuelen 1000 (Ethernet)
RX packets 16098 bytes 18728112 (17.8 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4869 bytes 499007 (487.3 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 1 (Local Loopback)
RX packets 16 bytes 1360 (1.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 16 bytes 1360 (1.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@yt-02 ~]# ip add ##查看到的到VIP xxx/32
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:0d:54:47 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.183/24 brd 192.168.2.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.2.100/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::62d6:aa12:bb83:d01a/64 scope link
valid_lft forever preferred_lft forever
2.4 怎么区分主从上的nginx
可以去更改nginx默认主页的文件内容,比如:主上改成This is Master,从上改成This is backup。这里,我懒了一下,就不去修改了,因为编译安装和yum安装的nginx默认页面区别很明显了。
nginx默认主页的文件地址
主上:更改 /data/wwwroot/default/index.html 文件 (编译安装)
如果找不到,就去/usr/local/nginx/html/index.html
从上:/usr/share/nginx/html/index.html 文件 (yum安装)
主:
从:
VIP:
2.5 测试高可用
先确定好两台机器上nginx差异,比如可以通过curl -I 来查看nginx版本,通过浏览器访问各个IP测试。
-
测试1:关闭master上的nginx服务
chkng脚本可以再次启动nginx的,我们上面测试过,无法关闭的 -
测试2:在master上增加iptabls规则 iptables -I OUTPUT -p vrrp -j DROP
用防火墙关闭vrrp协议,也不能让keepalived的主达到切换到从的目的。 我们还是恢复过来,iptables -F -
测试3:关闭master上的keepalived服务
[root@yt-01 ~]# systemctl stop keepalived
访问VIP成功切换到从上。
- 测试4:启动master上的keepalived服务
[root@yt-01 ~]# systemctl start keepalived
VIP马上又调回了主上面,这些过程,都可以在/var/log/messages日志里面看到。
一般工作中,我们的从服务器一般最少都有3台,我们在设置权重时,可以给不同的从服务器设置不同的权重,从高到低,方便控制。