1. 程式人生 > >32.2nginx反向代理+keepalived高可用實驗

32.2nginx反向代理+keepalived高可用實驗

本節內容:
keepalived基於lvs,內建了lvs功能,實現了ipvsadm命令及lvs排程器的高可用性;而其它應用的高可用性keepalived提供了指令碼方式以供解決。如nginx作為反向代理伺服器時,不具備高可用性,利用keepalived的指令碼方式實現nginx的高可用性。

keepalived實現lvs的原理是基於vrrp協議(借鑑路由器的工作方式),即一臺lvs伺服器實現排程,存在spof單點失敗問題,再搭建一臺lvs伺服器,實現主備,當主lvs宕機,啟動備用lvs即可實現高可用性。工作方式基於優先順序,優先順序高的自動為主lvs,又分為搶佔式和非搶佔式,即主lvs宕機,備用lvs成為主lvs,當原來宕機的主lvs修復後,誰當主的問題,預設搶佔模式,即原主修復後優先順序高,會重新成為主

keepalived基於指令碼呼叫介面通過執行指令碼完成指令碼中定義的功能,進而影響叢集事務, 以此支援nginx、haproxy等服務。這些是keepalived內建實現功能的原理,被開發keepalived的開發人員寫好了。而我們要實現其它服務,如nginx作為反向代理伺服器,則keepalived內建沒有此指令碼功能,但keepalived支援指令碼呼叫。需要我們自己寫指令碼,通過keepalived呼叫自定義指令碼實現高可用性

實驗:keepalived實現主主 nginx反向代理的高用性

這裡寫圖片描述

rs伺服器準備

[root@cos27 ~ ]#hostnamectl set-hostname rs1
[root@cos37 ~ ]#hostnamectl set-hostname rs2
[root@cos27 ~ ]#exit
[root@cos37 ~ ]#exit

[root@rs1 ~ ]#yum install httpd -y
[root@rs2 ~ ]#yum install httpd -y
[root@rs1 ~ ]#systemctl start httpd
[root@rs2 ~ ]#systemctl start httpd
[root@rs1 ~ ]#echo rs1:192.168.31.27 > /var/www/html/index.html [root@rs2 ~ ]#echo rs2:192.168.31.37 > /var/www/html/index.html [root@rs1 ~ ]#curl 192.168.31.27 rs1:192.168.31.27 [root@rs2 ~ ]#curl 192.168.31.37 rs2:192.168.31.37 [root@rs1 ~ ]#ip a a 192.168.31.47/24 dev eth0 [root@rs2 ~ ]#ip a a 192.168.31.57/24 dev eth0 [root@rs1 ~ ]#vim /etc/httpd/conf.d/vhosts.conf <virtualhost 192.168.31.47:80> documentroot /data/website2/ <directory /data/website2> require all granted </directory> </virtualhost> [root@rs1 ~ ]#mkdir /data/website2 -p [root@rs1 ~ ]#echo app.dhy.com:rs1 > /data/website2/index.html [root@rs1 ~ ]#systemctl restart httpd [root@rs1 ~ ]#curl 192.168.31.47 app.dhy.com:rs1 [root@rs2 ~ ]#vim /etc/httpd/conf.d/vhosts.conf <virtualhost 192.168.31.57:80> documentroot /data/website2/ <directory /data/website2> require all granted </directory> </virtualhost> [root@rs2 ~ ]#mkdir /data/website2 -p [root@rs2 ~ ]#echo app.dhy.com:rs2 > /data/website2/index.html [root@rs2 ~ ]#systemctl restart httpd [root@rs2 ~ ]#curl 192.168.31.57 app.dhy.com:rs2

ka和nginx代理配置

HA Cluster 配置準備:

(1) 各節點時間必須同步
ntp, chrony
(2) 確保iptables及selinux不會成為阻礙
(3) 各節點之間可通過主機名互相通訊(對KA並非必須)
建議使用/etc/hosts檔案實現
(4) 各節點之間的root使用者可以基於金鑰認證的ssh服務完成互相通訊(對KA並非必須)

[root@ka1 ~ ]#yum install keepalived
[root@ka2 ~ ]#yum install keepalived
[root@ka1 ~ ]#yum install nginx -y
[root@ka2 ~ ]#yum install nginx -y
[root@cos7 ~ ]#hostnamectl set-hostname ka1
[root@cos17 ~ ]#hostnamectl set-hostname ka2
[root@cos7 ~ ]#exit
[root@cos17 ~ ]#hxit
[root@ka1 ~ ]#cd /etc/keepalived/

[root@ka1 ~ ]#ssh-genkey
[root@ka1 ~ ]#ssh-copy-id 192.168.31.17
[root@ka1 ~ ]#ssh-genkey
[root@ka2 ~ ]#ssh-copy-id 192.168.31.7

[root@ka1 keepalived ]#vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 ka1
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.31.17 ka1

[root@ka2 etc ]#vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 ka2
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.31.7 ka1      
nginx反向代理配置
[[email protected] ~ ]#vim /etc/nginx/nginx.conf
#新增或者修改如下配置
http {
    upstream websrvs{            #反向代理
        server 192.168.31.27:80;
        server 192.168.31.37:80;
    }
    upstream websrvs2{
         server 192.168.31.47:80;
         server 192.168.31.57:80;
    }

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  www.dhy.com;

        location / {
                proxy_pass http://websrvs ;
        }  
    }
    server {
        listen       80;
        server_name app.dhy.com;
        location / {
            proxy_pass http://websrvs2 ;
        }
    }
[[email protected] ~ ]#vim /etc/nginx/nginx.conf
同上
ka1,ka2高可用性配置
[[email protected] ~ ]#vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
    [email protected]
   }
   notification_email_from [email protected]
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka1                     #ka2上修改為ka2
   vrrp_mcast_group4 230.10.10.10
}
vrrp_script chk_nginx {
        script "/usr/bin/killall -0 nginx &> /dev/null "
        interval 1
        weight -30
 #       fall 2
 #      rise 1
}

vrrp_instance VI_1 {
    state MASTER                     #ka2修改為BACKUP
    interface eth1
    virtual_router_id 50
    priority 100                     #ka2上修改為80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        172.18.0.100/16 
    }
    track_script {
        chk_nginx
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}
vrrp_instance VI_2 {
    state BACKUP                      #ka2上修改為MASTER
    interface eth1
    virtual_router_id 60
    priority 80                       #ka2上修改為100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 654321
    }
    virtual_ipaddress {
        172.18.0.200/16
    }
    track_script {
        chk_nginx
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

[[email protected] ~ ]#vim /etc/keepalived/notify.sh
#!/bin/bash
#
contact='[email protected]'
notify() {
mailsubject="$(hostname) to be $1, vip floating"
mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
systemctl start nginx
;;
backup)
notify backup
systemctl restart nginx
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac

啟動服務,測試
[root@ka1 ~ ]#systemctl start keepalived.service nginx.service 
[root@ka2 ~ ]#systemctl start keepalived.service nginx.service 

[root@client ~ ]#vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 client
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.18.0.100 www.dhy.com
172.18.0.200 app.dhy.com

[root@client ~ ]#curl www.dhy.com
rs1:192.168.31.27
[root@client ~ ]#curl www.dhy.com
rs2:192.168.31.37

[root@client ~ ]#for i in {1..100};do curl www.dhy.com;curl app.dhy.com;sleep 2;done
rs2:192.168.31.37
app.dhy.com:rs1
rs1:192.168.31.27
app.dhy.com:rs2
rs2:192.168.31.37
app.dhy.com:rs2
curl: (7) couldn't connect to host  #[[email protected] ~ ]#killall nginx
app.dhy.com:rs1
rs1:192.168.31.27
app.dhy.com:rs2
rs2:192.168.31.37
app.dhy.com:rs1
rs1:192.168.31.27
app.dhy.com:rs1
rs2:192.168.31.37