• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    Nginx高可用(主从、主主模式)的项目实践

    发布者: 琛瑞6678 | 发布时间: 2025-8-16 16:05| 查看数: 77| 评论数: 0|帖子模式

    1. 引言
    1. 在单机部署的Nginx环境中,一旦Nginx服务器出现故障,整个系统服务将受到影响,导致服务中断。为了解决这个问题,我们需要引入Nginx的高可用性(HA)架构。本文将详细探讨Nginx高可用性的两种主要解决方案:主从架构和主主架构。
    复制代码
    2. 高可用架构设计



    • KeepAlived是什么?
    1. KeepAlived是一款基于VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)的开源软件,主要用于解决网络服务的单点故障问题,特别是在集群环境中提供VIP(Virtual IP,虚拟IP地址)共享和故障切换功能
    复制代码

    • Nginx+keepalived 双机主从模式(也叫双机热备):
    1. 即前端使用两台服务器,一台主服务器和一台热备服务器,正常情况下,主服务器绑定一个虚拟IP,提供负载均衡服务,热备服务器处于空闲状态;当主服务器发生故障时,热备服务器接管主服务器的虚拟IP,提供负载均衡服务;但是热备服务器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠。
    复制代码

    • Nginx+keepalived 双机主主模式(也叫双机互备):
    1. 即前端使用两台负载均衡服务器,互为主备,且都处于活动状态,同时各自绑定一个虚拟IP,提供负载均衡服务;当其中一台发生故障时,另一台接管发生故障服务器的虚拟IP(这时由非故障机器一台负担所有的请求)
    复制代码
    3. 基础环境准备

    本片采用 nginx容器部署+keepalived宿主机部署、nginx容器部署+keepalived容器部署两种方案

    • 准备两台服务器
    • 分别安装docker
    • 分别安装nginx
      ① Nginx两个端口要保持一致
    • 分别安装keepalive

    4. Nginx安装


    • 创建nginx目录
    1. mkdir -p /home/xmc/nginx1/conf.d /home/xmc/nginx1/html /home/xmc/nginx1/logs
    复制代码

    • 临时构建nginx容器(目的是获取配置文件)
    1. docker run -d --name=nginx1 nginx:latest
    复制代码

    • 从临时nginx容器获取配置文件
    1. docker cp nginx1:/etc/nginx/nginx.conf /home/xmc/nginx1
    2. docker cp nginx1:/etc/nginx/conf.d /home/xmc/nginx1
    3. docker cp nginx1:/usr/share/nginx/html /home/xmc/nginx1
    复制代码

    • 删除临时nginx容器
    1. docker stop nginx1
    2. docker rm nginx1
    复制代码

    • 重新构建nginx容器
    1. docker run \
    2. -d -p 8081:80 \
    3. --name nginx1 \
    4. --privileged=true \
    5. --restart=always \
    6. -v /home/xmc/nginx1/nginx.conf:/etc/nginx/nginx.conf \
    7. -v /home/xmc/nginx1/logs:/var/log/nginx \
    8. -v /home/xmc/nginx1/conf.d:/etc/nginx/conf.d \
    9. -v /home/xmc/nginx1/html:/usr/share/nginx/html \
    10. nginx:latest
    复制代码
    5. keepalived安装

    keepalived安装包下载地址

    • 安装目录准备
    1. # 进入一下目录,解压的时候会自动创建keepalived文件夹
    2. cd /opt/module
    复制代码

    • 解压
    1. tar -zxvf keepalived-2.2.7.tar.gz
    复制代码

    • 安装
    1. ./configure --prefix=/usr/local/keepalived make && make install
    复制代码

    • 启停
    1. # 启动
    2. systemctl start keepalived
    3. # 状态
    4. systemctl status keepalived
    5. # 停止
    6. systemctl stop keepalived
    复制代码

    • 设置开机自启动
    1. sudo systemctl enable keepalived
    复制代码

    • 日志查看
    1. Keepalived默认所有的日志都是写入到/var/log/message,
    2. 你可以使用命令 tail -f /var/log/messages|grep Keepalived 进行查看
    复制代码
    4. 配置主备模式


    • 主机:keepalived的配置
    1. global_defs {
    2.     notification_email {
    3.         acassen@firewall.loc
    4.         failover@firewall.loc
    5.         sysadmin@firewall.loc
    6.     }
    7.     notification_email_from Alexandre.Cassen@firewall.loc
    8.     smtp_server 192.168.10.200
    9.     smtp_connect_timeout 30
    10.     router_id LVS_DEVEL
    11. }
    12. vrrp_script chk_http_port {
    13.     script "/etc/keepalived/nginx_check.sh" # 脚本路径
    14.     interval 2 #(检测脚本执行的间隔)
    15.     weight 2
    16. }
    17. vrrp_instance VI_1 {
    18.     state MASTER    # 主机使用: MASTER  备机使用: BACKUP
    19.     interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
    20.     virtual_router_id 51 # 虚拟路由标识,主、备服务器ID必须一样
    21.     priority 100 # 优先级,备份服务上将100改为小于100,可配置成90
    22.     advert_int 1 # 主备之间同步检查的时间间隔单位秒
    23.     authentication { # 验证类型和密码
    24.         auth_type PASS # 验证类型有两种 PASS和HA
    25.         auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
    26.     }
    27.     virtual_ipaddress {
    28.         192.168.10.50 # 虚拟IP地址,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
    29.     }
    30.      track_script {  # 调用上边的脚本
    31.         chk_http_port
    32.      }
    33. }
    复制代码

    • 备机:keepalived的配置
    1. global_defs {
    2.     notification_email {
    3.         acassen@firewall.loc
    4.         failover@firewall.loc
    5.         sysadmin@firewall.loc
    6.     }
    7.     notification_email_from Alexandre.Cassen@firewall.loc
    8.     smtp_server 192.168.10.200
    9.     smtp_connect_timeout 30
    10.     router_id LVS_DEVEL
    11. }
    12. vrrp_script chk_http_port {
    13.     script "/etc/keepalived/nginx_check.sh" # 脚本路径
    14.     interval 2 #(检测脚本执行的间隔)
    15.     weight 2
    16. }
    17. vrrp_instance VI_1 {
    18.     state BACKUP    # 主机使用: MASTER  备机使用: BACKUP
    19.     interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
    20.     virtual_router_id 51 # 虚拟路由标识,主、备服务器ID必须一样
    21.     priority 90 # 优先级,备份服务上将100改为小于100,可配置成90
    22.     advert_int 1 # 主备之间同步检查的时间间隔单位秒
    23.     authentication { # 验证类型和密码
    24.         auth_type PASS # 验证类型有两种 PASS和HA
    25.         auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
    26.     }
    27.     virtual_ipaddress {
    28.         192.168.10.50 # 虚拟IP地址,主、备节点必须一致,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
    29.     }
    30.      track_script {  # 调用上边的脚本
    31.         chk_http_port
    32.      }
    33. }
    复制代码

    • 检测脚本(主机和备机一致):
    1. vim /etc/keepalived/nginx_check.sh
    复制代码
    1. #!/bin/bash

    2. # 容器名称
    3. container_name="nginx1"

    4. # 检查容器状态
    5. container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)

    6. # 如果容器不存在
    7. if [ -z "$container_status" ]; then
    8.     echo "容器 $container_name 不存在! 关闭 keepalived..."
    9.     systemctl stop keepalived
    10.     echo "Keepalived 已关闭。"
    11.     exit 1
    12. fi

    13. echo "容器 $container_name 当前状态为: $container_status"

    14. # 如果容器未运行,尝试重新启动
    15. if [ "$container_status" != "running" ]; then
    16.     echo "容器 $container_name 未运行,尝试重新启动..."
    17.     docker start "$container_name"
    18.     sleep 5  # 等待 5 秒,确保容器有足够时间启动

    19.     # 再次检查容器状态
    20.     container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)

    21.     if [ "$container_status" != "running" ]; then
    22.         echo "容器 $container_name 重启后仍未运行,将关闭 Keepalived。"
    23.         systemctl stop keepalived
    24.         echo "Keepalived 已关闭。"
    25.         exit 1
    26.     else
    27.         echo "容器 $container_name 已成功启动。"
    28.     fi
    29. else
    30.     echo "容器 $container_name 已处于运行状态,无需重启。"
    31. fi
    复制代码
    赋予执行权限
    1. chmod +x /etc/keepalived/nginx_check.sh
    复制代码
    5. 配置主主(双主)模式


    • 主机1:keepalived的配置(互为主备配置)
    1. global_defs {
    2.     notification_email {
    3.         acassen@firewall.loc
    4.         failover@firewall.loc
    5.         sysadmin@firewall.loc
    6.     }
    7.     notification_email_from Alexandre.Cassen@firewall.loc
    8.     smtp_server 192.168.10.200
    9.     smtp_connect_timeout 30
    10.     router_id LVS_DEVEL
    11. }
    12. vrrp_script chk_http_port {
    13.     script "/etc/keepalived/nginx_check.sh" # 脚本路径
    14.     interval 2 #(检测脚本执行的间隔)
    15.     weight 2
    16. }
    17. vrrp_instance VI_1 {
    18.     state MASTER    # 主机使用: MASTER  备机使用: BACKUP
    19.     interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
    20.     virtual_router_id 51 # 虚拟路由标识,主、备服务器ID必须一样
    21.     priority 100 # 优先级,备份服务上将100改为小于100,可配置成90
    22.     advert_int 1 # 主备之间同步检查的时间间隔单位秒
    23.     authentication { # 验证类型和密码
    24.         auth_type PASS # 验证类型有两种 PASS和HA
    25.         auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
    26.     }
    27.     virtual_ipaddress {
    28.         192.168.10.50 # 虚拟IP地址,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
    29.     }
    30.     track_script {  # 调用上边的脚本
    31.         chk_http_port
    32.     }
    33. }
    34. vrrp_instance VI_2 {
    35.     state BACKUP   # 主机使用: MASTER  备机使用: BACKUP
    36.     interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
    37.     virtual_router_id 52 # 虚拟路由标识,主、备服务器ID必须一样
    38.     priority 90 # 优先级,备份服务上将100改为小于100,可配置成90
    39.     advert_int 1 # 主备之间同步检查的时间间隔单位秒
    40.     authentication { # 验证类型和密码
    41.         auth_type PASS # 验证类型有两种 PASS和HA
    42.         auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
    43.     }
    44.     virtual_ipaddress {
    45.         192.168.10.51 # 虚拟IP地址,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
    46.     }
    47.     track_script {  # 调用上边的脚本
    48.         chk_http_port
    49.     }
    50. }
    复制代码

    • 主机2:keepalived的配置(互为主备配置)
    1. global_defs {
    2.     notification_email {
    3.         acassen@firewall.loc
    4.         failover@firewall.loc
    5.         sysadmin@firewall.loc
    6.     }
    7.     notification_email_from Alexandre.Cassen@firewall.loc
    8.     smtp_server 192.168.10.200
    9.     smtp_connect_timeout 30
    10.     router_id LVS_DEVEL
    11. }
    12. vrrp_script chk_http_port {
    13.     script "/etc/keepalived/nginx_check.sh" # 脚本路径
    14.     interval 2 #(检测脚本执行的间隔)
    15.     weight 2
    16. }
    17. vrrp_instance VI_1 {
    18.     state BACKUP    # 主机使用: MASTER  备机使用: BACKUP
    19.     interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
    20.     virtual_router_id 51 # 虚拟路由标识,主、备服务器ID必须一样
    21.     priority 90 # 优先级,备份服务上将100改为小于100,可配置成90
    22.     advert_int 1 # 主备之间同步检查的时间间隔单位秒
    23.     authentication { # 验证类型和密码
    24.         auth_type PASS # 验证类型有两种 PASS和HA
    25.         auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
    26.     }
    27.     virtual_ipaddress {
    28.         192.168.10.50 # 虚拟IP地址,主、备节点必须一致,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
    29.     }
    30.      track_script {  # 调用上边的脚本
    31.         chk_http_port
    32.      }
    33. }vrrp_instance VI_2 {    state MASTER    # 主机使用: MASTER  备机使用: BACKUP    interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号    virtual_router_id 52 # 虚拟路由标识,主、备服务器ID必须一样    priority 100 # 优先级,备份服务上将100改为小于100,可配置成90    advert_int 1 # 主备之间同步检查的时间间隔单位秒    authentication { # 验证类型和密码        auth_type PASS # 验证类型有两种 PASS和HA        auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样    }    virtual_ipaddress {        192.168.10.51 # 虚拟IP地址,主、备节点必须一致,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口    }     track_script {  # 调用上边的脚本        chk_http_port     }}
    复制代码
    检测脚本(主机和备机一致):
    1. #!/bin/bash

    2. # 容器名称
    3. container_name="nginx1"

    4. # 检查容器状态
    5. container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)

    6. # 如果容器不存在
    7. if [ -z "$container_status" ]; then
    8.     echo "容器 $container_name 不存在! 关闭 keepalived..."
    9.     systemctl stop keepalived
    10.     echo "Keepalived 已关闭。"
    11.     exit 1
    12. fi

    13. echo "容器 $container_name 当前状态为: $container_status"

    14. # 如果容器未运行,尝试重新启动
    15. if [ "$container_status" != "running" ]; then
    16.     echo "容器 $container_name 未运行,尝试重新启动..."
    17.     docker start "$container_name"
    18.     sleep 5  # 等待 5 秒,确保容器有足够时间启动

    19.     # 再次检查容器状态
    20.     container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)

    21.     if [ "$container_status" != "running" ]; then
    22.         echo "容器 $container_name 重启后仍未运行,将关闭 Keepalived。"
    23.         systemctl stop keepalived
    24.         echo "Keepalived 已关闭。"
    25.         exit 1
    26.     else
    27.         echo "容器 $container_name 已成功启动。"
    28.     fi
    29. else
    30.     echo "容器 $container_name 已处于运行状态,无需重启。"
    31. fi
    复制代码

    • 双主模式keepalived的主要区别

      • 互为主备,两个实例,两个虚拟ip
      • 每个实例都拥有自己独立的虚拟路由id(virtual_router_id这个属性)


    6. 注意事项
    1. 没有出现虚拟ip,如果出现主备都抢用了虚拟ip的情况,那很可能是firewall的原因,keepalived 是基于vrrp做到虚拟ip漂移的,这里不开启的话,主备均会认为对方挂掉了,会造成主备都能获取到虚拟ip(vip)
    复制代码
    防火墙开启vrrp
    1. firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --permanent
    复制代码
    重新载入配置
    1. firewall-cmd –reload
    复制代码
    到此这篇关于Nginx高可用(主从、主主模式)的项目实践的文章就介绍到这了,更多相关Nginx高可用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:互联网
    免责声明:如果侵犯了您的权益,请联系站长(1277306191@qq.com),我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    浏览过的版块

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表