一、keepalived的组成
keepalived就是vrrp协议在Linux主机上,以守护进程方式运行的实现,其能够根据配置文件,自动生成IPVS规则,并且还可以对各RS做健康状态检测
- 核心组件
vrrp stack:vrrp协议实现的核心
ipvs wrapper:为集群中的节点生成ipvs规则
checkers:为ipvs集群内的各主机做健康状态检测
- 控制组件:实现keepalived配置文件的分析、加载
- IO复用器
- 内存管理组件:管理高可用时的内存空间占用
二、安装
1. 安装前配置环境
- 同步个节点时间
- 配置iptables及selinux
- 各节点之间可通过主机名ping通(非必须)
- 确保各节点用于服务的网卡支持多播通信
2. 安装
从CentOS 6.4之后,keepalived就被收录进base仓库中,可直接使用yum安装
yum install -y keepalived
三、相关文件
- 主配置文件:
/etc/keepalived/keepalived.conf
/usr/bin/genhash
- 核心程序:
/usr/sbin/keepalived
- Unit file:
/usr/lib/systemd/system/keepalived.service
四、指令意义
其配置文件为/etc/keepalived/keepalived.conf
,主要分为三个配置段:全局配置段(GLOBAL CONFIGURATION)、VRRPD CONFIGURATION、LVS CONFIGURATION。
1. 全局配置段
global_defs {
notification_email:指明出错时给谁发邮件
notification_email_from:指明发送邮件时的发件人
smtp_server:指明从那个邮件服务器发出
smtp_connect_timeout:连接邮件服务器的超时时长
router_id:当前物理设备的唯一标示
trank_interface:定义跟踪的网卡,用{}配置段定义,里面写网卡名;
nopreempt:定义为非抢占模式
preempt_delay N :抢占模式下,节点出发新选举操作的延时时长。
vrrp_mcast_group4:vrrp协议发送心跳的组播网段
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval
vrrp_gna_interval
}
2. vrrp配置段
vrrp_instance NAME { :给出实例名称,要唯一
state MASTER|BUCKUP:自己的初始状态,只有两个master和backup
interface eth0:要把虚拟地址配置在哪个网卡上
virtual_router_id 51:虚拟路由的标识符,0-255
priority 100:定义优先级,0-255
advert_int 1:心跳信息发送的频率,单位为秒钟
authentication { PASS为简单密码认证,可使用openssl rand -hex 4生成随机子串
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
标准格式:<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE>
简单示例:192.168.2.100/24 brd 192.168.2.0 dev ens32
}
3. lvs配置段
virtual_server <IP> <PORT> {
delay_loop #:健康状态检测多少次判定为失败
lb_algo rr|wrr|lc|wlc|lblc|sh|dh:调度方法
lb_kind NAT|DR|TUN:调度类型
persistence_timeout # :持久链接时长
ha_suspend:如果没有定义VIP的话,那么健康状态检测也停止
virtualhost <string>:定义虚拟主机
sorry_server <IPADDR> <PORT>:定义sorry server
real_server <IPADDR> <PORT> { 定义real server
weight:权重
HTTP_GET | TCP_CHECK { 定义使用http协议做健康状态检测
url {
path <string>:指明路径
digest <string>:通过校验码验证
status_code <int>:通过状态结果获取
}
nb_get_retry <int>:如果链接超时重试几次
deleay_before_retry <int>
connect_ip:指明需要检查的IP地址
connect_port:指明需要链接的端口
bindto <IP>:指明通过本机的哪个接口发出检测
connect_timeout:超时时间
}
}
}
4. vrrp_script配置段
示例1:监控服务是否正常运行
vrrp_script NAME { :为脚本起一个名字
script "killall -0 nginx" :killall -0不会真正的杀死进程,如果返回成功则表示这个进程正常运行中
interval 2 :每隔2秒检测1次
weight -4 :如果脚本检查失败了,其权重减4
fall 2 :需要检查2次才判定为失败
rise 2 :检测2次成功才判定为成功
user USER :使用哪个用户运行这个脚本
}
示例2:手动调度主节点
vrrp_script chk_down {
script "/bin/bash -c '[[ -e /etc/keepalived/down ]]' && exit 1 || exit 0"
interval 2
weight -30
fall 2
rise 2
user root
}
五、配置示例
1. 高可用LVS
实验环境:两台RS作为后端的web,两台服务器作为调度器,并在调度器中启用keepalived实现高可用,关于IPVS的相关内容可以点击这里
RIP1:192.168.60.100 RIP2:192.168.60.110
DIP1:192.168.60.120 DIP2:192.168.60.130
VIP:192.168.60.200
- 第一步:手动创建IPVS集群,使得DR模型实现
1. 调度器安装ipvsadm工具,配置VIP地址,使得各节点可以ping通VIP地址
~]# yum install ipvsadm -y
~]# ip addr add 192.168.60.200 dev ens32
2. 在两台RS中安装httpd并启动,使用不同的测试网页供后续测试
3. 两台RS中加入ARP响应参数,并添加VIP地址,这里使用一个脚本完成
#!/bin/bash
vip=192.168.60.200
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/ens32/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/ens32/arp_announce
ip addr add ${vip}/32 broadcast $vip dev lo label lo:0
ip route add $vip dev lo:0
;;
stop)
ip addr del $vip dev lo label lo:0
ip route del $vip dev lo:0
echo 0 > /proc/sys/net/ipv4/conf/ens32/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/ens32/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
;;
esac
4. 在调度器中加入IPVS规则,测试IPVS集群
~]# ipvsadm -A -t 192.168.60.200:80 -s wrr
~]# ipvsadm -a -t 192.168.60.200:80 -r 192.168.60.100 -g -w 1
~]# ipvsadm -a -t 192.168.60.200:80 -r 192.168.60.110 -g -w 2
~]# 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.60.200:80 wrr
-> 192.168.60.100:80 Route 1 0 0
-> 192.168.60.110:80 Route 2 0 0
5. 测试成功后,将调度器的ipvs规则清空、VIP地址删除,第一步中手动实现IPVS集群创建只是为了测试后端RS可以有效的被调度
- 第二步:两台调度器中安装keepalived服务、httpd服务,并编辑配置文件
! Configuration File for keepalived
global_defs {
notification_email {
busyops@outlook.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens32
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.60.200
}
}
virtual_server 192.168.60.200 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
persistence_timeout 0
protocol TCP
sorry_server 127.0.0.1 80
real_server 192.168.60.100 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.60.110 80 {
weight 2
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
---------------------------------------------------------
需要注意,此配置文件为主节点的配置文件,从节点需要将角色改为BACKUP,优先级也需要降低
- 第三步:停止不同的RS查看健康状态检测情况,停止不同的调度器查看VIP和服务是否可以正常访问,停止全部的RS查看sorry_server是否正常上线
2. 双主模型高可用nginx
实验环境:两台RS作为后端的web,两台Nginx分别同时代理后端的两台RS,用户可以通过任意节点访问后端的web
RS1:192.168.60.100 RS2:192.168.60.110
Nginx1:192.168.60.120 VIP1:192.168.60.210
Nginx2:192.168.60.130 VIP2:192.168.60.220
- 第一步:在两台RS中安装httpd,提供不同的网页文件以便测试
- 第二步:两台Nginx服务器通过upstream将后端的web加入调度,更多Nginx相关配置可以点击这里
1. 直接使用官方yum源进行安装
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
2. 启用upstream配置
http {
...
upstream web {
server 192.168.60.100 weight=1;
server 192.168.60.110 weight=2;
}
server {
location / {
proxy_pass http://web;
}
}
...
}
- 第三步:两台Nginx主机安装Keepalived并配置双主模型,通过手动停止Nginx服务,测试切换情况
Nginx1的keepalived配置
! Configuration File for keepalived
global_defs {
notification_email {
busyops@outlook.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL1
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_down {
script "/bin/bash -c '[[ -e /etc/keepalived/down ]]' && exit 1 || exit 0"
interval 2
weight -20
fall 2
rise 2
}
vrrp_script chk_nginx {
script "/usr/bin/killall -0 nginx"
interval 2
weight -20
fall 2
rise 2
user root
}
vrrp_instance VI_1 {
state MASTER
interface ens32
virtual_router_id 151
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.60.210/24 brd 192.168.60.255 dev ens32 label ens32:0
}
track_script {
chk_down
chk_nginx
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens32
virtual_router_id 52
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
virtual_ipaddress {
192.168.60.220/24 brd 192.168.60.255 dev ens32 label ens32:1
}
}
Nginx2的keepalived配置
! Configuration File for keepalived
global_defs {
notification_email {
busyops@outlook.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL2
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_down {
script "/bin/bash -c '[[ -e /etc/keepalived/down ]]' && exit 1 || exit 0"
interval 2
weight -20
fall 2
rise 2
}
vrrp_script chk_nginx {
script "/usr/bin/killall -0 nginx"
interval 2
weight -20
fall 2
rise 2
user root
}
vrrp_instance VI_1 {
state BACKUP
interface ens32
virtual_router_id 151
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.60.210/24 brd 192.168.60.255 dev ens32 label ens32:0
}
}
vrrp_instance VI_2 {
state MASTER
interface ens32
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
track_script {
chk_down
chk_nginx
}
virtual_ipaddress {
192.168.60.220/24 brd 192.168.60.255 dev ens32 label ens32:1
}
}
六、遇到的问题
1. 使用down文件切换主节点
老版本的Keepalived中,vrrp_script配置段添加切换节点配置如下
vrrp_script chk_down {
script "[[ -e /etc/keepalived/down ]] && exit 1 || exit 0"
interval 2
weight -20
fall 2
rise 2
}
但是在新版本中(我的是1.3.5),如果继续使用此配置,会发现日志中报错Unable to access script [[
,将其改为如下即可,日志会提示VRRP_Script(chk_down) succeeded
vrrp_script chk_down {
script "/bin/bash -c '[[ -e /etc/keepalived/down ]]' && exit 1 || exit 0"
interval 2
weight -20
fall 2
rise 2
}
2. keepalived_script用户
如果没有创建keepalived_script用户,日志中会出现WARNING - default user 'keepalived_script' for script execution does not exist - please create.
但vrrp_script配置段的down配置并没有影响,暂时不清楚这个用户到底会导致什么问题
3. killall探测无效
- 如果日志中出现
Cannot find script killall in path
,安装killall命令即可,其安装包为psmisc.x86_64 - 安装完
psmisc.x86_64
依然发现报错WARNING - script `killall` resolved by path search to `/usr/bin/killall`. Please specify full path.
,于是我将配置段改为了如下
vrrp_script chk_nginx {
script "/usr/bin/killall -0 nginx"
interval 2
weight -20
fall 2
rise 2
}
发现一个节点可以实现killall命令探测健康状态,一个节点不可以,于是又加了一行user配置,所以保险起见还是全加上
vrrp_script chk_nginx {
script "/usr/bin/killall -0 nginx"
interval 2
weight -20
fall 2
rise 2
user root
}
4. 无法解释的玄学问题
- 虚拟路由ID冲突问题:在做双主实验的过程中,有一个虚拟路由的主节点VIP怎么都上不来,发现日志报错
ip address associated with VRID 51 not present in MASTER advert :
网上的说法是虚拟路由ID冲突,但是我家里面谁能跟我冲突呢,太TM玄学了 - 不知道什么问题:两个节点配置完成后,通过VIP无论如何都无法访问后端的RS,用Nginx去访问RS和用物理机直接访问RS都是没问题的。于是我尝试将VIP换了一个地址,就很意外的可以访问了
- 双主模型配置完成后,一台Keepalived怎么都运行不起来,日志报错
Can‘t open PID file /run/keepalived.pid (yet?) after start: No such file or directory
,于是我一气之下恢复快照,所有配置文件(nginx+keepalived)全都复制的另一台keepalived的,然后就又能运行了。。。。
希望这些踩过的坑能对你有帮助