2020-04-04 Keepalived高可用集群应用实践(三)

1. Nginx负载均衡配合Keepalived服务的案例实战

1.1 在lb01和lb02上配置Nginx负载均衡

结合前面介绍的Nginx负载均衡的环境,根据下图调整好主负载均衡器lb01、备用负载均很器lb02服务器上Nginx负载均衡环境,两台服务器的安装基础环境一致。

Nginx负载均衡器高可用逻辑图

这里使用的Nginx负载均衡的配置如下:

[root@lb01 ~]# cd /application/nginx/conf/
[root@lb01 conf]# cat nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream www_pools {    ---这里定义Web服务器池,包含了106和108两个Web节点
        server 192.168.9.106:80  weight=1;
        server 192.168.9.108:80  weight=1;
    }
    server {    ---这里定义代理的负载均衡域名虚拟主机
        listen       192.168.9.210:80;    ---请注意这里的配置,指定IP监听了
        server_name  www.etiantian.org;
        location / {
            proxy_pass http://www_pools;    ---访问www.etiantian.org,请求发送给www_pools里面的节点
        proxy_set_header Host $host;
        }
   }
}

提示:此配置仅代理了www.etiantian.org域名。

1.2 在lb01和lb02上配置Keepalived服务

此处使用单实例为例进行配置说明。lb01上Keepalived服务单实例主节点的配置如下:

[root@lb01 keepalived]# cat keepalived.conf
global_defs {
    router_id lb01
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.9.210/24 dev eth0 label eth0:3
    }
}

提示:VIP为192.168.9.210,即工作时需要把Nginx负载均衡代理的www.etiantian.org解析到这个VIP。
lb02上Keepalived服务单实例备节点的配置如下:

[root@lb02 keepalived]# cat keepalived.conf
global_defs {
    router_id lb02
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.9.210/24 dev eth0 label eth0:3
    }
}

1.3 用户访问准备及模拟实际访问

准备工作如下:
1)在客户端hosts文件里把www.etiantian.org域名解析到VIP 192.168.9.210上,正式场景需通过DNS解析。

192.168.9.210  www.etiantian.org

2)两台服务器也要配好Nginx负载均衡服务,并且确保后面代理的Web节点可以测试访问。

[root@lb01 conf]# tail -1 /etc/hosts
192.168.9.210   www.etiantian.org
[root@lb01 keepalived]# netstat -lntup|grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      28553/nginx: master
[root@lb01 keepalived]# ip addr|grep 192.168.9.210
    inet 192.168.9.210/24 scope global secondary eth0:3

下面模拟实际的访问。
1)通过在客户端浏览器输入“www.etiantian.org”测试访问,按Ctrl+F5组合键刷新几次,正常应该可以出现如下图所示的两种访问结果。

客户端访问负载均衡测试结果1

客户端访问负载均衡测试结果2

2)此时停止lb01服务器或者停掉Keepalived服务,观察业务是否正常:

[root@lb01 conf]# systemctl stop keepalived
[root@lb01 conf]# ip addr|grep 192.168.9.210

提示:严格来讲应该关掉服务器来模拟效果才是最佳的。
3)观察lb02备节点是否接管VIP 192.168.9.210。

[root@lb02 keepalived]# ip addr|grep 192.168.9.210
    inet 192.168.9.210/24 scope global secondary eth0:3

再次在客户端浏览器输入“www.etiantian.org”测试访问,按Ctrl+F5组合键刷新几次,正常应该可以出现和切换lb02前相同的访问结果。
4)开启lb01的Keepalived服务。

[root@lb01 conf]# systemctl start keepalived
[root@lb01 conf]# ip addr|grep 192.168.9.210
    inet 192.168.9.210/24 scope global secondary eth0:3

可以看到,VIP很快就接管回来了,此时浏览器访问结果依然正常。

2. 解决服务监听的网卡上不存在IP地址的问题

如果配置使用“listen 192.168.9.210:80;”的方式指定IP监听服务,而本地的网卡上没有192.168.9.210这个IP,Nginx就会报错:

[root@lb01 conf]# nginx
nginx: [emerg] bind() to 192.168.9.210:80 failed (99: Cannot assign requested address)

如果要实施双主(即主备)同时提供不同的服务,配置文件里指定了IP监听,备节点则会因为网卡实际不存在VIP报错。
出现上面问题的原因就是在物理网卡上没有与配置文件里监听的IP相应的IP,我们要让Nginx服务在网卡上没有指定监听的IP时也能启动,不报错,解决办法是在/etc/sysctl.conf中加入如下内核参数配置:

net.ipv4.ip_nonlocal_bind = 1
---此项表示启动Nginx而忽略配置中监听的IP是否存在,它同样适合Haproxy。

最后执行sysctl -p使上述修改生效。

3. 解决高可用服务只是针对物理服务器的问题

默认情况下,Keepalived软件仅仅在对方机器宕机或者Keepalived停掉的时候才会接管业务。但在实际工作中,有业务服务停止而Keepalived服务还在工作的情况,这就会导致用户访问的VIP无法找到对应的服务,那么,如何解决业务宕机就可以将IP漂移到备节点接管提供服务呢?
方法一:可以写守护进程脚本来处理。当Nginx业务出现问题时就停掉本地的Keepalived服务,实现IP漂移到对端接管提供服务。实际工作中部署及开发的示例脚本如下:

[root@lb01 conf]# cd /server/scripts/
[root@lb01 scripts]# vim check_nginx.sh
#!/bin/bash
while true
do
    if [ 'netstat -lntup|grep nginx|wc -l' != 1 ];then
        systemctl stop keepalived
        break
    fi
        sleep 5
done

此脚本的基本思想是若没有80端口存在,就停掉Keepalived服务实现释放本地的VIP。
在后台执行上述脚本并检查:

[root@lb01 scripts]# sh /server/scripts/check_nginx.sh &
[1] 29858
[root@lb01 scripts]# ps -ef|grep check
root      29858  19844  0 16:49 pts/0    00:00:00 sh /server/scripts/check_nginx.sh

确认Nginx以及Keepalived服务是正常的。

[root@lb01 scripts]# lsof -i :80
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   29398  root    6u  IPv4 168351      0t0  TCP www.etiantian.org:http (LISTEN)
nginx   29399 nginx    6u  IPv4 168351      0t0  TCP www.etiantian.org:http (LISTEN)
[root@lb01 scripts]# ps -ef|grep keep|grep -v grep
root      29656      1  0 15:29 ?        00:00:00 /usr/sbin/keepalived -D
root      29657  29656  0 15:29 ?        00:00:00 /usr/sbin/keepalived -D
root      29658  29656  0 15:29 ?        00:00:00 /usr/sbin/keepalived -D

然后模拟Nginx服务停掉,看IP是否发生切换。

[root@lb01 scripts]# nginx -s stop
[root@lb01 scripts]# systemctl status keepalived
---keepalived已停
[root@lb01 scripts]# netstat -lntup|grep nginx

此时,备节点已接管:

[root@lb02 conf]# ip addr|grep 192.168.9.210
    inet 192.168.9.210/24 scope global secondary eth0:3

方法二:可以使用Keepalived的配置文件参数触发写好的监测服务脚本。
首先要开发监测服务脚本,注意这个脚本与上一个脚本的区别。

[root@lb01 scripts]# vim chk_nginx_proxy.sh
#!/bin/bash
if [ 'netstat -lntup|grep nginx|wc -l' != 1 ];then
    systemctl stop keepalived
fi
[root@lb01 scripts]# chmod +x chk_nginx_proxy.sh 
[root@lb01 scripts]# ls -l chk_nginx_proxy.sh 
-rwxr-xr-x 1 root root 94 Apr  3 17:21 chk_nginx_proxy.sh

此时,Keepalived服务的完整配置如下:

[root@lb01 keepalived]# cat keepalived.conf
global_defs {
    router_id lb01
    script_user root    ---指定检查脚本的用户
    enable_script_security
}
vrrp_script chk_nginx_proxy {    ---定义VRRP脚本,检测HTTP端口
    script "/server/scripts/chk_nginx_proxy.sh"    ---执行脚本,当Nginx服务出现问题时,就停掉Keepalived服务
    interval 2    ---间隔2秒
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.9.210/24 dev eth0 label eth0:3
    }
}

下面测试接管结果。

[root@lb01 keepalived]# lsof -i :80
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   31922  root    6u  IPv4 237693      0t0  TCP www.etiantian.org:http (LISTEN)
nginx   31923 nginx    6u  IPv4 237693      0t0  TCP www.etiantian.org:http (LISTEN)
[root@lb01 keepalived]# ps -ef|grep keep
root      31914      1  0 11:40 ?        00:00:00 /usr/sbin/keepalived -D
root      31915  31914  0 11:40 ?        00:00:00 /usr/sbin/keepalived -D
root      31916  31914  0 11:40 ?        00:00:00 /usr/sbin/keepalived -D
root      31945  31806  0 11:40 pts/0    00:00:00 grep --color=auto keep
[root@lb01 keepalived]# ip addr|grep 192.168.9.210
    inet 192.168.9.210/24 scope global secondary eth0:3
[root@lb01 keepalived]# nginx -s stop
[root@lb01 keepalived]# ip addr|grep 192.168.9.210
[root@lb01 keepalived]# ps -ef|grep keep
root      31945  31806  0 11:40 pts/0    00:00:00 grep --color=auto keep

当停掉Nginx的时候,Keepalived 2秒钟内会被自动停掉,IP被释放,由对端接管,这样就实现了即使服务宕机也进行IP漂移、业务切换,如果此时把Nginx和Keepalived同时启动,IP又会被接管回来。
lb01的日志是Keepalived停掉的消息。

4. 解决多组Keepalived服务器在一个局域网内冲突的问题

当在同一个局域网内部署了多组Keepalived服务器而又未使用专门的心跳线通信时,可能会发生高可用接管的严重故障问题。前面已经讲解过Keepalived高可用功能是通过VRRP协议实现的,VRRP协议默认通过IP多播的形式实现高可用服务对之间的通信,如果同一个局域网内存在多组Keepalived服务器对,就会造成IP多播地址冲突问题,导致接管错乱,不同组的Keepalived都会使用默认的224.0.0.18作为多播地址。此时的解决办法是在同组的Keepalived服务器所有的配置文件里指定各自独一无二的多播地址,配置如下:

global_defs {
  router_id LVS_19
  vrrp_mcast_group4 224.0.0.19    ---这个就是指定多播地址的配置
}

提示
1)不同实例的通信认证密码也最好不同,以确保接管正常。
2)另一款高可用软件Hearbeat,如果采用多播方式实现主备通信,同样会有多播地址冲突问题。

5. 配置指定文件接收Keepalived服务日志

默认情况下,Keepalived服务日志会输出到系统日志/var/log/messages,和其他日志信息混合在一起,查看起来很不方便,可以将其调整成由独立的文件记录Keepalived服务日志。操作步骤如下:
1)编辑配置文件/etc/sysconfig/keepalived,将“KEEPALIVED_OPTIONS="-D"”修改为“KEEPALIVED_OPTIONS="-D -d -S 0"”,快速修改方法如下:

[root@lb01 keepalived]# sed -i '14 s#KEEPALIVED_OPTIONS="-D"#KEEPALIVED_OPTIONS="-D -d -S 0"#g' /etc/sysconfig/keepalived 
[root@lb01 keepalived]# sed -n '14p' /etc/sysconfig/keepalived 
KEEPALIVED_OPTIONS="-D -d -S 0"
说明:可以查看/etc/sysconfig/keepalived里注释获得上述参数的说明
--dump-conf    -d    导出备份配置数据
--log-detail    -D    详细日志
--log-facility    -S    设置本地的syslog设备,编号0-7(default=LOG_DAEMON)
-S 0    表示指定为local0设备

2)修改rsyslog的配置文件vi /etc/rsyslog.conf,在结尾处加入如下两行内容:

#keepalived
local0.*                                                /var/log/keepalived.log

上述配置表示来自local0设备的所有日志信息都记录到了/var/log/keepalived.log文件中。
然后在如下信息的第一列结尾加入“;local0.none”,注意有分号。

*.info;mail.none;authpriv.none;cron.none;local0.none /var/log/messages

上述配置表示来自local0设备的所有日志信息不再记录于/var/log/messages里。
3)配置完成后,重启rsyslog服务。

[root@lb01 keepalived]# systemctl restart rsyslog.service

4)测试Keepalived日志记录结果。在重启Keepalived服务后,就会把日志信息输出到rsyslog定义的/var/log/keepalived.log文件中:

[root@lb01 keepalived]# systemctl restart keepalived
[root@lb01 keepalived]# tail /var/log/keepalived.log 
Apr  4 12:15:52 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210
Apr  4 12:15:52 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210
Apr  4 12:15:52 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210
Apr  4 12:15:52 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210
Apr  4 12:15:57 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210
Apr  4 12:15:57 lb01 Keepalived_vrrp[32113]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth0 for 192.168.9.210
Apr  4 12:15:57 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210
Apr  4 12:15:57 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210
Apr  4 12:15:57 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210
Apr  4 12:15:57 lb01 Keepalived_vrrp[32113]: Sending gratuitous ARP on eth0 for 192.168.9.210

如果要求更高,还可以在/var/log/messages上设置对/var/log/keepalived.log进行轮询,以防单个日志文件变得太大。

6. 开发监测Keepalived“裂脑”的脚本

检测思路:在备节点上执行脚本,如果可以ping通主节点并且备节点有VIP就报警,让工作人员检查是否裂脑。
1)在lb02备节点开发脚本并执行。

[root@lb02 scripts]# cat check_split_brain.sh 
#!/bin/bash
lb01_vip=192.168.9.210
lb01_ip=192.168.9.81
while true
do
ping -c 2 -W 3 $lb01_ip &>/dev/null
    if [ $? -eq 0 -a `ip addr|grep "$lb01_vip"|wc -l` -eq 1 ]
        then
            echo "ha is split brain.warning."
else
    echo "ha is ok."
fi
sleep 5
done
[root@lb02 scripts]# sh check_split_brain.sh 
ha is ok.
ha is ok.

正常情况下,主节点活着,VIP 192.168.9.210在主节点,因此不会报警,提示“ha is ok.”。
2)停止Keepalived服务看lb02脚本执行情况。lb01上:

[root@lb01 keepalived]# systemctl stop keepalived
[root@lb01 keepalived]# ip addr|grep 192.168.9.210

在lb02上观察即可,此前脚本已经执行。

[root@lb02 scripts]# sh check_split_brain.sh 
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.

3)关掉lb01服务器,然后再观察lb02脚本的输出。

[root@lb02 scripts]# sh check_split_brain.sh 
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is ok.
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is ok.
ha is ok.

裂脑报警恢复了。
4)可以将此脚本整合到Nagios或Zabbix监控服务里,进行监控报警。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,961评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,444评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,009评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,082评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,101评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,271评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,738评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,395评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,539评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,434评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,481评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,160评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,749评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,816评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,038评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,548评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,140评论 2 341

推荐阅读更多精彩内容