keepalived+nginx,實現nginx高可用,注意事項:1、VIP不需要在服務器網絡配置文件中配置。2、nginx主不可用時,需要kill掉nginx主的keepalived服務,這樣才可以實現VIP切換,因為主的keepalived優先級高。3、故障切換時發送郵件通知由nginx備的keepalived服務來實現。
其中nginx主上keepalived.conf配置為:
/etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs { #標識本節點的名稱 router_id master } vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" #每2秒檢測一次nginx的運行狀態 interval 2 #失敗一次,將自己的優先級調整為-20 weight -20 } vrrp_instance VI_1 { #狀態,主節點為MASTER state MASTER #綁定VIP的網絡接口 interface ens33 #虛擬路由的ID號,兩個節點設置必須一樣 virtual_router_id 51 #節點優先級,值范圍0~254,MASTER>BACKUP priority 100 #組播信息發送時間間隔,兩個節點必須設置一樣,默認為1秒 advert_int 1 #設置驗證信息,兩個節點必須一致 authentication { auth_type PASS auth_pass 1111 } #虛擬IP,兩個節點設置必須一致,可以設置多個 virtual_ipaddress { 192.168.1.106 } #nginx存活狀態檢測腳本 track_script { chk_nginx } }
其中調用的/etc/keepalived/nginx_check.sh腳本內容為:
#!/bin/bash A=`ps -C nginx -no-header |wc -l` if [ $A -eq 1 ];then pkill keepalived fi
nginx備上keepalived.conf配置為:
! Configuration File for keepalived global_defs { #標識本節點的名稱 router_id backup } vrrp_instance VI_1 { #狀態,備節點為BACKUP state BACKUP #綁定VIP的網絡接口 interface ens33 #虛擬路由的ID號,兩個節點設置必須一樣 virtual_router_id 51 #節點優先級,值范圍0~254,MASTER>BACKUP priority 99 #組播信息發送時間間隔,兩個節點必須設置一樣,默認為1秒 advert_int 1 #設置驗證信息,兩個節點必須一致 authentication { auth_type PASS auth_pass 1111 } #節點變為master時執行 notify_master /etc/keepalived/send_mail.sh #虛擬IP,兩個節點設置必須一致,可以設置多個 virtual_ipaddress { 192.168.1.106 } }
里邊調用的send_mail.sh腳本為使用Perl編寫的,需要安裝環境:
yum -y install perl-CPAN
cpan Net::SMTP_auth
send_mail.sh腳本內容為:
#!/usr/bin/perl -w
use Net::SMTP_auth;
use strict;
#smtp服務器
my $mailhost = 'smtp.exmail.qq.com';
#發送郵件的郵箱
my $mailfrom = 'from@qq.com';
#接收郵件的郵箱
my @mailto = ('to@qq.com');
#郵件主題
my $subject = 'keepalived up on backup';
#郵件正文
my $text = "正文\n nginx-1服務器宕機!!nginx-2變為master!!!";
#發送郵件的用戶名
my $user = 'from@qq.com';
#發送郵件的郵箱密碼
my $passwd = '123456';
&SendMail();
##############################
# Send notice mail
##############################
sub SendMail() {
my $smtp = Net::SMTP_auth->new( $mailhost, Timeout => 120, Debug => 1 )
or die "Error.\n";
$smtp->auth( 'LOGIN', $user, $passwd );
foreach my $mailto (@mailto) {
$smtp->mail($mailfrom);
$smtp->to($mailto);
$smtp->data();
$smtp->datasend("To: $mailto\n");
$smtp->datasend("From:$mailfrom\n");
$smtp->datasend("Subject: $subject\n");
$smtp->datasend("\n");
$smtp->datasend("$text\n\n");
$smtp->dataend();
}
$smtp->quit;
}