基于雲端虛拟機的LVS/DR+Keepalived+nginx的高可用叢集架構配置
最近,公司要我部署一個叢集架構,選來選取還是選擇了大家都很熟悉的基于DR的LVS+Keepalived做負載分發,然後使用輕量級的nginx做中間代理層,這裡呢先暫時實作一個簡單web應用功能,對于代理功能和後續的web層部署、資料層安排将擇機更新!
一、IP規劃:
做一件事情需要想想怎麼去做既簡單又有條理,我們做項目也應該如此。是以這裡一定先做一個簡單的規劃,對于你後續測試的時候出現不能分發的情況有所解決。
負載均衡層 代理層 WEB層(待定)
LVS1:10.124.20.248 nginx1:10.124.20.250 web1 10.124.20.240
web2 10.124.20.241
nginx2:10.124.20.251 web3 10.124.20.242
web4 10.124.20.243
LVS2:10.124.20.249 nginx3:10.124.20.252 web5 10.124.20.244
VIP:10.124.20.20 對應綁定的外網IP:117.78.3.253 web6 10.124.20.245
備注:在雲端虛拟機做架構,比在自己本地虛拟機做實驗,要略有不同。初次接觸雲端虛拟機的同學可能有點犯迷糊,不知道這個ip位址是怎麼配置設定的,怎麼去管理。我的老師教給一個最能解決問題的辦法:在任何服務之前,首先要了解整個網絡環境,然後根據環境部署服務,更改配置、規則等。關于雲端虛拟機,它在整個硬體防火牆和整個路由器封閉起來的一個大的區域網路叢集(這裡為了好了解我們姑且認為雲端就一個防火牆和一個路由器)。在這個叢集中,又有很多網段的區域網路,每個企業在申請虛拟機的時候一般會建立一個虛拟機組,這個機組則對應着一個網段。
這裡使用的網段是10.124.20.0/24,給各台伺服器配置設定唯一的IP位址。這裡要特别說明一下,華為雲技術人員建議使用的伺服器固定ip在32-254之間,在2-31之間的IP位址作為候補之用,比如說VIP就選用這裡面,還有臨時加虛拟機的話也可以選用。是以對于IP位址的規劃是很重要的。另外說一下,這也是在生産環境中的經驗吧,VIP必須是和叢集IP位址在一個網段,還要必須有别于叢集IP位址,另外要提供網站通路服務或者測試,則需要将内網的VIP與一個公網IP進行綁定,在外部網絡浏覽器通路外網IP就會直接映射到内網VIP上,然後就會實作我們所熟悉的功能,VIP漂移,LVS分發。小技巧:公網IP與單純的一個内網ip做綁定是不成功的,是以先把需要綁定公網IP的内網IP綁定到一個虛拟機上,然後再進行綁定,綁定完之後再進行更改IP位址。(比如說我要使用10.124.20.20做VIP,首先我把10.124.20.20綁定到一台虛拟機上,通過背景将外網IP117.78.3.253與10.124.20.20綁定,也就是做映射,最後再将10.124.20.20與虛拟解綁,這樣就實作了預期目的)
二、源碼安裝&&配置
1.LVS+Keepalived搭建
1)LVS1:10.124.20.248&&LVS2:10.124.20.249
cd /usr/local/src/
wget http://www.keepalived.org/software/keepalived-1.1.20.tar.gz
tar xf ipvsadm-1.24.tar.gz
tar xf keepalived-1.1.20.tar.gz
ipvsadm編譯安裝
ln -s /usr/src/kernels/2.6.32-279.el6.x86_64/ /usr/src/linux #建立軟連接配接
cd /usr/local/src/ipvsadm-1.24
make && make install
#/sbin/ipvsadm -v #檢測ipvsadm是否安裝成功(或者:#watch ipvsadm –ln)
ipvsadm v1.24 2005/12/10 (compiled with getopt_long and IPVS v1.2.1)
Keepalived編譯安裝
/usr/local/src/keepalived-1.1.20
./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.32-279.el6.x86_64
傳回資訊:
Keepalived configuration
------------------------
Keepalived version : 1.1.20
Compiler : gcc
Compiler flags : -g -O2
Extra Lib : -lpopt -lssl -lcrypto
Use IPVS Framework : Yes
IPVS sync daemon support : Yes
Use VRRP Framework : Yes
Use Debug flags : No
傳回資訊:
install -d /usr/local/keepalived/bin
install -m 755 ../bin/genhash /usr/local/keepalived/bin/
install -d /usr/local/keepalived/share/man/man1
install -m 644 ../doc/man/man1/genhash.1 /usr/local/keepalived/share/man/man1
将Keepalived做成服務:
cd /usr/local/keepalived/
cp etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
cp etc/sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived
cp etc/keepalived/keepalived.conf /etc/keepalived/
cp sbin/keepalived /usr/sbin/
将keepalived設定成開機自啟動服務
chkconfig --add keepalived
chkconfig keepalived on
2) 修改Keepalived.conf配置檔案
#cat /etc/keepalived/keepalived.conf #主LVS1:10.124.20.248
! Configuration File for keepalived
global_defs {
notification_email {
}
notification_email_from [email protected]
smtp_server 127.0.0.1
# smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_sync_group VGM {
group {
VI_1
}
notify_master "/opt/shell/arp.sh"
notify_backup "/opt/shell/arp.sh"
vrrp_script chk_nginx {
script "/opt/shell/check_nginx.sh"
interval 1
weight -2
vrrp_script chk_nginx2 {
script "/opt/shell/check_nginx2.sh"
vrrp_script chk_nginx3 {
script "/opt/shell/check_nginx3.sh"
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass yzkjTest
track_script {
chk_nginx
chk_nginx2
chk_nginx3
virtual_ipaddress {
10.124.20.20
}
virtual_server 10.124.20.20 80 {
delay_loop 5
lb_algo sh
lb_kind DR
persistence_timeout 60
protocol TCP
real_server 10.124.20.250 80 {
weight 1
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
real_server 10.124.20.251 80 {
weight 1
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
real_server 10.124.20.252 80 {
#cat /etc/keepalived/keepalived.conf #備LVS1:10.124.20.249
state BACKUP
priority 99
==============================================================
相關檢測腳本:
#cat /opt/shell/arp.sh
#!/bin/bash
VIP=10.124.20.20
GATEWAY=10.124.20.1
/sbin/arping -I eth0 -c 5 -s $VIP $GATEWAY &>/dev/null
#cat /opt/shell/check_nginx.sh
!/bin/bash
url="http://10.124.20.250"
status=$(/usr/bin/curl -s --head "$url" | awk '/HTTP/ {print $2}')
if [ "$status" != "200" ]; then
/opt/shell/arp.sh start
fi
#cat /opt/shell/check_nginx2.sh
url="http://10.124.20.251"
#cat /opt/shell/check_nginx3.sh
url="http://10.124.20.252"
===============================================================
3)Keepalived服務啟動(ifconfig eth0:1 10.124.20.248 netmask 255.255.255.255 up)
service keepalived start #服務啟動
#ps -aux|grep keepalived #檢測服務啟動狀态
(/usr/local/keepalived/sbin/keepalived -D -f /etc/keepalived/keepalived.conf -D 顯示在日志記錄 -f 指定配置檔案目錄)
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 21205 0.0 0.0 36776 732 ? Ss 17:06 0:00 keepalived -D
root 21207 0.0 0.1 38880 1936 ? S 17:06 0:00 keepalived -D
root 21208 0.0 0.1 38880 1232 ? S 17:06 0:00 keepalived -D
root 21301 0.0 0.0 103240 840 pts/0 S+ 17:07 0:00 grep keepalived
4)#設定開機啟動服務
(##echo “/usr/local/keepalived/sbin/keepalived -D -f /etc/keepalived/keepalived.conf” >> /etc/rc.d/rc.local)
chkconfig --add keepalived
chkconfig keepalived on
service iptables stop
5)添加防火牆規則:
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT #使80端口提供對外服務
iptables -A INPUT -d 224.0.0.0/8 -j ACCEPT
iptables -A INPUT -p vrrp -j ACCEPT #基于DR模式,當使用者送出請求後,隻有DR響應ARP廣播包,允許vrrp虛拟路由器備援協定
/etc/rc.d/init.d/iptables save #儲存規則到iptables檔案,使重新開機後生效)
6)開啟轉發功能;
#vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
#sysctl -p #使轉發能夠生效
三、nginx伺服器的搭建
1)安裝pcre-8.36.tar.gz
cd /usr/local/src
tar xf pcre-8.36.tar.gz
cd pcre-8.36
./configure --prefix=/usr/local/pcre
make && make install
2)安裝nginx-1.5.1.tar.gz
tar xf nginx-1.5.1.tar.gz
cd nginx-1.5.1
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.36 --with-openssl=/usr/local/src/openssl-1.0.0c //這裡跟的目錄是源碼目錄,而不是源碼安裝後的目錄
3)啟動
編寫啟動腳本:
vim /etc/init.d/nginx | chmod +x /etc/init.d/nginx
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /usr/local/nginx/conf/nginx.conf
# pidfile: /usr/local/nginx/logs/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
lockfile=/var/lock/subsys/nginx
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
[ $retval -eq 0 ] && rm -f $lockfile
restart() {
configtest || return $?
stop
start
reload() {
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
force_reload() {
restart
configtest() {
$nginx -t -c $NGINX_CONF_FILE
rh_status() {
status $prog
rh_status_q() {
rh_status >/dev/null 2>&1
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
restart|configtest)
reload)
rh_status_q || exit 7
force-reload)
force_reload
status)
rh_status
condrestart|try-restart)
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
======================================================================
service nginx start 啟動服務
4)RS配置腳本
======================================================================
#cat /opt/RS.sh
#!/bin/bash
# Script to start LVS DR real server.
# description: LVS DR real server
. /etc/rc.d/init.d/functions
VIP=10.124.20.20
host=`/bin/hostname`
start)
# Start LVS-DR real server on this machine.
/sbin/ifconfig lo down
/sbin/ifconfig lo up
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev lo:0
echo "RealServer Start OK"
;;
stop)
# Stop LVS-DR real server loopback device(s).
/sbin/ifconfig lo:0 down
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo "RealServer Stoped OK"
status)
# Status of LVS-DR real server.
islothere=`/sbin/ifconfig lo:0 | grep $VIP`
isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
if [ ! "$islothere" -o ! "isrothere" ];then
# Either the route or the lo:0 device
# not found.
echo "LVS-DR real server Stopped."
else
echo "LVS-DR real server Running."
fi
*)
# Invalid entry.
echo "$0: Usage: $0 {start|status|stop}"
exit 1
===================================================================
啟動RS配置:
sh /opt/RS.sh start
5)配置ngin.conf檔案,開啟反向代理功能(三台代理伺服器,需要修改的就是需要web伺服器的IP位址)
#nginx1:10.124.20.250
vim /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream YZKJ1 { #定義一個代理服務群組
ip_hash;
server 10.124.20.240 weight=1;
server 10.124.20.241 weight=1;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://YZKJ1; #開啟代理服務,直接執行代理服務群組
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
==================================================================
#nginx1:10.124.20.251
upstream YZKJ2 { #定義一個代理服務群組
server 10.124.20.242 weight=1;
server 10.124.20.243 weight=1;
proxy_pass http://YZKJ2; #開啟代理服務,直接執行代理服務群組
#nginx1:10.124.20.251
upstream YZKJ3 { #定義一個代理服務群組
server 10.124.20.244 weight=1;
server 10.124.20.245 weight=1;
server 10.124.20.246 weight=1;
proxy_pass http://YZKJ3; #開啟代理服務,直接執行代理服務群組
四、web層伺服器:
這裡使用的是nginx提供的web服務功能,是以,安裝步驟請參考第三部分RS的配置
如果使用Apache提供的文本服務,安裝流程請見下文:
=======================================================================
Apache源碼編譯安裝流程:(http-2.4.10.tar.gz)
cd /usr/local/src/
#依賴包安裝
*apr*
tar xf apr-1.4.6.tar.gz
cd apr-1.4.6
./configure --prefix=/usr/local/apr
make && make install
*apr-util*
tar xf apr-util-1.4.1.tar.gz
cd apr-util-1.4.1
./configure --prefix=/usr/lcoal/apr-util --with-apr=/usr/local/apr
make && make intsall
*pcre*
tar xf pcre-8.36.tar.gz
cd pcre-8.36
./configure --prefix=/usr/local/pcre
make
make check
make install
#Apache安裝
tar xf httpd-2.4.10.tar.gz
cd httpd-2.4.10
./configure --prefix=/usr/local/apache --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-pcre=/usr/local/pcre --enable-module=so --enable-deflate=shared --enable-expires=shared --enable-rewrite=shared --enable-cache --enable-file-cache --enable-men-cache --enable-disk-cache --enable-static-support --enable-static-ab --disable-userdir --with-mpm=prefork --enable-nonportable-atomics --disable-ipv6 --with-senfile
#Apache啟動
/usr/local/src/apache/bin/apachectl start
======================================================================================
五、測試
浏覽器通路測試117.78.3.253,能夠傳回想要的資訊即為成功!
六、總結
使用LVS+Keepalived做負載均衡,首先先将内部各個伺服器的iptables與selinux關閉,確定内部網絡通暢,一般而言,将上述防火牆關閉之後,安裝上述配置檔案提供的參數進行配置,是能夠實作預期功能的。我的檔案中可能提到過要設定iptables規則,這個要在測試通過之後,再打開iptables,然後寫上防火牆規則。通過查閱很多資料,看到很多人都在防火牆關閉的情況實驗成功,看來防火牆與LVS的分發功能是多少有點沖突,對于這方面的知識學習,有待于我們在今後的工作和學習中進行探索,我也将對後續知識在被人部落格上做介紹,希望以後能在這個平台與大家一起交流、學習、成長!
2014-12-02
2014-12-05更新
更新:防火牆設定:
修改防火牆
-A INPUT -p vrrp -j ACCEPT #基于DR模式,當使用者送出請求後,隻有DR響應ARP廣播包,允許vrrp虛拟路由器備援協定
重新開機防火牆:service iptables restart
2015.11.24更新
本文轉自 南非波波 51CTO部落格,原文連結:http://blog.51cto.com/nanfeibobo/1585684,如需轉載請自行聯系原作者