|
LVS-DR + Keepalived
什么是Keepalived
keepalived是一个类似于layer3, 4 , 5交换机制的软件,也就是我们平时说的第3层、第4层和第5层交换。
Keepalived的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到, 并将有故障的web服务器从系统中剔除,当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的web服务器。
Keepalived 的工作流程和原理
Keepalived 最初的设计目标就是给IPVS提供HA高可用的底层工具,而IPVS是工作在内核实现的,ipvs不依赖任何后端的存储,只要规则存在就可以, 为此keepalived为ipvs实现了规则和vip在节点间的流转,但是要实现vip在节点之间的流转需要依赖于VRRP(虚拟路由冗余协议),VRRP的工作原理是能将多个物理设备虚拟成一个物理设备,VRRP协议最初跟Keepalived没有关系的,最初的主要目的是解决局域网LAN网络,当客户端需要连接外网的路由指定方式,最常用的方式有两种:静态和动态,当一个客户端需要跟外部网络联系的时候只需要发一个ARP请求,这时路由就会响应ARP请求最终能获得一个网关地址。通过这种动态获取的方式我们可以设置过个路由,哪个响应的快就从哪个路由把报文送出去,由此我们达到了路由冗余的功能,进而使得用户不会因一个路由故障而不能访问,但是这种方式配置需要用户安装专门的ARP客户端工具和很多繁杂的配置,所以比较麻烦,而后就有了第二种方式,基于动态路由协议,比如rip2,ospf等... 但是需要在客户端做出额外的配置 很繁杂。而最简单的方法就是使用默认静态路由,但是这种方法最致命的的就是没有冗余,如果路由挂了那么全部都瘫痪,将无法工作。而这时需要一种在网关本身就能实现冗余的功能,正巧此时此刻我们的Keepalived诞生了,它能将两台物理路由器接口虚拟成一个接口并向外提供服务。
VRRP
VRRP(Virtual Routing Redundant Protocol)可以通过在多台路由器组合成一个虚拟路由组(一个VRRP组)之间共享一个虚拟IP(VIP)解决静态配置的问题,此时仅需要客户端以VIP作为其默认网关即可,虚拟IP配置在哪个路由设备上取决于VRRP的工作机制,实现网关地址漂移;MASTER与BACKUP设备之间有优先级设定,数字越大优先级越高,通过各节点之间不停的传送通告信息来确认对方是否在线;当MASTER宕机的时候,虚拟IP会漂移到备用路由上,实现前端网关的高可用
‍
VRRP 和Keepalived的关系以及工作流程
VRRP 将两台物理路由设备接口虚拟成一个接口,向外提供服务,只提供一个ip进行服务,通过内部协议协调或者配置,工作在一个节点上,另外一个作为备用节点,一旦主节点出故障,备用节点就可以替代主节点提供服务,在vrrp协议中可以有一个主多个从,也可以是多主。在一组物理设备山可以虚拟多组,Keepalived 是实现VRRP协议能够工作在linux上的服务软件,此软件本身能都在主机接口上上配置虚拟地址或者是虚拟路由的功能,而且能基于VRRP协议来选举其中某一个节点来使用VIP,而且在节点故障时能转移到其它备用节点,到底转移到哪个节点是依赖于他们自身的优先级。对于Keepalived来说实现vip转移时不够的还需要在备用节点上启用ipvs规则在实现vip飘逸的时候还需要实现ipvs的生效以及后面的节点的健康检查,比如节点一故障了,ip会飘逸到节点二上,但是节点二的服务没有启动,ipvs规则没有启动那么就飘逸就没有意义了,所以在实现ip地址飘逸的时候还要判断我们高可用集群提供的其它健康状况,所以Keepalived 自身提供的有脚本,可以实现在飘逸的时候检查HA高可用节点的服务或者功能,只要监测成功则飘逸,不成功则表示对方不满足飘逸条件,不漂移。 VRRP工作原理图如下:

上面的基本理论知识点就暂且介绍到这里!! LVS+Keepalived 是淘宝采用过的企业级架构,现在还有没有使用就不知道了。为了让大家知了解配置步骤先简单的介绍一下配置的主要流程。有一下四大部分:
一、配置架构图和配置信息,包括ip分配信息、服务信息、简称注意事项等...
二、准备LVS-DR-realserver 的环境准备工作
三、配置HA基础服务信息,包括主机名、双机互信,selinux等...
四、正式进入核心配置
国际惯例,废话不多说,下面我们就直接说配置过程!!!!
一、配置架构图和配置信息

系统版本和软件地址:
系统平台 REDHAT 5.8
应用软件 LVS+keepalived
软件包地址,里面有相应的软件包 根据需要下载
http://www.linuxvirtualserver.org/software/kernel-2.6/
http://www.keepalived.org/software/
IP配置信息:
LVS-DR-Master 172.16.163.10 后面文章中简称HA1
LVS-DR-Backup 172.16.163.11 后面文章中简称HA2
LVS-DR-vip 172.16.163.1
LVS-DR-realserver1 172.16.163.13 后面文章中简称RS1
LVS-DR-realserver2 172.16.163.14 后面文章中简称RS2
本文的服务搭建采用的事LVS-DR +Keepalived 架构所以先配置 DR模型的后端RS 环境。在企业中使用负载均衡DR模型的几率是非常大的 ,为了方便期间写了脚本,只需配置好敲回车就可以完成RS的环境搭建。
二、准备LVS-DR-realserver 的环境准备工作
1,首先配置本机RS1 IP 172.16.163.13 和 RS2 IP 并重启网卡,确保两主机能ping通
# vim /etc/sysconfig/network-scripts/ifcfg-eth0
# /etc/init.d/network restart
2,编写RealServer脚本并运行
vim /root/RealServer.sh 把一下内容复制粘贴到脚本中
#!/bin/bash
#
# Script to start LVS DR real server.
# chkconfig: - 90 10
# description: LVS DR real server
#
. /etc/rc.d/init.d/functions
VIP=172.16.163.0.1
host=`/bin/hostname`
case "$1" in
start)
# Start LVS-DR real server on this machine.
/sbin/ifconfig lo down
/sbin/ifconfig lo up
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
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev lo:0
;;
stop)
# Stop LVS-DR real server loopback device(s).
/sbin/ifconfig lo:0 down
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
;;
status)
# Status of LVS-DR real server.
islothere=`/sbin/ifconfig lo:0 | grep $VIP`
isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
if [ ! "$islothere" -o ! "isrothere" ];then
# Either the route or the lo:0 device
# not found.
echo "LVS-DR real server Stopped."
else
echo "LVS-DR real server Running."
fi
;;
*)
# Invalid entry.
echo "$0: Usage: $0 {start|status|stop}"
exit 1
;;
esac
3,给予脚本执行权限,并执行配置RS环境。此脚本通用语LVS负载均衡,可以根据vip不同更改即可使用。
# chmod +x /root/RealServer.sh
# ./root/RealServer.sh
4,配置时间同步,由于笔者的实验环境特殊,暂用此方法,也可以使用ntpdate的方法进行更新
为了以后时间保持正常可以定义crontab
# hwclock –s
# crontab -e
*/5 * * * * /sbin/ntpdate 172.16.0.1 &> /dev/null
5,测试环境是否配置成功,方法很简单(附图)
# ifconfig
# route -n
‍二、准备LVS-DR-realserver 的环境准备工作‍‍二、准备LVS-DR-realserver 的环境准备工作‍‍‍‍3,给予执行权限并执行脚本‍‍‍
路由信息如下

好了RS1 的环境已经配置好了,相同的配置在RS2上执行一遍即可!!!!
6,复制脚本 和时间crontab 到RS2 ,并执行此脚本即可
scp -p /root/RealServer.sh root@172.16.163.14:/root/
scp -p /var/spool/cron/root root@172.16.163.14:/var/spool/cron/
7,在两个RS上装Httpd服务,提供页面并开启服务
RS1 上运行
# yum install httpd
# vim /var/www/html/index.html
RS13
# service httpd restart
RS2 上运行
# yum install httpd
# vim /var/www/html/index.html
RS14
# service httpd restart
基本的RS 环境配置完毕了 现在该配置第三大块内容了!!!
三、配置HA 基础信息
1,关掉selinux,配置主机名,保持主机名一致。
# setenforce 0
# hostname node1.laogen.com
# vim /etc/sysconfig/network
##修改如下:
HOSTNAME=node1.laogen.com #当然HA2上要改为node2
2,主机名称解析
# vim /etc/hosts
##添加如下内容
172.16.163.10 node1.doubao.com node1
172.16.163.11 node2.doubao.com node2
3,配置双机互信
先在 HA1 上做
#ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' 生成密钥
#ssh-copy-id -i .ssh/id_rsa.pub root@172.16.163.11 ##将公钥文件发送到HA2上边
# ssh node2 'ifconfig' 在HA2上做
#ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' 生成密钥
#ssh-copy-id -i .ssh/id_rsa.pub root@172.16.163.10 ##将公钥文件发送到HA2上边
#ssh node2 'ifconfig'
4,时间同步,这里应该注意的事 在做双HA 的时候时间一定要同步,因为时间如果差距过大会导致很多莫名其妙的各种错误问题
由于笔者的实验环境特殊,暂用此方法,也可以使用ntpdate的方法进行更新
为了以后时间保持正常还可以可以定义crontab来校队时间
# hwclock –s
# crontab -e
*/5 * * * * /sbin/ntpdate 172.16.0.1 &> /dev/null
5,把crontab和hosts主机名解析复制到HA2上,让其双方保持一致。
ssh node2 'hwclock –s'
scp /var/spool/cron/root node2:/var/spool/cron/
scp /etc/hosts node2:/etc/
到此,两台HA的简单基本配置完毕 下面我们开始进入主配置部分了!!!
四、进入正式的主配置
1,两台HA上分别装上keepalived 包和ipvsadm, ipvsadm本系统自带的有,所以直接可以安装。
# yum --nogpgcheck localinstall keepalived-1.2.7-5.el5.i386.rpm
# yum install -y ipvsadm
2,配置HA1的 keepalived 主配置文件。
配置文件如下:
! Configuration File for keepalived
######################### 全局配置部分
##########################################
global_defs {
notification_email {
root@localhost
}
notification_email_from keepavlied@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
#######################模拟 HA 高可用地址漂移,自监测脚本,完成维护模式切换
########################################################
vrrp_script chk_schedown {
script "[ -e /etc/keepalived/down ] && exit 1 || exit 0"
interval 1
weight -5
fall 2
rise 1
}
########################################定义虚拟路由段
###########################################################
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 58
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass keepalivedpass
}
virtual_ipaddress {
172.16.163.1/16 dev eth0 label eth0:0
}
track_script {
chk_schedown
}
}
########################################Virtual_server与real_server设置段
###############################################################################
virtual_server 172.16.163.1 80 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.0.0
# persistence_timeout 50
protocol TCP
sorry_server 127.0.0.1 80
real_server 172.16.163.13 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 2
nb_get_retry 3
delay_before_retry 1
}
}
real_server 172.16.163.14 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 2
nb_get_retry 3
delay_before_retry 1
}
}
}
3,配置文件复制到 node2一份,两个HA 配置文件基本相同,只需修改少许地方即可
# scp keepalived.conf node2:/etc/keepalived/
4,修改 node2 的配置文件
# vim /etc/keepalived/keepalived.conf
state MASTERT 改为 Pstate BACKUP 在22行
priority 101 改为 priority 100 在25行 此时此刻我们的Keepalived 已经可以启动工作了,让我启动两个HA 验证奇迹的一刻吧!!
5,两个HA节点的启动服务
# service keepalived start
# ssh node2 'service keepalived start'
6,查看看日志和ip 验证keepalived 是否启动起来
# tail -f /var/log/messages
# ifconfig 

7,查看RS条目规则是否加载进来
# ipvsadm -L -n 
配置keepalived已经成功,下面测试一下 一台RS挂掉 keepalived是否会中自动去除RS,
如果RS恢复 keepalived会不会自动添加进来,并且有邮件提醒,这就是健康监测.
8,关闭其中一台RS 的httpd 服务测试,是否会自动踢出已故障的RS节点。方法很简单。
# service httpd stop 
9,让RS的httpd 服务上线 监测是否会自动添加,实现邮件提醒
# service httpd start 
实现RS全部挂掉之后网站都瘫痪, 让两个HA 节点提供服务,返回用户提示页面,
比如提示用户所访问的网页正在维护中...
‍
10,两台 HA都安装上 httpd服务,并提供错误页面
# yum install -y httpd
# vim /var/www/html/index.html
添加网页内容
Maintenance of the site...
# service httpd start
# curl http://172.16.163.10
# curl http://172.16.163.11
11, 编辑配置文件,配置错误返回页面
当然了我配置文件已经贴出来了 里面都添加的有,在这里我提示一下,希望大家能知道此命令的作用
# vim /etc/keepalived/keepalived.conf
大概在34行下面添加,两个HA节点都要添加
sorry_server 127.0.0.1 80
12,重启两个HA节点keepalived服务
# service keepalived start
# ssh node2 'service keepalived start'
13,关闭所有RS httpd 服务,开始验证由两台HA 提供的访问错误提示页面。
分别在两台RS上执行;
# service httpd stop 这里缺少了第14不,没有问题直接跳过执行 第15步即可!!!
15,在主节点上查看 ipvs条目
# ipvsadm -L -n

访问vip主页试试 看!!!

下面我们开始测试另外一个主要的功能--模拟 HA 高可用地址漂移,自写监测脚本,完成维护模式切换!!!
16,定义漂移ip 选项参数,两个HA 节点都要添加。当然前面给出的配置文件里面已经添加了。这里列出来是让大家了解,这一段代码是什么意思和什么作用。
# vim /etc/keepalived/keepalived.conf
大概在第11行下面添加,也就是是在global_defs 这段结束后面添加
vrrp_script chk_schedown {
script "[ -e /etc/keepalived/down ] && exit 1 || exit 0"
interval 1
weight -2
fall 2
rise 1
}
17,定义ip漂移 参数选项 执行规范,就是在什么场景下执行,两个HA 都添加。
在172.16.163.1/16 dev eth0 label eth0:0 后面添加 { } 是一整句 在这个}后面添加 大概在33行后。同样上面的配置文件里已经给出,这里列出来希望大家能明白什么作用。
# vim /etc/keepalived/keepalived.conf
track_script {
chk_schedown
}
18,重启连个HA 的 keepalived 服务
# service keepalived restart
# ssh node2 'service keepalived restart'
19,使HA1 主节点故障实现 节点故障vip飘逸,实现高可用功能。
# cd /etc/keepalived/
# touch down
20,查看日志和HA2 IP 信息
# tail /var/log/messages
21,查看ip是否飘逸到HA2从节点上。
# ssh node2 'ifconfig' 
漂移成功结束!!!
如何在VRRP事务发生时,发送警告邮件给指定的管理员,并管理员提供的服务名判断其状态并重启和关闭某个服务。看下面脚本完满足你的要求!!!
22,添加脚本让其支持上面所提出的功能
下面的脚本可以接受选项,其中:
-s, --service SERVICE,...:指定服务脚本名称,当状态切换时可自动启动、重启或关闭此服务;
-a, --address VIP: 指定相关虚拟路由器的VIP地址;
-m, --mode {mm|mb}:指定虚拟路由的模型,mm表示主主,mb表示主备;它们表示相对于同一种服务而方,其VIP的工作类型;
-n, --notify {master|backup|fault}:指定通知的类型,即vrrp角色切换的目标角色;
-h, --help:获取脚本的使用帮助;
# vim /etc/keepalived/notify.sh
#!/bin/bash
# Author: MageEdu
# description: An example of notify script
# Usage: notify.sh -m|--mode {mm|mb} -s|--service SERVICE1,... -a|--address VIP -n|--notify {master|backup|falut} -h|--help
#contact='linuxedu@foxmail.com'
helpflag=0
serviceflag=0
modeflag=0
addressflag=0
notifyflag=0
contact='root@localhost'
Usage() {
echo "Usage: notify.sh [-m|--mode {mm|mb}] [-s|--service SERVICE1,...] "
echo "Usage: notify.sh -h|--help"
}
ParseOptions() {
local I=1;
if [ $# -gt 0 ]; then
while [ $I -le $# ]; do
case $1 in
-s|--service)
[ $# -lt 2 ] && return 3
serviceflag=1
services=(`echo $2|awk -F"," '{for(i=1;i |
|