keepalived + nginx 实现高可用

只谈情不闲聊 提交于 2021-02-13 06:49:01

原理

nginx 可以实现负载均衡,但 nginx 自身存在单点故障的问题,这时候最先想到的就是 keepalived,可以解决单点故障的问题

由于没有使用 lvs,所以这里 nginx 之间不存在负载均衡

同时,如果 keepalived 的 master 节点 nginx 服务宕了以后,如果 keepalived 还在运行,则用户就访问不到 nginx 服务了,所以需要添加监控脚本,当 nginx 宕机时,杀死本机的 keepalived 服务

这样,keepalived 的 master 就会切换,同时用户访问的 nginx 服务也会切换到原来的 backup 节点

测试节点

  RIP VIP
MASTER 192.168.132.136 192.168.132.200
SLAVE 192.168.132.140 192.168.132.200

配置nginx

安装 nginx 不是重点,这里就是用 yum 简单安装
yum -y install nginx
systemctl start nginx

 

配置keepalived

安装 keepalived 使用 yum 安装即可
keepalived 配置如下:
global_defs {
   notification_email {
     chen@test.com
   }
   notification_email_from chen@test.com
   smtp_server smtp.exmail.qq.com
   smtp_connect_timeout 30
   router_id my-slave
}
 
vrrp_script chk_nginx {
    script "/etc/keepalived/nginx_check.sh"
    interval 5
}
 
vrrp_instance my_nginx {
    state MASTER            # BACKUP 节点这里配置成 BACKUP
    interface ens37
    virtual_router_id 51
    priority 200            # BACKUP 节点配置要比该值小
    advert_int 1
    
    # vrrp_script定义的chk_nginx需要放到vrrp_instance里,用track_script指定,才能执行
    track_script {
        chk_nginx
    }
    
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.132.200/24 dev ens37 label ens37:200
    }
}

 

以上配置中,重点在脚本 /etc/keepalived/nginx_check.sh
该脚本会被每 5s 执行一次,用来检测 nginx 是否存活,如果不存活,则尝试重启 nginx,启动失败的话,会将本机的 keepalived 服务也杀死,保证切换主节点,不影响 nginx 访问
脚本 /etc/keepalived/nginx_check.sh 内容如下:
#!/bin/bash
 
# 注意,整个脚本的执行时间必须小于keepalived中定义的时间间隔,即interval定义的时间,否则下次执行脚本时,会杀死上次正在执行的脚本
systemctl status nginx &> /dev/null
# 检查nginx状态,nginx正常运行,$?为0,否则为非零数
if [ $? -ne 0 ];then
    systemctl start nginx
 
    # 启动nginx后等待2s,保证nginx已经正常启动运行,如果nginx还未正常运行,则关闭keepalived服务,使用备用keepalived
    sleep 2
    systemctl status nginx &> /dev/null
 
    if [ $? -ne 0 ];then
        systemctl stop keepalived
    fi
fi

 

keepalived 配置公网虚拟IP

因为内网IP我们可以随意支配,随意容易配置,但配置公网虚拟IP时,还是有很大不同的,这里以云厂商提供的云主机为例
首先,需要主备keepalived机器都包含两个网卡,其中一个网卡为绑定内网,另一个绑定公网
事实上,两台云主机只需要有一个绑定了公网即可,但网卡数量不能少
大部分云厂商提供的云主机中,都包含公网网卡,但是也有只有内网网卡的
之所以可以使用公网IP访问,应该是通过路由器设置的,如金山云的云主机就只有内网网卡,这种机器暂时不知道怎么配置keepalived 的虚拟公网IP
 
这里服务器ip如下:
服务器 内网 外网
A 192.168.10.30 118.110.20.14
B 192.168.10.40  
外网IP的默认路由为118.110.20.11
内网网卡名为 ens224
外网网卡名为 ens160
 
方法一:
这里需要将两个服务器外网网卡都配置成不包含IP的配置并启动:
[admin@test ~]$ cat /etc/sysconfig/network-scripts/ifcfg-ens160
# 其中大部分配置都不是必须的,只需要能保证网卡能正常启动且不包含IP即可
HWADDR=00:50:56:8b:72:14
NAME=ens160
# GATEWAY=118.110.20.12
# NETMASK=255.255.255.240
# IPADDR=118.110.20.14
DNS1=8.8.4.4
DNS2=8.8.8.8
DOMAIN=example
DEVICE=ens160
ONBOOT=yes
USERCTL=no
BOOTPROTO=static
PEERDNS=no
 
check_link_down() {
 return 1;
}

 

keepalived配置如下:
# 这里只列出了主要部分,其他部分按照前面的例子来即可
vrrp_instance my_nginx {
    state MASTER
    interface ens224        # 这里必须写成内网网卡名,不能写成外网网卡名
    virtual_router_id 51
    priority 100
    advert_int 1
 
    track_script {
        chk_nginx
    }
 
    authentication {
        auth_type PASS
        auth_pass 111111
    }
    virtual_ipaddress {
        118.110.20.14/28 dev ens160    # 这里配置和上面的例子不一样,相当于直接配置ens160网卡,没用到label
    }
    virtual_routes {
        default via 118.110.20.12       # 这里配置默认路由
    }
}

 

注意,我们前面的例子中,interface 和虚拟网卡指定的网卡名都是一样,但事实上,这两个是没有联系的
interface 指定的网卡是用来发送arrp包的源地址,而虚拟网卡指定的网卡是为了做虚拟IP的
因为,如果我们这里interface 指定的网卡名为ens160,由于这个网卡没有IP,则由于发送arrp包时找不到源地址,而导致启动keepalived失败,报错如下,在/var/log/message中能找到报错信息:
Cannot find an IP address to use for interface

 

方法二:
主要思路是,两台机器都配置好公网网卡,IP都配置成118.193.20.4,然后让主的公网网卡启动,从的公网网卡关闭
具体步骤如下:
网卡配置如下:
[root@test sites]# cat /etc/sysconfig/network-scripts/ifcfg-ens160
HWADDR=00:50:56:8b:0e:60
NAME=ens160
GATEWAY=118.110.20.12
DNS1=8.8.4.4
DNS2=8.8.8.8
DOMAIN=example
DEVICE=ens160
ONBOOT=yes
USERCTL=no
BOOTPROTO=static
NETMASK=255.255.255.240
IPADDR=118.110.20.14
PEERDNS=no
 
check_link_down() {
 return 1;
}

 

keepalived配置如下:
vrrp_instance my_nginx {
    state BACKUP
    interface ens224        # 这里必须写成内网网卡名,不能写成外网网卡名
    virtual_router_id 51
    priority 100
    advert_int 1
 
    track_script {
        chk_nginx
    }
 
    authentication {
        auth_type PASS
        auth_pass 111111
    }
    notify_master /etc/keepalived/script/master.sh
    notify_backup /etc/keepalived/script/backup.sh
}

 

这里master.sh内容如下,主要功能是保证公网网卡启动:
#!/bin/bash
 
ifconfig | grep 118.110.20.14
if [ $? -ne 0 ];then
    ifconfig ens160 up
fi

 

backup.sh内容如下,主要功能就是关闭公网网卡:
#!/bin/bash
 
# 即使已经关闭了,再执行该命令也不会有报错,所以不用做判定
ifconfig ens160 down

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!