Nginx系列-Nginx高可用(主从、主主模式)

06-01 1144阅读

文章目录

  • Nginx系列-Nginx高可用(主从、主主模式)
    • 1. 引言
    • 2. 高可用架构设计
    • 3. 基础环境准备
    • 4. Nginx安装
    • 5. keepalived安装
    • 4. 配置主备模式
    • 5. 配置主主(双主)模式
    • 6. 注意事项

      Nginx系列-Nginx高可用(主从、主主模式)

      1. 引言

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

      2. 高可用架构设计

      Nginx系列-Nginx高可用(主从、主主模式)

      • KeepAlived是什么?

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

        • Nginx+keepalived 双机主从模式(也叫双机热备):

          即前端使用两台服务器,一台主服务器和一台热备服务器,正常情况下,主服务器绑定一个虚拟IP,提供负载均衡服务,热备服务器处于空闲状态;当主服务器发生故障时,热备服务器接管主服务器的虚拟IP,提供负载均衡服务;但是热备服务器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠。

          • Nginx+keepalived 双机主主模式(也叫双机互备):

            即前端使用两台负载均衡服务器,互为主备,且都处于活动状态,同时各自绑定一个虚拟IP,提供负载均衡服务;当其中一台发生故障时,另一台接管发生故障服务器的虚拟IP(这时由非故障机器一台负担所有的请求)

            3. 基础环境准备

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

            1. 准备两台服务器
            2. 分别安装docker
            3. 分别安装nginx

              ① Nginx两个端口要保持一致

            4. 分别安装keepalive

            4. Nginx安装

            Nginx高可用相关软件下载(包括keepalived镜像)

            • 创建nginx目录
              mkdir -p /home/xmc/nginx1/conf.d /home/xmc/nginx1/html /home/xmc/nginx1/logs
              
              • 临时构建nginx容器(目的是获取配置文件)
                docker run -d --name=nginx1 nginx:latest
                
                • 从临时nginx容器获取配置文件
                  docker cp nginx1:/etc/nginx/nginx.conf /home/xmc/nginx1
                  docker cp nginx1:/etc/nginx/conf.d /home/xmc/nginx1
                  docker cp nginx1:/usr/share/nginx/html /home/xmc/nginx1
                  
                  • 删除临时nginx容器
                    docker stop nginx1
                    docker rm nginx1
                    
                    • 重新构建nginx容器
                      docker run \
                      -d -p 8081:80 \
                      --name nginx1 \
                      --privileged=true \
                      --restart=always \
                      -v /home/xmc/nginx1/nginx.conf:/etc/nginx/nginx.conf \
                      -v /home/xmc/nginx1/logs:/var/log/nginx \
                      -v /home/xmc/nginx1/conf.d:/etc/nginx/conf.d \
                      -v /home/xmc/nginx1/html:/usr/share/nginx/html \
                      nginx:latest
                      

                      5. keepalived安装

                      Nginx高可用相关软件下载(包括keepalived镜像)

                      • 安装目录准备
                        # 进入一下目录,解压的时候会自动创建keepalived文件夹
                        cd /opt/module
                        
                        • 解压
                          tar -zxvf keepalived-2.2.7.tar.gz
                          
                          • 安装
                            ./configure --prefix=/usr/local/keepalived make && make install
                            
                            • 启停
                              # 启动
                              systemctl start keepalived
                              # 状态
                              systemctl status keepalived
                              # 停止
                              systemctl stop keepalived
                              
                              • 设置开机自启动
                                sudo systemctl enable keepalived
                                
                                • 日志查看
                                  Keepalived默认所有的日志都是写入到/var/log/message,
                                  你可以使用命令 tail -f /var/log/messages|grep Keepalived 进行查看
                                  

                                  4. 配置主备模式

                                  • 主机:keepalived的配置
                                    global_defs {
                                        notification_email {
                                            acassen@firewall.loc
                                            failover@firewall.loc
                                            sysadmin@firewall.loc
                                        }
                                        notification_email_from Alexandre.Cassen@firewall.loc
                                        smtp_server 192.168.10.200
                                        smtp_connect_timeout 30
                                        router_id LVS_DEVEL
                                    }
                                    vrrp_script chk_http_port {
                                        script "/etc/keepalived/nginx_check.sh" # 脚本路径
                                        interval 2 #(检测脚本执行的间隔)
                                        weight 2
                                    }
                                    vrrp_instance VI_1 {
                                        state MASTER    # 主机使用: MASTER  备机使用: BACKUP
                                        interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
                                        virtual_router_id 51 # 虚拟路由标识,主、备服务器ID必须一样
                                        priority 100 # 优先级,备份服务上将100改为小于100,可配置成90
                                        advert_int 1 # 主备之间同步检查的时间间隔单位秒
                                        authentication { # 验证类型和密码
                                            auth_type PASS # 验证类型有两种 PASS和HA
                                            auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
                                        }
                                        virtual_ipaddress {
                                            192.168.10.50 # 虚拟IP地址,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
                                        }
                                         track_script {  # 调用上边的脚本
                                            chk_http_port
                                         }
                                    }
                                    
                                    • 备机:keepalived的配置
                                      global_defs {
                                          notification_email {
                                              acassen@firewall.loc
                                              failover@firewall.loc
                                              sysadmin@firewall.loc
                                          }
                                          notification_email_from Alexandre.Cassen@firewall.loc
                                          smtp_server 192.168.10.200
                                          smtp_connect_timeout 30
                                          router_id LVS_DEVEL
                                      }
                                      vrrp_script chk_http_port {
                                          script "/etc/keepalived/nginx_check.sh" # 脚本路径
                                          interval 2 #(检测脚本执行的间隔)
                                          weight 2
                                      }
                                      vrrp_instance VI_1 {
                                          state BACKUP    # 主机使用: MASTER  备机使用: BACKUP
                                          interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
                                          virtual_router_id 51 # 虚拟路由标识,主、备服务器ID必须一样
                                          priority 90 # 优先级,备份服务上将100改为小于100,可配置成90
                                          advert_int 1 # 主备之间同步检查的时间间隔单位秒
                                          authentication { # 验证类型和密码
                                              auth_type PASS # 验证类型有两种 PASS和HA
                                              auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
                                          }
                                          virtual_ipaddress {
                                              192.168.10.50 # 虚拟IP地址,主、备节点必须一致,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
                                          }
                                           track_script {  # 调用上边的脚本
                                              chk_http_port
                                           }
                                      }
                                      
                                      • 检测脚本(主机和备机一致):
                                        vim /etc/keepalived/nginx_check.sh
                                        
                                        #!/bin/bash
                                        # 容器名称
                                        container_name="nginx1"
                                        # 检查容器状态
                                        container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)
                                        # 如果容器不存在
                                        if [ -z "$container_status" ]; then
                                            echo "容器 $container_name 不存在! 关闭 keepalived..."
                                            systemctl stop keepalived
                                            echo "Keepalived 已关闭。"
                                            exit 1
                                        fi
                                        echo "容器 $container_name 当前状态为: $container_status"
                                        # 如果容器未运行,尝试重新启动
                                        if [ "$container_status" != "running" ]; then
                                            echo "容器 $container_name 未运行,尝试重新启动..."
                                            docker start "$container_name"
                                            sleep 5  # 等待 5 秒,确保容器有足够时间启动
                                            # 再次检查容器状态
                                            container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)
                                            if [ "$container_status" != "running" ]; then
                                                echo "容器 $container_name 重启后仍未运行,将关闭 Keepalived。"
                                                systemctl stop keepalived
                                                echo "Keepalived 已关闭。"
                                                exit 1
                                            else
                                                echo "容器 $container_name 已成功启动。"
                                            fi
                                        else
                                            echo "容器 $container_name 已处于运行状态,无需重启。"
                                        fi
                                        

                                        赋予执行权限

                                        chmod +x /etc/keepalived/nginx_check.sh 
                                        

                                        5. 配置主主(双主)模式

                                        • 主机1:keepalived的配置(互为主备配置)
                                          global_defs {
                                              notification_email {
                                                  acassen@firewall.loc
                                                  failover@firewall.loc
                                                  sysadmin@firewall.loc
                                              }
                                              notification_email_from Alexandre.Cassen@firewall.loc
                                              smtp_server 192.168.10.200
                                              smtp_connect_timeout 30
                                              router_id LVS_DEVEL
                                          }
                                          vrrp_script chk_http_port {
                                              script "/etc/keepalived/nginx_check.sh" # 脚本路径
                                              interval 2 #(检测脚本执行的间隔)
                                              weight 2
                                          }
                                          vrrp_instance VI_1 {
                                              state MASTER    # 主机使用: MASTER  备机使用: BACKUP
                                              interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
                                              virtual_router_id 51 # 虚拟路由标识,主、备服务器ID必须一样
                                              priority 100 # 优先级,备份服务上将100改为小于100,可配置成90
                                              advert_int 1 # 主备之间同步检查的时间间隔单位秒
                                              authentication { # 验证类型和密码
                                                  auth_type PASS # 验证类型有两种 PASS和HA
                                                  auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
                                              }
                                              virtual_ipaddress {
                                                  192.168.10.50 # 虚拟IP地址,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
                                              }
                                              track_script {  # 调用上边的脚本
                                                  chk_http_port
                                              }
                                          }
                                          vrrp_instance VI_2 {
                                              state BACKUP   # 主机使用: MASTER  备机使用: BACKUP
                                              interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
                                              virtual_router_id 52 # 虚拟路由标识,主、备服务器ID必须一样
                                              priority 90 # 优先级,备份服务上将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
                                              }
                                          }
                                          
                                          • 主机2:keepalived的配置(互为主备配置)
                                            global_defs {
                                                notification_email {
                                                    acassen@firewall.loc
                                                    failover@firewall.loc
                                                    sysadmin@firewall.loc
                                                }
                                                notification_email_from Alexandre.Cassen@firewall.loc
                                                smtp_server 192.168.10.200
                                                smtp_connect_timeout 30
                                                router_id LVS_DEVEL
                                            }
                                            vrrp_script chk_http_port {
                                                script "/etc/keepalived/nginx_check.sh" # 脚本路径
                                                interval 2 #(检测脚本执行的间隔)
                                                weight 2
                                            }
                                            vrrp_instance VI_1 {
                                                state BACKUP    # 主机使用: MASTER  备机使用: BACKUP
                                                interface ens33 #实例绑定的网卡, 用ip a命令查看网卡编号
                                                virtual_router_id 51 # 虚拟路由标识,主、备服务器ID必须一样
                                                priority 90 # 优先级,备份服务上将100改为小于100,可配置成90
                                                advert_int 1 # 主备之间同步检查的时间间隔单位秒
                                                authentication { # 验证类型和密码
                                                    auth_type PASS # 验证类型有两种 PASS和HA
                                                    auth_pass 1111 # 验证密码,在一个实例中主备密码保持一样
                                                }
                                                virtual_ipaddress {
                                                    192.168.10.50 # 虚拟IP地址,主、备节点必须一致,可以有多个,每行一个,不需要指定端口,端口使用的是Nginx容器的端口
                                                }
                                                 track_script {  # 调用上边的脚本
                                                    chk_http_port
                                                 }
                                            }
                                            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
                                                 }
                                            }
                                            

                                            检测脚本(主机和备机一致):

                                            #!/bin/bash
                                            # 容器名称
                                            container_name="nginx1"
                                            # 检查容器状态
                                            container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)
                                            # 如果容器不存在
                                            if [ -z "$container_status" ]; then
                                                echo "容器 $container_name 不存在! 关闭 keepalived..."
                                                systemctl stop keepalived
                                                echo "Keepalived 已关闭。"
                                                exit 1
                                            fi
                                            echo "容器 $container_name 当前状态为: $container_status"
                                            # 如果容器未运行,尝试重新启动
                                            if [ "$container_status" != "running" ]; then
                                                echo "容器 $container_name 未运行,尝试重新启动..."
                                                docker start "$container_name"
                                                sleep 5  # 等待 5 秒,确保容器有足够时间启动
                                                # 再次检查容器状态
                                                container_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)
                                                if [ "$container_status" != "running" ]; then
                                                    echo "容器 $container_name 重启后仍未运行,将关闭 Keepalived。"
                                                    systemctl stop keepalived
                                                    echo "Keepalived 已关闭。"
                                                    exit 1
                                                else
                                                    echo "容器 $container_name 已成功启动。"
                                                fi
                                            else
                                                echo "容器 $container_name 已处于运行状态,无需重启。"
                                            fi
                                            
                                            • 双主模式keepalived的主要区别
                                              • 互为主备,两个实例,两个虚拟ip
                                              • 每个实例都拥有自己独立的虚拟路由id(virtual_router_id这个属性)

                                                6. 注意事项

                                                没有出现虚拟ip,如果出现主备都抢用了虚拟ip的情况,那很可能是firewall的原因,keepalived 是基于vrrp做到虚拟ip漂移的,这里不开启的话,主备均会认为对方挂掉了,会造成主备都能获取到虚拟ip(vip)

                                                防火墙开启vrrp

                                                firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --permanent
                                                

                                                重新载入配置

                                                firewall-cmd –reload
                                                
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码