nginx + keepalived 高可用

178 阅读4分钟

keepalived + nginx 安装步骤

一、 Nginx 安装及启动

  1. 默认情况Centos7中没有Nginx的源,Nginx官方提供了源,执行以下命令添加源
  1. 安装Nginx

    • yum install -y nginx
  2. 启动Nginx并设置开机自启

    • systemctl start nginx.service
    • systemctl enable nginx.service
  3. Nginx其他命令

    • systemctl stop nginx.service
    • systemctl restart nginx.service
  4. Ifconfig 查看ip地址(inet)

    • ifconfig命令不存在,则下载 yum install -y net-tools
  5. 主机访问虚拟机上的nginx

    • 如果访问失败,可能是因为防火墙没有开放80端口的原因
    • 执行命令 firewall-cmd --zone=public --add-port=80/tcp --permanent
    • --zone=public 表示作用域
    • --add-port=80/tcp 表示添加的端口、协议
    • --permanent 表示永久生效,没有此参数重启后失效
    • 配置完成后,重启防火墙systemctl restart firewall

二、keepalived 安装及启动

  1. 安装keepalived

    • yum install -y keepalived
    • systemctl enbale keepliaved.service 开机自启keepalived
  2. 常用命令

    • systemctl start keepalived.service
    • systemctl stop keepalived.service
    • systemctl restart keepalived.service
  3. 修改keepalived默认配置

    • 两个重点文件
    • /etc/keepalived/keepalived.conf (keepalived配置文件)
    • tail -f /var/log/messages(查看日志)
  4. 重点配置项

    • global_defs(全局配置)
      • notification_email 服务停止,发送邮件
      • route_id 路由id,此处设置的是KEEPALIVED_NGINX_MASTER
        • 到/etc/hosts中配置 127.0.0.1 KEEPALIVED_NGINX_MASTER
      • vrrp_skip_check_adv_addr 是否跳过心跳检测,默认不跳过,比较费时,因此可以关闭,没什么影响
      • vrrp_strict 严格遵守vrrp协议,一定要注释掉
    • vrrp_instance(实例配置)
      • 集群设置 多机设置,除了state和priority不一样,其他都一样
      • state 分为MASTER 和 BACKUP,主机的权重必须比备机大
      • interface 绑定实例网卡,通过ip addr查看,一般是ens33
      • virtual_route_id 虚拟路由ID,即实例ID,keepalived集群的时候必须一致
      • Priority 权重比,备机设置20 - 60 都行,一定要比主机小
      • advert_int 1 心跳间隔 单位秒,keepalived集群通过心跳检测,如果没反应,备机立刻接管
      • Authentication 服务器之间的通信的密码认证
      • virtual_ipaddress 设置虚拟ip
    • vrrp_server(lvs配置项,删掉)
  5. shell脚本优化keepalived+nginx

    • 大多数时候nginx比keepalived更容易挂,如果nginx挂了,则keepalived会一直空请求,因此当nginx挂掉后,要随后停止keepalived
    #!/bin/bash
    echo 'xxxxxx'
    count_nginx=`ps -ef|grep -w nginx|grep -v grep|wc -l`
    echo $count_nginx
    if [ $count_nginx -eq 0 ];then
    	systemctl start nginx.service
    		echo 'nginx auto restart !!!'
    	sleep 2
    	if [ `ps -ef|grep -w nginx|grep -v grep|wc -l` -eq 0 ];then
    		systemctl stop keepalived.service
    		echo 'keepalived shutdown !!!'
    	fi
    fi
    
    • 赋予执行权限 chmod 744 nginx_check.sh

    • 到keepalived.conf中添加代码段,注意:vrrp_script代码段必须在vrrp实例之前,否则实例中的track_script代码段找不到自定义的script

      vrrp_script chk_nginx {
         script "/shell/nginx_check.sh" # keepalived+nginx检测脚本地址
         interval 5 #检查时间间隔,一定要比脚本执行时间长
         weight -30 # 比重,这里是单独的知识点,比较复杂
      }
      
    • 在VRRP实例中添加 track_script { chk_nginx } 以启动脚本检测

    1. 完整的主机keepalived.conf

image-20230823113132087

  1. 各类问题解决

    • warning default user ‘keepalived_script’ for script execution does not exist - please create

      • 找不到keepalived_script这个用户组,开启下面的配置,如果找不到就使用root

      • 在全局配置global_defs中添加 script_user root

    • Unable to access script `/shell/nginx_check.sh’

      • selinux禁止了这个脚本
      • 执行命令 “sed -i “s\SELINUX=enforcing\SELINUX=disabled\g” /etc/selinux/config”
      • 重启shutdown -r now
    • Disabling track script chk_nginx since not found

      • 在VRRP实例中添加 track_script { chk_nginx } 以启动脚本检测
    • SECURITY VIOLATION - scripts are being executed but script_security not enabled

      • 在全局配置global_defs中添加 enable_script_security
    • Can't open PID file /var/run/nginx.pid (yet?) after start: No such file or directory

      • 使用systemctl start nginx时,先调用的是 nginx.service,启动时nginx.pid文件并未生成
      • /usr/lib/systemd/system/nginx.service[service]模块下添加ExecStartPost=/bin/sleep 0.1
    • Can't open PID file /var/run/keepalived.pid (yet?) after start: No such file or directory

      • 使用systemctl start keepalived时,先调用的是 keepalived.service,启动时keealived.pid文件并未生成
      • /usr/lib/systemd/system/keepalived.service[service]模块下添加ExecStartPost=/bin/sleep 0.1
    • 网络上的各种格式问题都是假的,比如vrrp_script的两个大括号要单独占一行

    • 但是 vrrp_script / track_script 需要 空格一次 再写大括号。例如 track_script{}错,tract_script {}对

    • vrrp_script中的interval 5后面不能有空格

  2. 输出日志检查

    cat /var/log/messages 打印完整日志

    tail -f /var/log/messages 实时输出最新日志

    cat /var/log/nginx/error.log 查看nginx报错日志

三、keepalived邮件功能

  1. 检查系统中是否安装了mailx
  2. yum install -y mailx
  3. 申请阿里云邮箱的授权码,获取发件服务器的smtp地址
  4. vi /etc/mail.rc,添加以下配置
set from=xxxx@qq.com # 发件人邮箱
set smtp=smtp.qiye.aliyun.com # aliyun的smtp发件服务器地址
set smtp-auth-user=xxxx@qq.com #需要和from保持一致
set smtp-auth-password=xxxxxx # 第三方客户端授权码
  1. 可以选择设置hostname在邮件内容中使用,hostnamectl set-hostname xxxxxxx
  2. 邮件内容脚本 notify.sh
contact='mail1@qq.com mail2@qq.com'

notify() {  
    mailsubject="$(hostname) to be $1, vip change"  
    mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"  
    echo "$mailbody" | mail -s "$mailsubject" $contact  
}  
case $1 in  
master)  
    notify master  
    ;;  
backup)  
    notify backup  
    ;;  
fault)  
    notify fault  
    ;;  
*)  
    echo "Usage: $(basename $0) {master|backup|fault}"  
    exit 1  
    ;;  
esac
  1. chmod +x notify.sh 给予执行权限
  2. 修改 /etc/keepalived/keepalived.conf配置文件,在示例中添加

image.png

四、防止脑裂,改为单播模式

  1. 在主备服务器的keepalived配置文件的实例中配置unicast_src_ip(当前服务器IP)和unicast_peer(对端服务器IP) image.png

五、keepalived stop时,发送邮件

  1. 编写脚本 notify_stop.sh
contact='mail1@qq.com mail2@qq.com'  

notify_stop() {  
    mailsubject="$(hostname) shutdown!!!"  
    mailbody="$(date +'%F %T'): $(hostname) shutdown!!!"  
    echo "$mailbody" | mail -s "$mailsubject" $contact  
}  

notify_stop
  1. 可以对脚本进行测试 ./notify_stop.sh ,会发送邮件
  2. 在keepalived的配置文件中,添加 notify_stop "/shell/notify_stop.sh",重启keepalived即可