keepalived双机热备方案实现Nginx高可用

问题描述

只用一台Nginx做反向代理,如果这台Nginx出现故障(比如宕机),则服务不可用。

以下给出keepalived双机热备方案实现Nginx高可用的方法。先介绍几个概念:

高可用

高可用(High Availability)是指系统或服务能够在面对硬件故障、软件崩溃、网络问题等各种故障情况下,仍然保持正常运行或快速恢复的能力,以减少服务中断时间,确保业务连续性和数据完整性。

双机热备

指一台服务器提供服务,另一台作为备用。当一台服务器不可用时另一台就自动顶上去。

keepalived

一个开源的高可用解决方案,通过VRRP协议实现故障转移,避免单点故障导致的服务中断。

keepalived双机热备方案实现Nginx高可用的步骤

准备两台Nginx环境

安装两台Linux虚拟机,每台虚拟机安装Nginx(如何安装Nginx)

  • 192.168.52.200 (Nginx1)
  • 192.168.52.201 (Nginx2)

修改Nginx.conf, 给Nginx1,Nginx2分别添加一个简单的主页

Nginx1

    server {
        listen 80;
        server_name localhost;
        location / {
            default_type text/html;
            return 200 '<h1>welcome to Nginx1</h1>';
        }
		# ...
    }

Nginx2

    server {
        listen 80;
        server_name localhost;
        location / {
            default_type text/html;
            return 200 '<h1>welcome to Nginx2</h1>';
        }
		# ...
    }

启动Nginx

systemctl start nginx

安装并配置Keepalived

Nginx1,Nginx2都安装keepalived, 如下:

yum -y install keepalived

修改Nginx1的keepalived主配置文件/etc/keepalived/keepalived.conf

vrrp_script chk_http_port {
    script "/usr/local/bin/keepalived_check_nginx.sh" #心跳检测脚本
    interval 2 #检测脚本执行的间隔,单位是秒)
    weight 2   #权重
}

vrrp_instance VI_1 {
    state BACKUP            # 指定keepalived的角色,MASTER为主,BACKUP为备
    interface ens33         # 指定vrrp通讯的网卡, ifconfig查下你的网卡名
    virtual_router_id 66    # 虚拟路由编号,主从要一致
    priority 100            # 优先级,数值越大,获取处理请求的优先级越高
    advert_int 1            # 检查间隔,默认为1s(vrrp组播周期秒数)
    nopreempt               # 设置为不抢占。这个配置只能在BACKUP主机上面设置
    #授权访问
    authentication {
        auth_type PASS      #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码
        auth_pass peter
    }
    track_script {
        chk_http_port       # 调用检测脚本
    }
    virtual_ipaddress {
        192.168.52.199      # 设置VIP
    }
}

Nginx2直接复用Nginx1的keepalived.conf即可

说明:

  • virtual_router_id指虚拟路由编号,主从要一致。
  • 如果需要主节点恢复后,VIP再转移到主节点,需要设置为state MASTER;
  • 如不需要抢占,可以设置为state BACKUP, 同时设置nopreempt; 对于多个从节点场景,发生故障转移后,根据priority选取MASTER节点。

编写检测脚本

编写keepalived_check_nginx.sh,判断Nginx是否启动。如果Nginx没有启动并且重启也失败,就停止keepalived服务,进行VIP转移

cmd=`ps -C nginx --no-header |wc -l`
if [ $cmd -eq 0 ];then
    systemctl start nginx
    if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
        killall keepalived
    fi
fi

把脚本分别传到Nginx1和Nginx2的/usr/local/bin路径

配置防火墙

VRRP使用组播地址, 必须配置相应firewall规则或关闭firewall,否则会出现脑裂。

添加规则

firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload

或者直接关闭firewall

systemctl disable firewalld --now

启动keepalived,开始测试

测试Nginx1, Nginx2可以正常访问
curl 192.168.52.200
Welcome to Nginx1
curl 192.168.52.201
Welcome to Nginx2
启动Nginx1和Nginx2的keepalived
systemctl start keepalived

比如,我先启动Nginx1的keepalived,再启动Nginx2,那么在Nginx1上可以看到VIP(192.168.52.199), Nginx2查不到VIP

ip a
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:36:d4:a9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.52.200/24 brd 192.168.52.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.52.199/32 scope global ens33
       valid_lft forever preferred_lft forever
通过VIP访问, 可以返回Nginx1的主页
curl 192.168.52.199
welcome to Nginx1
在Nginx1构造故障, 再通过VIP可以访问Nginx2的主页
# 先构造Nginx1故障
curl 192.168.52.199
welcome to Nginx2

构造故障方法,可以是先stop nginx,再mv Nginx主程序

再恢复Nginx1(重启Nginx和keepalived),访问VIP,仍返回Nginx2
curl 192.168.52.199
welcome to Nginx2

这是符合预期的,因为我们在配置文件里设置了BACKUP和nopreempt

最后构造Nginx2故障,访问VIP,可以返回Nginx1的主页
curl 192.168.52.199
welcome to Nginx1

keepalived故障转移原理概述

  • 基于VRRP(Virtual Router Redundancy Protocol)协议,通过在多个服务器之间共享一个虚拟IP地址来实现。
  • 监控到主服务器(Master)出现故障时,备份服务器(Backup)会检测到并自动接管虚拟IP,继续提供服务。
  • 这个过程对客户端是透明的,确保了服务的连续性和高可用性。

参考

【1】nginx+keepalived高可用配置笔记

【2】https://docs.nginx.com/nginx/admin-guide/high-availability/ha-keepalived/

相关推荐
ross1 小时前
nginx 配置lua执行shell脚本
nginx·lua
oushaojun22 小时前
ubuntu中使用ffmpeg和nginx推http hls视频流
nginx·ubuntu·ffmpeg·hls
周雨濛2 小时前
通过shell脚本分析部署nginx网络服务
linux·服务器·nginx
yuguo.im18 小时前
Nginx 架构与设计
运维·nginx·架构
vvw&21 小时前
使用 Nginx 在 Ubuntu 22.04 上安装 LibreNMS 开源网络监控系统
linux·运维·服务器·nginx·ubuntu·github·librenms
OkeyProxy1 天前
Nginx正向代理處理HTTPS請求詳解
nginx·https·ip地址·代理服务器·海外ip代理
2201_761199041 天前
nginx动静分离和rewrite重写和https和keepalived
运维·nginx·https
苹果醋31 天前
前端面试之九阴真经
java·运维·spring boot·mysql·nginx
YiSLWLL2 天前
Django+Nginx+uwsgi网站使用Channels+redis+daphne实现简单的多人在线聊天及消息存储功能
服务器·数据库·redis·python·nginx·django