1? 概述
本文將介紹三個Keepalive高可用的實現案例,分別是keepalive實現LVS高可用,keepalive通過fwmark實現LVS高可用,keepalive實現Nginx高可用。
2實驗準備
.(1)各節(jié)點時間必須同步,這個操作很關鍵。工具有ntp和chrony(CentOS7上開始啟用)
.(2)確保iptables及selinux不會成為阻礙。7上要停止firewalld服務和iptables
.(3)各節(jié)點之間可通過主機名互相通信(對KA并非必須),建議使用/etc/hosts文件實現
172.18.50.63和73上配置
echo"172.18.50.63? node1 ">>/etc/hosts
echo"172.18.50.73?node2">>/etc/hosts
.(4)各節(jié)點之間的root用戶可以基于密鑰認證的ssh服務完成互相通信(對KA并非必須,但是建議配置)
兩臺都要設置
172.18.50.63上配置
ssh-keygen
ssh-copy-id -i /root/.ssh/id_rsa.pub 172.18.50.73
172.18.50.73上配置
ssh-keygen
ssh-copy-id -i /root/.ssh/id_rsa.pub 172.18.50.63
(5)多播地址
建議更改默認的多播地址,防止沖突,可以在配置文件里的全局加入選項vrrp_mcast_group4224.100.50.100。將組播地址調整為224.100.50.100。
網卡需要支持多播模式,默認網卡都開啟多播功能,可以使用如下的命令關閉多播地址(不能關閉該功能,僅當學習):
ip link set dev eth1 multicast off.
(6)測試
通過抓包查看
tcpdump -i eth1 -nn host組播ip,如下
tcpdump -i eth1 -nn host 224.50.50.50
注意,如果對應的主服務器的keepalived服務被停了,就會發(fā)一條優(yōu)先級為0的狀態(tài)。查看vip地址用ip a命令查看對應主機是否將VIP加入到網卡里
3 配置介紹
.虛擬服務器:
.配置參數:
有兩個配置的方法
virtual_server? IP port定義vip和端口,實現對該vip的統(tǒng)一調度
virtual_server? fwmark?int:指在keepalive的機器上的防火墻mangle表打標簽。同一標簽的主機實現同一的調度。如對外同一服務有兩個ip,vip1和vip2,后端有4臺RS,vip1和vip2在mangle表上打同一標簽,后臺的4臺RS都配置這兩個vip,那么keepalive服務器就可以實現訪問這兩個vip時,實現對這四臺RS的統(tǒng)一調度
virtual_server??IP?port?|?virtual_server??fwmark?int
{
...
real_server{
...
}
...
}
常用參數
.delay_loop??:服務輪詢的時間間隔
.lb_algo??rr|wrr|lc|wlc|lblc|sh|dh:定義調度方法
.lb_kind??NAT|DR|TUN:集群的類型
.persistence_timeout??:持久連接時長
.protocol?TCP:服務協(xié)議,僅支持TCP
.sorry_server?????:所有RS故障時,備用服務器地址
#以下配置,有幾臺RS就要重復配置幾遍
.real_server
{
weight????RS權重
notify_up??|?RS上線通知腳本
notify_down??|?RS下線通知腳本
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK???{?...}:定義當前主機的健康狀態(tài)檢測方法
}
KeepAlived配置檢測
.HTTP_GET|SSL_GET:應用層檢測
HTTP_GET|SSL_GET?{
url{
path??:定義要監(jiān)控的URL
status_code??:判斷上述檢測機制為健康狀態(tài)的響應碼
digest??:判斷為健康狀態(tài)的響應的內容的校驗碼
}
connect_timeout??:連接請求的超時時長
nb_get_retry??:重試次數
delay_before_retry??:重試之前的延遲時長
connect_ip???:向當前RS哪個IP地址發(fā)起健康狀態(tài)檢測請求,分流,定義用來監(jiān)控的網卡和提供服務的網卡不一樣
connect_port??:向當前RS的哪個PORT發(fā)起健康狀態(tài)檢測請求
bindto???:發(fā)出健康狀態(tài)檢測請求時使用的源地址
bind_port??:發(fā)出健康狀態(tài)檢測請求時使用的源端口
}
.TCP_CHECK?{
connect_ip?:向當前RS的哪個IP地址發(fā)起健康狀態(tài)檢測請求
connect_port?:向當前RS的哪個PORT發(fā)起健康狀態(tài)檢測請求
bindto??:發(fā)出健康狀態(tài)檢測請求時使用的源地址
bind_port?:發(fā)出健康狀態(tài)檢測請求時使用的源端口
connect_timeout?:連接請求的超時時長
}
4? 案例實現
所有實驗會用到通知腳本和RS配置腳本,所以,將這兩個腳本單獨放置
4.1示例通知腳本
這里例子是發(fā)郵件的腳本,實際情況當角色發(fā)生變化的時候,需要服務器執(zhí)行什么操作可以直接寫入腳本里,而不僅僅是發(fā)郵件通知,從而實現其他應用的高可用。
注意,以下的HA1和HA2表示高可用主機1和高可用主機2,和haproxy無關。HA為highavailability
#!/bin/bash
#
contact='root@localhost'
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
;;
backup)
notify?backup
;;
fault)
notify?fault
;;
*)
echo?"Usage:?$(basename?$0)
{master|backup|fault}"
exit?1
;;
esac
.腳本的調用方法:
直接寫入配置文件VRRPD配置段里
notify_master??"/etc/keepalived/notify.sh?master"
notify_backup??"/etc/keepalived/notify.sh?backup"
notify_fault???"/etc/keepalived/notify.sh?fault"
重啟服務,用mail查看
4.2 RS配置
#!/bin/bash
#
#******************************************************************************
#Author:??????????????? ?Sunny
#Date:?????????????????2017-10-24
#FileName:?????????????? ? lvs_dr_rs.sh
#version:?????????????? ?1.0
#Your?change?info:
#Description:?????????? ? ? ? ?For?auto?set?RS_dr
#DOC?URL:????????????? ?http://ghbsunny.blog.51cto.com/7759574/1975813
#Copyright(C):?????????? ? ? 2017??All?rights?reserved
#*****************************************************************************
vip=172.18.50.80
mask='255.255.255.255'
dev=lo:1
rpm?-q?httpd?&>?/dev/null?||?yum?-y?install?httpd?&>/dev/null
service?httpd?start?&>?/dev/null?&&?echo?"The?httpd?Server?is?Ready!"
echo?"
`hostname`
"?>?/var/www/html/index.html
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?$dev?$vip?netmask?$mask?broadcast?$vip?up
echo?"The?RS?Server?is?Ready!"
;;
stop)
ifconfig?$dev?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
echo?"The?RS?Server?is?Canceled!"
;;
*)
echo?"Usage:?$(basename?$0)?start|stop"
exit?1
;;
esac
4.3? keepalive實現LVS高可用
實現效果是當有請求過來時,根據輪詢規(guī)則調度到后端RS,同時實現了對RS的健康性檢查,同時實現VS的高可用
拓撲圖如下

4.3.1 HA1 配置如下
!?Configuration?File?for?keepalived
global_defs?{
notification_email?{
root@localhost
}
notification_email_from?node1@localhost
smtp_server?127.0.0.1
smtp_connect_timeout?30
router_id?node1
vrrp_mcast_group4?224.50.50.50
}
vrrp_instance?VI_1?{
state?MASTER
interface?eth1
virtual_router_id?50
priority?100
advert_int?1
authentication?{
auth_type?PASS
auth_pass?sunny
}
virtual_ipaddress?{
172.18.50.80
}
notify_master?"/etc/keepalived/vip1_notify.sh?master"
notify_backup?"/etc/keepalived/vip1_notify.sh?backup"
notify_fault??"/etc/keepalived/vip1_notify.sh?fault"
virtual_server?172.18.50.80?80?{
delay_loop?3
lb_algo?wrr
lb_kind?DR
protocol?TCP
sorry_server?127.0.0.1?80
real_server?172.18.50.65?80?{
weight?2
HTTP_GET?{
url?{
path?/
status_code?200
}
connect_timeout?1
nb_get_retry?2
delay_before_retry?1
}
}
real_server?172.18.50.75?80?{
weight?1
HTTP_GET?{
url?{
path?/
status_code?200
}
connet_timeout?1
nb_get_retry?2
delay_before_retry?1
}
}
}
}
HA2只需調整優(yōu)先級,stats 為BACKUP,網卡等相關信息,其他不變,RS配置參考3.2,注意VIP使用32位,防止路由問題,導致調度不通,然后測試
4.4? keepalive通過fwmark實現LVS高可用
基于fwmark雙主模式的lvs集群,基于fwmark,實現雙主高可用的前提下,根據防火墻prerouting鏈上的mark會將所有的請求均勻調度。

4.4.1 打標簽
在兩臺63和73上keepalive機器上防火墻的mangle表打標簽,命令如下
iptables?-t?mangle?-A?PREROUTING?-d172.18.50.80,172.18.50.90?-p?tcp?--dport?80?-j?MARK?--set-mark?6
4.4.2 HA1 上配置
!?Configuration?File?for?keepalived
global_defs?{
notification_email?{
root@localhost
}
notification_email_from?node1@localhost
smtp_server?127.0.0.1
smtp_connect_timeout?30
router_id?node1
vrrp_mcast_group4?224.50.50.50
}
vrrp_instance?VI_1?{
state?MASTER
interface?eth1
virtual_router_id?50
priority?100
advert_int?1
authentication?{
auth_type?PASS
auth_pass?sunny
}
virtual_ipaddress?{
172.18.50.80
}
notify_master?"/etc/keepalived/vip1_notify.sh?master"
notify_backup?"/etc/keepalived/vip1_notify.sh?backup"
notify_fault??"/etc/keepalived/vip1_notify.sh?fault"
}
virtual_server?fwmark?6?{
delay_loop?3
lb_algo?wrr
lb_kind?DR
protocol?TCP
sorry_server?127.0.0.1?80
real_server?172.18.50.65?80?{
weight?1
HTTP_GET?{
url?{
path?/
status_code?200
}
connect_timeout?1
nb_get_retry?2
delay_before_retry?1
}
}
real_server?172.18.50.75?80?{
weight?1
HTTP_GET?{
url?{
path?/
status_code?200
}
connet_timeout?1
nb_get_retry?2
delay_before_retry?1
}
}
}
4.4.3 配置RS1和RS2,參考3.2,然后進行測試
4.5keepalive實現Nginx高可用
.keepalived調用外部的輔助腳本進行資源監(jiān)控,并根據監(jiān)控的結果狀態(tài)能實現優(yōu)先動態(tài)調整
.vrrp_script:自定義資源監(jiān)控腳本,vrrp實例根據腳本返回值,公共定義,可被多個實例調用,定義在vrrp實例之外
.track_script:調用vrrp_script定義的腳本去監(jiān)控資源,定義在實例之內,調用事先定義的vrrp_script
.分兩步:(1)先定義一個腳本;(2)調用此腳本。
vrrp_script ? {
script " " #這里寫腳本的真實路徑,也可以是bash命令
interval INT? #多久執(zhí)行一次腳本
weight? -INT #當主服務異常,把之前定義的vrrp權重減掉多少,減少得比backup的值還低,這樣就可以實現對別得應用的高可用性的支持
}
track_script {
#以下是調用腳本,這里相當于是虛擬路由器的代碼段
SCRIPT_NAME_1
SCRIPT_NAME_2
}
示例:高可用nginx服務

兩臺nginx服務器上分別安裝keepalive,通過腳本檢查keepalive和nginx是否存在,實現高可用。
一般只有一臺keepalive的級別高,所以該機器的nginx起作用,負責調度,當nginx異常,權重減去20后,備用的keepalive起作用,備用機器刪的nginx接管工作。后端的RS是定義在nginx的http配置段里
chk_down的函數作用是檢查/etc/keepalived/down文件存在時,就返回1,就將keepalive權重減去20。vip將配置到另一臺主機,使得備用主機生效。當/etc/keepalived/down刪掉后,該主機的優(yōu)先級就會自動加上20.重新?lián)屨紇ip。
chk_nginx的函數作用是檢查nginx是否正常運行,當nginx異常時,就將keepalive優(yōu)先級減去20。vip將配置到另一臺主機,使得另一臺的keepalive生效當nginx重新工作后,該主機的優(yōu)先級就會自動加上20.重新?lián)屨紇ip。
4.5.1 HA1配置如下
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from node1@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1
vrrp_mcast_group4 224.50.50.50
}
vrrp_script? chk_down {
script "[[ -f? /etc/keepalived/down ]] && exit 1 || exit 0"
interval? 1
weight? -20
}
vrrp_script? chk_nginx {
script "killall -0 nginx && exit 0 || exit 1"
interval 1
weight? -20
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface eth1
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass sunny
}
virtual_ipaddress {
172.18.50.80
}
notify_master "/etc/keepalived/vip1_notify.sh master"
notify_backup "/etc/keepalived/vip1_notify.sh backup"
notify_fault? "/etc/keepalived/vip1_notify.sh fault"
track_script {
chk_down
chk_nginx
}
}
4.5.2 nginx 配置如下
http{
......
upstream websrvs {
server 172.18.50.75:80 weight=1;
server 172.18.50.65:80 weight=2;
server 127.0.0.1:8000 backup;
}
......
}
server {
.....
location / {
proxy_pass http://websrvs;
}
......
}
4.5.3 測試
創(chuàng)建/etc/keeplived/down文件以及關閉keepalive查看實驗