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/

相关推荐
Knight_AL2 小时前
Docker 中的端口映射原理:为什么 Nginx 要 `listen 80`,而不是“随便写端口”
nginx·docker·容器
虹梦未来3 小时前
【运维心得】Ubuntu2404编译nginx隐藏Server信息
运维·服务器·nginx
tgethe7 小时前
Nginx笔记
运维·笔记·nginx
invicinble8 小时前
对于nginx(一,认识nginx)
运维·nginx
徒手千行代码无bug8 小时前
Nginx upstream 负载均衡 404,单节点转发正常的根因与解决
运维·nginx·负载均衡
irisart9 小时前
第二章【NGINX 开源功能】—— 七层反向代理(下)
运维·nginx
xixiyuguang9 小时前
nginx tar离线安装 ubuntu22.04
运维·nginx
丁丁丁梦涛9 小时前
nginx解决域名代理到IP+端口的平台静态资源和接口地址问题
运维·tcp/ip·nginx
苹果醋310 小时前
24.记录Vue项目iview组件日期获取时间少一天
java·运维·spring boot·mysql·nginx
丁丁丁梦涛10 小时前
nginx在多层服务器代理接口地址的应用
运维·服务器·nginx