文章目录

展开

nginx负载均衡高可用

Keepalived概述

Keepalived是一个高可用软件,可以和任何应用配合使用

什么是高可用

一般是指2台机器启动着完全相同的业务系统,当有一台机器down机了,另外一台服务器就能快速的接管,对于访问的用户是无感知的。

高可用软件

  • 硬件
    • F5
  • 软件
    • keepalived
    • heartbeat
  • MySQL
    • MGR
    • MHA
  • Redis
    • Redis-Cluster
    • Sentinel

keepalived实现原理

keepalived底层协议:VRRP(虚拟路由冗余协议)

image-20231003115521350

image-20231003115534165

keepalived核心概念

1.通过选举投票,决定谁是主节点谁是备节点(选举)(一个节点就是一台服务器)

2.如果Master故障,Backup自动接管,那么Master恢复后会夺权吗(抢占试、非抢占式)

3.两台服务器都认为自己是master,那么会出现一个故障(脑裂)

keepalived安装配置

主机名 WanIP LanIP 角色 应用
lb01 10.0.0.5 172.16.1.5 Master keepalived主节点 keepalived
lb02 10.0.0.6 172.16.1.6 Master keepalived备节点 keepalived

部署keepalived(抢占式)

# 1.安装keepalived
[root@lb01 ~]# yum install -y keepalived
[root@lb02 ~]# yum install -y keepalived

# 2.查找keepalived配置文件
[root@lb01 ~]# rpm -ql keepalived
/etc/keepalived/keepalived.conf

# 3.修改Master配置文件
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
global_defs {                   #全局配置
    router_id lb01              #标识身份->名称
}

vrrp_instance VI_1 {
    state  MASTER               #标识角色状态
    interface eth0              #网卡绑定接口
    virtual_router_id 50        #虚拟路由id
    priority 150                #优先级 数字越大 优先级越高
    advert_int 1                #监测间隔时间
    authentication {            #认证
        auth_type PASS          #认证方式
        auth_pass 666           #认证密码
    }
    virtual_ipaddress {
        10.0.0.3                #虚拟的VIP地址
    }
}

# 4.修改Backup配置文件
[root@lb02 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
    router_id lb02
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 666
    }
    virtual_ipaddress {
        10.0.0.3
    }
}

# 5.启动master上的keepalived
[root@lb01 ~]# systemctl start keepalived
[root@lb01 ~]# systemctl enable keepalived
# 6.启动backup上的keepalived
[root@lb02 ~]# systemctl start keepalived
[root@lb02 ~]# systemctl enable keepalived

## 注意:此时是抢占式 只要停止掉Keepalived,VIP会漂移到另外一个节点 权重高的节点修复后会漂移回去
## 可以 ip a 查看10.0.0.3虚拟ip绑定的是哪个节点
Keepalived配置区别 Master节点配置 Backup节点配置
router_id(节点名称) lb01 lb02
state(角色) MASTER BACKUP
priority(权重) 150 100

非抢占式配置

## 配置需求
1、两个节点的state都必须配置为BACKUP
2、两个节点都必须加上配置 nopreempt
3、其中一个节点的优先级必须要高于另外一个节点的优先级。

## master节点配置
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
    router_id lb01
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 50
    priority 150
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 666
    }
    virtual_ipaddress {
        10.0.0.3
    }
}

## BACKUP节点配置
[root@lb02 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
    router_id lb02
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 50
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 666
    }
    virtual_ipaddress {
        10.0.0.3
    }
}

## 注意:此时是非抢占式 只要停止掉Keepalived,VIP会漂移到另外一个节点 权重高的节点修复后也不会漂移回去
## 可以 ip a 查看10.0.0.3虚拟ip绑定的是哪个节点

脑裂的原因

1、服务器网线松动等网络故障

2、服务器硬件故障发生损坏现象而崩溃

3、主备节点都开启

# 解决脑裂故障脚本
[root@lb02 ~]# vim check_split_brain.sh
#!/bin/sh
vip=10.0.0.3
lb01_ip=10.0.0.5
while true;do
    ping -c 2 $lb01_ip &>/dev/null  #测试连接10.0.0.5是否通信
    if [ $? -eq 0 -a `ip add|grep "$vip"|wc -l` -eq 1 ];then #检查ip add是否有vip
        echo "ha is split brain.warning."  #如果有的话就停止vip
    else
        echo "ha is ok"   #这里两个echo在生产环境中换成停止的指令就行了 
    fi
sleep 5
done

keepalived结合nginx做高可用

当前架构图

image-20231003120802282

环境准备

主机名 WanIP LanIP 角色 应用
lb01 10.0.0.5 172.16.1.5 Master keepalived主节点 keepalived,nginx
lb02 10.0.0.6 172.16.1.6 Master keepalived备节点 keepalived,nginx
web01 10.0.0.7 172.16.1.7 web网站 nginx、php
web02 10.0.0.8 172.16.1.8 web网站 nginx、php

关联nginx

# 写检测nginx健康状态的脚本
[root@lb01 ~]# vim check_web.sh
#!/bin/sh
nginx_count=$(ps -ef|grep [n]ginx|wc -l)

# 判断Nginx是否存活,如果不存活则漂移vip
if [ $nginx_count -eq 0 ];then
    systemctl stop keepalived
fi

###优化后脚本
[root@lb01 ~]# vim check_web.sh
#!/bin/sh
nginx_count=$(ps -ef|grep [n]ginx|wc -l)

#1.判断Nginx是否存活,如果不存活则尝试启动Nginx
if [ $nginx_count -eq 0 ];then
    systemctl start nginx
    sleep 3
    #2.等待3秒后再次获取一次Nginx状态
    nginx_count=$(ps -ef|grep [n]ginx|wc -l)
    #3.再次进行判断, 如Nginx还不存活则停止Keepalived,让地址进行漂移,并退出脚本
    if [ $nginx_count -eq 0 ];then
        systemctl stop keepalived
    fi
fi

先配置两台负载均衡

## lb01
[root@lb01 ~]# vim /etc/nginx/conf.d/keepalived.conf 
upstream www.test.com {
        server 172.16.1.7;
        server 172.16.1.8;
}
server {
        listen 80;
        server_name www.test.com;
        rewrite (.*) https://www.test.com$1 redirect;
}

server {
        listen 443 ssl;
        server_name www.test.com;
        ssl_certificate ssl/server.crt;
        ssl_certificate_key ssl/server.key;

        location /{
                proxy_pass http://www.test.com;
                include proxy_params;
        }
}

## lb02
[root@lb02 ~]# vim /etc/nginx/conf.d/keepalived.conf 
upstream www.test.com {
        server 172.16.1.7;
        server 172.16.1.8;
}
server {
        listen 80;
        server_name www.test.com;
        rewrite (.*) https://www.test.com$1 redirect;
}

server {
        listen 443 ssl;
        server_name www.test.com;
        ssl_certificate ssl/server.crt;
        ssl_certificate_key ssl/server.key;

        location /{
                proxy_pass http://www.test.com;
                include proxy_params;
        }
}

[root@lb02 ~]# mkdir /etc/nginx/ssl

[root@lb01 ~]# scp /etc/nginx/ssl/* 172.16.1.6:/etc/nginx/ssl

keepalived关联nginx

# 修改keepalived配置文件
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
global_defs {                   #全局配置
    router_id lb01              #标识身份->名称
}

vrrp_script check_web {         #指定项目名称
    script "/root/check_web.sh" #指定你脚本的位置
    interval 5                  #每5秒执行一次脚本
}

vrrp_instance VI_1 {
    state  MASTER               #标识角色状态
    interface eth0              #网卡绑定接口
    virtual_router_id 50        #虚拟路由id
    priority 150                #优先级 数字越大 优先级越高
    advert_int 1                #监测间隔时间
    authentication {            #认证
        auth_type PASS          #认证方式
        auth_pass 666           #认证密码
    }
    virtual_ipaddress {
        10.0.0.3                #虚拟的VIP地址
    }
    track_script {
        check_web               #执行指定你上面的项目名 
    }
}

# 给脚本加执行权限
[root@lb01 ~]# chmod +x /root/check_web.sh

# 域名解析在vip上
10.0.0.3 www.test.com