1. 程式人生 > >實踐:在CentOS7.3部署 keepalived 高可用nginx(負載均衡)

實踐:在CentOS7.3部署 keepalived 高可用nginx(負載均衡)

高可用 nginx keepalived centos7.3

背景:

既然有了Lvs+keepalived這樣高性能的組合,那為何還要有Nginx+keepalived呢,keepalived的初衷就是為了Lvs而設計的,我們都知道Lvs是一個四層的負載均衡設備,雖然有著高性能的優勢,但同時它卻沒有後端服務器的健康檢查機制,keepalived為lvs設計了一系列的健康檢查機制TCP_CHECK,UDP_CHECK,HTTP_GET等。同時lvs也可以自己寫健康檢查腳腳本。或者結合ldirectory來實現後端檢測。但是固LVS始終無法擺脫它是一個四層設備,無法對上層協議進行解析。Nginx不一樣,Nginx是一個七層的設備可以對七層協議進行解析,可以對一些請求進行過濾,還可以對請求結果進行緩存。這些都是Nginx獨有的優勢。但是keepalived並沒有為Nginx提供健康檢測。需要自己去寫一些腳步來進行健康檢測。關於keepalived+lvs的構建可參考我的另一篇博文:

http://ljohn.blog.51cto.com/11932290/1980547

廢話不多說開始構建 keppalived+nginx 高可用集群

1、首先還是要準備環境

四臺機器

192.168.0.56 ---> proxy1 (nginx)

192.168.0.57 ---> proxy2 (nginx)

192.168.0.58 ---> web1 (httpd)

192.168.0.59 ---> web1 (httpd)

拓撲

技術分享 技術分享

註:

1、這裏需要保持4臺機器時間同步
# ntpdate IP(ntp時鐘服務器自行搭建不多介紹)
*/5 * * * * root /usr/sbin/ntpdate 192.168.1.99 &>/dev/null;hwclock -w
2、為了操作的方便後面配置對所有參與機器進行免密處理
# ssh-keygen -t rsa -P ‘‘ -f "/root/.ssh/id_rsa"
# for i in 56 57 58 59;do ssh-copy-id -i .ssh/id_rsa.pub [email protected].$i;done


2、配置realserver(web1和web2)

a、安裝web程序

註意這裏的realserver 可以是任何web容器(tomcat、jetty、httpd、nginx..),因為是學習,所以這裏使用httpd來演示

#yum install httpd -y
#systemctl restart httpd
# netstat -nultp| grep httpd##確保httpd啟動
tcp6       0      0 :::80                   :::*                    LISTEN      4619/httpd
配置頁面
web1:
# echo "<h1>The page from web1(58)</h1>" > /var/www/html/index.html
web2:
# echo "<h1>The page from web1(59)</h1>" > /var/www/html/index.html

b、設置VIP及內核參數

# cat setka.sh
#!/bin/bash
vip=192.168.0.100
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
;;
stop)
ifconfig lo:0 down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
;;
esac
# bash setka.sh start#運行該腳本設置相關內核參數及VIP地址。
# cat /proc/sys/net/ipv4/conf/lo/arp_ignore##內核參數設置成功
1
# cat /proc/sys/net/ipv4/conf/all/arp_announce
2
# ifconfig lo:0#VIP設置成功
lo:0      Link encap:Local Loopback
inet addr:192.168.137.10  Mask:255.255.255.255
UP LOOPBACK RUNNING  MTU:65536  Metric:1
# scp setka.sh [email protected]:/root #拷貝一份給RS2並執行
setka.sh                                                                                         100%  547     0.5KB/s   00:00

3、配置nginx proxy1和2 負載均衡

a、兩臺proxy都安裝nginx

yum install -y nginx

b、配置nginx proxy

vim /etc/nginx/nginx.conf
upstream backserver {
server 192.168.0.58:80 weight=1 max_fails=3 fail_timeout=3s;
server 192.168.0.59:80 weight=2 max_fails=3 fail_timeout=3s;
}
server {
listen       80;
server_name  localhost;
location / {
root   html;
index  index.html index.htm;
proxy_pass http://backserver;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

復制一份至另一臺proxy(nginx)

# scp /etc/nginx/nginx.conf [email protected]:/etc/nginx/nginx.conf
# systemctl restart nginx;ssh 192.168.0.57 ‘systemctl restart nginx’

c、測試訪問

# for i in {1..10};do curl http://192.168.0.56;done
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
# for i in {1..10};do curl http://192.168.0.57;done
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>

#註:這裏可以看出,每臺proxy(nginx) 都完成了負載均衡配置,且實現了負載均衡調度。細心的同學發現後端real server 配置的權重1:2,調度大致請求調度返回也為1:2

4、配置keepalived 高可用nginx

a、每臺proxy安裝httpd 和keepalived

# yum install -y httpd keepalived

每臺proxy 配置Sorry頁面,這裏一旦後端服務器同時無法訪問,會自動調用本地的httpd服務

# echo "<h1>Sorry,Under maintances(56).</h1>" >/var/www/html/index.html
# echo "<h1>Sorry,Under maintances(57).</h1>" >/var/www/html/index.html
# 編輯各個proxy 的 nginx.conf,添加在upstream下添加
server 127.0.0.1:8080 backup;
或者:# sed -i ‘/server 192.168.0.59:80 weight=2 max_fails=3 fail_timeout=3s;/a\server 127.0.0.1:8080 backup;‘ /etc/nginx/nginx.conf

b、編輯配置文件

proxy1:

# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost    #定義郵箱報警的郵箱地址
}
notification_email_from root@localhost #定義發送報警信息的地址
smtp_server 127.0.0.1 #定義發送郵件的郵件服務器地址
smtp_connect_timeout 30 #定義發送郵件的超時時間
router_id ha_nginx #全局標識
}
vrrp_script chk_nginx {    #定義檢查nginx服務的腳本
script "/etc/keepalived/chk_nginx.sh"  #腳本重啟nginx,如果進程還是無法檢測到,則強制停止keepalived
interval 2 #檢查的間隔時間
weight -2 #檢查失敗的話權重減2
fall 2 #檢查失敗2次才認為是真正的檢查失敗
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100  #備用機器的keepalived的權重要小於這個權重,並且當nginx服務掛掉後100-2要小於備用機器的權重。
advert_int 1
smtp_alert #比較重要 定義使用郵件發送,不然上面的郵件定義都是沒有用的,使用了這個當狀態發生改變就會發送郵件報警
authentication {
auth_type PASS
auth_pass 1111
}
track_script {    #定義使用哪個腳本來檢查。
chk_nginx
}
virtual_ipaddress {
192.168.0.100/16 dev=ens33
}
}

##拷貝配置文件至proxy2

# scp /etc/keepalived/keepalived.conf [email protected]:/etc/keepalived/keepalived.conf

proxy2:

修改keepalived.conf 如下兩個參數:

state BACKUP

priority 99

#這裏貼出我實驗的配置

# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {
notification_email {
root@localhost    #定義郵箱報警的郵箱地址
}
notification_email_from root@localhost #定義發送報警信息的地址
smtp_server 127.0.0.1 #定義發送郵件的郵件服務器地址
smtp_connect_timeout 30 #定義發送郵件的超時時間
router_id ha_nginx #全局標識
}
vrrp_script chk_nginx {    #定義檢查nginx服務的腳本
script "/etc/keepalived/chk_nginx.sh" #腳本重啟nginx,如果進程還是無法檢測到,則強制停止keepalived
interval 2 #檢查的間隔時間
weight -2 #檢查失敗的話權重減2
fall 2 #檢查失敗2次才認為是真正的檢查失敗
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 99  #備用機器的keepalived的權重要小於這個權重,並且當nginx服務掛掉後100-2要小於備用機器的權重。
advert_int 1
smtp_alert #比較重要 定義使用郵件發送,不然上面的郵件定義都是沒有用的,使用了這個當狀態發生改變就會發送郵件報警
authentication {
auth_type PASS
auth_pass 1111
}
track_script {    #定義使用哪個腳本來檢查。
chk_nginx
}
virtual_ipaddress {
192.168.0.100/16 dev=ens33
}
}

c、nginx檢測腳本

#腳本先判斷是否有nginx進程,然後如果沒有,則會重啟nginx,如果進程還是無法檢測到,則強制停止keepalived,啟用備用節點的作為master。

#該腳本可以有效防止HA腦裂,發現無發啟動nginx嘗試重啟,不行再將keepalived關閉,徹底移除此節點。

#cat /etc/keepalived/chk_nginx.sh
#!/bin/bash
N=`ps -C nginx --no-header|wc -l`
if [ $N -eq 0 ];then
systemctl restart keepalived
sleep 1
if [ `ps -C nginx --no-header|wc -l` -eq 0 ];then
systemctl stop keepalived
fi
fi

d、啟動keepalived及nginx

# systemctl restart nginx;ssh 192.168.0.57 ‘systemctl restart nginx‘
# systemctl restart keepalived.service;ssh 192.168.0.57 ‘systemctl restart keepalived.service‘

5、測試

1、查看地址是否在proxy1上:

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d6:84:65 brd ff:ff:ff:ff:ff:ff
 inet 192.168.0.56/24 brd 192.168.0.255 scope global ens33
valid_lft forever preferred_lft forever
  inet 192.168.0.100/16 scope global ens33:1
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed6:8465/64 scope link
valid_lft forever preferred_lft forever

測試網頁是否能夠打開。

# for i in {1..5};do curl http://192.168.0.100;done
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>

這裏能夠正常訪問,測試通過。

2、關閉主節點的keepalived測試VIP是否能夠漂移至備用節點

[root@node2 keepalived]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:7c:92:ae brd ff:ff:ff:ff:ff:ff
   inet 192.168.0.57/24 brd 192.168.0.255 scope global ens33
valid_lft forever preferred_lft forever
 inet 192.168.0.100/16 scope global ens33:1
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe7c:92ae/64 scope link
valid_lft forever preferred_lft forever

查看VIP是否能正常訪問

# for i in {1..5};do curl http://192.168.0.100;done
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>

這裏能夠正常訪問,測試通過。

5、由於我們配置的搶占模式,一旦主節點恢復,則VIP會直接漂回去。

[root@node1 ~]# systemctl  start  keepalived
[root@node1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d6:84:65 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.56/24 brd 192.168.0.255 scope global ens33
valid_lft forever preferred_lft forever
  inet 192.168.0.100/16 scope global ens33:1
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed6:8465/64 scope link
valid_lft forever preferred_lft forever

測試VIP訪問

# for i in {1..5};do curl http://192.168.0.100;done
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(58)</h1>
<h1>The page from web1(59)</h1>
<h1>The page from web1(59)</h1>

VIP地址又被主節點搶回來,服務正常訪問,通過測試

最後我們來看下一下備用節點的在主節點keepalived關閉時,系統到底做了什麽

##查看日誌,觀察VIP漂移的整個過程

1、傳遞MASTER的狀態

2、設置自己為MASTER狀態,

3、設置VIP 虛擬地址

4、發送ARP廣播地址 ,地址為:192.168.0.100 #告訴大家我現在叫MASTER,對外提供服務了。

備用節點上/var/log/messages:

Nov 13 16:46:02 localhost Keepalived_vrrp[12348]: VRRP_Instance(VI_1) Transition to MASTER STATE

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: VRRP_Instance(VI_1) Entering MASTER STATE

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: VRRP_Instance(VI_1) setting protocol VIPs.

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: Sending gratuitous ARP on ens33 for 192.168.0.100

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.0.100

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: Sending gratuitous ARP on ens33 for 192.168.0.100

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: Sending gratuitous ARP on ens33 for 192.168.0.100

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: Sending gratuitous ARP on ens33 for 192.168.0.100

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: Sending gratuitous ARP on ens33 for 192.168.0.100

Nov 13 16:46:03 localhost Keepalived_vrrp[12348]: Remote SMTP server [127.0.0.1]:25 connected.

FAQ:

Q:再/var/log/messages日誌中發現:Unable to access script `killall`

A:因為centos7精簡安裝,沒有killall命令,需要安裝一下

# yum install psmisc -y

至此在CentOS7.3上完成了:keepalived 高可用nginx,有興趣的同學可以玩一下,有什麽問題,還請批評指正。


參考博文:

http://forlinux.blog.51cto.com/8001278/1404936

http://www.178linux.com/75428

本文出自 “Ljohn” 博客,請務必保留此出處http://ljohn.blog.51cto.com/11932290/1981369

實踐:在CentOS7.3部署 keepalived 高可用nginx(負載均衡)