keepalived
一、原理:
功能:能夠自動實現將用戶訪問的ip轉移的方法,故障重啟,故障,恢復切換,故障報警
模型:Master/Backup
使用場景:節點少,沒有共享存儲等等。他只能有一個主活動,其他為從節點
- 功能實現:
Master不停的向Backup進行心跳通告,一旦心跳停止就遷移VIP。
Keepalived是模塊化,主要是給LVS提供高可用性,並且可以向后端的Realserver提供健康狀態檢查,還可以通過腳本對特定服務進行健康檢查,故障重啟及切換。
- keepalived核心:
vrrp:虛擬冗余路由協議
VRRP有限狀態機
為了解決ip漂移后mac地址也變化了,IP地址和MAC地址都是虛擬的(VMAC),通 過心跳檢測的良好狀態進行轉移也可以降低優先級進行故障轉移(0-255 ,數字越大優先級越高)
virtual server
vrrp_script:
監控服務的健康狀態。根據服務的狀態故障轉移
- Keepalived架構圖:
Configure file parser 配置文件檢測,主進程負責分析配置文件
I/O Multiplexer , io多路復用
watchdog : 監控兩個進程健康狀態,負責啟動,重啟兩個紫禁城
兩個子進程:真正工作的子進程
Checkers:自身的IPVS的后端服務器的健康狀態
用戶提供腳本
VRRP:
VRRP認證機制:1、明文認證, 2、hmac認證
二、安裝及配置
1、http://keepalived.org/ 下載軟件或在Centos 6.4以后可以yum安裝
ansible two -m yum -a "name=keepalived state=installed"
2、Keepalived文件
/etc/keepalived/keepalive.conf
/etc/init.d/keepalived
3、同步時間
ansible all -a 'ntpdate s1a.time.edu.cn'
4、備份配置文件
ansible two -a "cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak"
man Keepalived.conf
! Configuration File for keepalived #這部分配置好了就可以啟動,Keepalived就開始互相監聽Keepalived服務了。 global_defs { #全局配置 ,主要是通知機制及靜態路由配置,還可以定義靜態路由,但非必要,所以這里沒給默認值 notification_email { #收件人 #acassen@firewall.loc #這三個均為收件人 #failover@firewall.loc #sysadmin@firewall.loc
# } notification_email_from Alexandre.Cassen@firewall.loc #發件人 smtp_server 192.168.200.1 #發件服務器 smtp_connect_timeout 30 #發件連接超時 router_id LVS_DEVEL #路由器標示,隨便給一個字符串 }
vrrp_script chk_svr_down { #vrrp定義檢測判斷腳本 , chk_svr_down 是腳本名稱,隨便取 script "[[ -f /etc/keepalived/down ]]" && exit 1 || exit 0" #這里可以去讀取腳本,或者用引號括起來的一個命令 返回1執行下面額weight -2 interval 1 #每隔1秒鍾檢測一次 weight -2 #如果腳本檢測成功權重 - 2 }
vrrp_instance VI_1 { . #配置vrrpd 定義虛擬路由器 VI_1 虛擬路由的標示名稱,隨意取名 state MASTER #初始狀態,這里定義了master了其priority的值就要高於其他節點
state MASTER #定義主,可以不定義
interface eth0 #通告選舉通過那個網卡進行 virtual_router_id 51 #虛擬路由ID,每個虛擬路由都需要有id號,vmac的最后一段地址,最大255,一套Keepalived 應該是相同的id priority 100 #初始優先級,高的為master,高的會在恢復的時候搶過來 advert_int 1 #通告時間間隔 authentication { #認證機制 auth_type PASS #明文機制 ,或者ssl認證 auth_pass 1111 #認證密碼 } virtual_ipaddress { #VIP地址 192.168.200.16 #定義ip格式 <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> lable <LABLE>
# IP MASK 廣播地址 工作在那塊網卡上 工作范圍:外網是否可見 網卡別名
可以定義多個vip #192.168.200.17/24 dev eth1 #定義的格式,可以指定多個option
#192.168.200.18/24 dev eth2 label eth2:1
}
track_script { #這里面追蹤上面的腳本,才真正執行上面的腳本
chk_svr_down
[可以是多個。。。]
}
}
vrrp_instance VI_2 { #可以定義兩套vrrp路由協議,做成雙主,互相切換,前段通過DNS多個A記錄達到分攤負載的作用
interface eth0 virtual_router_id 52 priority 99 advert_int 1 authentication { auth_type PASS auth_pass 2222 } virtual_ipaddress { 192.168.200.17 #定義ip格式 <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> lable <LABLE>
# IP MASK 廣播地址 工作在那塊網卡上 工作范圍:外網是否可見 網卡別名
#192.168.200.17/24 dev eth1
#192.168.200.18/24 dev eth2 label eth2:1
}
track_script {
chk_svr_down
[可以是多個。。。]
notify_master "/path/to/file.sh master" #轉變成master 通知,代參數(有空白字符)需要有引號
notify_backup "/path/to/file.sh backup" #轉變成backup 通知
notify_fault "/path/to/file.sh fault" #轉變成失敗通知
notify /path/notify.sh #自寫腳本應付所有的通知
#腳本的格式 $1 指明白是 GROUP | instance 哪個配置段中
# $2 說明是哪個 name of group or instance #說明是哪個group 或者instance
# $3 轉換狀態說明
}
#調取腳本發通知或執行
virtual_server 192.168.56.100 80 { LVS 配置段 支持 virtual server group 和 virtual server
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP
#sorry_server 192.168.200.200 1358
real_server 192.168.56.2 80 {
weight 1
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.56.3 80 {
weight 1
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}

Dec 15 00:39:22 vm2 kernel: IPVS: Registered protocols (TCP, UDP, SCTP, AH, ESP) Dec 15 00:39:22 vm2 kernel: IPVS: Connection hash table configured (size=4096, memory=64Kbytes) Dec 15 00:39:22 vm2 kernel: IPVS: ipvs loaded. Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Netlink reflector reports IP 10.0.2.5 added Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Netlink reflector reports IP 192.168.56.4 added Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Netlink reflector reports IP fe80::a00:27ff:fee5:3c84 added Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Netlink reflector reports IP fe80::a00:27ff:fea9:ff31 added Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Registering Kernel netlink reflector Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Registering Kernel netlink command channel Dec 15 00:39:22 vm2 Keepalived_vrrp[3543]: Opening file '/etc/keepalived/keepalived.conf'. Dec 15 00:39:22 vm2 Keepalived_vrrp[3543]: Configuration is using : 62967 Bytes Dec 15 00:39:22 vm2 Keepalived_vrrp[3543]: Using LinkWatch kernel netlink reflector... Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Opening file '/etc/keepalived/keepalived.conf'. Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Configuration is using : 7510 Bytes Dec 15 00:39:22 vm2 Keepalived_healthcheckers[3542]: Using LinkWatch kernel netlink reflector... Dec 15 00:39:22 vm2 Keepalived_vrrp[3543]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)] Dec 15 00:39:23 vm2 Keepalived_vrrp[3543]: VRRP_Instance(VI_1) Transition to MASTER STATE Dec 15 00:39:24 vm2 Keepalived_vrrp[3543]: VRRP_Instance(VI_1) Entering MASTER STATE Dec 15 00:39:24 vm2 Keepalived_vrrp[3543]: VRRP_Instance(VI_1) setting protocol VIPs. Dec 15 00:39:24 vm2 Keepalived_vrrp[3543]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.56.6 Dec 15 00:39:24 vm2 Keepalived_healthcheckers[3542]: Netlink reflector reports IP 192.168.56.6 added Dec 15 00:39:29 vm2 Keepalived_vrrp[3543]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.56.6

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:e5:3c:84 brd ff:ff:ff:ff:ff:ff inet 10.0.2.5/24 brd 10.0.2.255 scope global eth0 inet 192.168.56.6/32 scope global eth0 inet6 fe80::a00:27ff:fee5:3c84/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:a9:ff:31 brd ff:ff:ff:ff:ff:ff inet 192.168.56.4/24 brd 192.168.56.255 scope global eth1 inet6 fe80::a00:27ff:fea9:ff31/64 scope link valid_lft forever preferred_lft forever
ip位置在eth0上,看着不爽,改到eth1上
virtual_ipaddress { 192.168.56.6 dev eth1 }
keepalived 心跳地址:224.0.0.1
現在就可以實現Keepalived服務及主機宕機故障恢復的切換了。(因為優先級高的原因,默認下Keepalived的 VRRP工作在搶占模式)
5、vrrp_script 腳本檢測
vrrp_script chk_svr_down { 定義腳本 script "[[ -f /etc/keepalived/down ]]" && exit 1 || exit 0" #可以是引號中的判斷命令,也可以是個腳本路徑 返回1執行下面的操作
interval 2 #1s 檢測一次 weight -2 #權重 -2
fall 2 #失敗2次才下線
rise 2 #成功2次才上線 }
vrrp_script chk_nginx {
scrip "killall -0 nginx" #檢查nginx
interval 2
weight -2
fall 2
rise 2
}
track_scropt { #引用腳本
chk_svr_down
[可以是多個]
chk_nginx
}
*但是有多個檢測可能因為權重值得原因服務不切換
*如果兩邊都有例子中的文件,則不切換,一旦一個服務器沒有了這個文件,立刻轉移過去,並且master一旦恢復也會切換過來
ipvsadm
ipvsadm -A -t [tcp|udp|fwm] 192.168.50.100:80 -s rr [ -p 持久連接時間 ]
ipvsadm -a -t [tcp|udp|fwm] 192.168.50.100:80 -r 10.0.5.10 -g -w rr
virtual_server 10.0.50.10 443 { #虛擬服務器 #這個ip就是vip , 80是客戶端訪問的端口 ,防火牆的標記 : virtual_server fwmark int ,組 virtual_server group string delay_loop 6 lb_algo rr #lvs 調取算法 [ rr|wrr|lc|wlc|lblc|sh|dh|... ] lb_kind NAT #策略 NAT|DR|TUN nat_mask 255.255.255.0 persistence_timeout 50 #支持持久連接的時間 protocol TCP
sorry_server 192.168.200.200 1358 , #所有服務器全掛了
real_server 192.168.201.100 443 { #real 地址 端口 weight 1 #權重
notify_up "script" #腳本通知
notify_down "script" #腳本通知
SSL_GET|HTTP_GET|{ #監控狀態檢測, tcp_check tcp檢測,ssl_check 檢測ssl服務器,smtp檢測郵件服務器,misc 不便歸類的方式。 url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc #通過校驗碼比較
}
url {
path /mrtg/
#status_code 200 #或者使用返回碼 }
connect_port <port> #realserver 發起檢測的端口
bindto <ipaddr> #發起檢測ip的端口
connect_timeout 3 #連接超時時間 nb_get_retry 3 #嘗試幾次 delay_before_retry 3 #每次嘗試之前等待時間 } } } virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP sorry_server 192.168.200.200 1358 , #所有服務器全掛了 real_server 192.168.200.2 1358 { weight 1 TCP_CHECK { #tcp_check 只有以下檢測選項 connect_port <port>
bindto <ipaddr>
connect_timeout 3 } } }
配置文件層次:
GLOBL CONFIGURATION . #全局配置文件
Global definitons #全局配置
static route #靜態路徑
VRRPD CONFIGURATION #配合vrrp子進程工作協議的,雙主需要在這里定義兩個路由,路由標示
VRRP synchronization group #同步組,在一個節點上配置了2個VIP,一同轉移時
string ,name of group of ips that falover together
VRRP instace(s) #vrrp實例:核心,優先級等在這配置
Describes the moveable IP for each instance of a group in vrrp_sync_group . #轉移ip地址
LVS CONFIGUATION
Virtual server group #虛擬路由服務器組
Virtual server #虛擬服務器
*下划線的用的比較多
通知:
位置
1、vrrp_instance {
}
2、vrrp_sync_groyp{
}
通知腳本類型:
1.分開通知,每種狀態觸發不同腳本
# to MASTER transition
notify_master /path/to_master.sh
# to BACKUP transition
notify_backup /path/to_backup.sh
# FAULT transition
notify_fault "/path/fault.sh VG_1"
2.一個腳本應付3中狀態,但是需要接受參數
# arguments
# $1 = "GROUP"|"INSTANCE" #明確用在group中還是instance中
# $2 = name of group or instance #說明那個group or instence
# $3 = target state of transition #說明轉換成什么狀態
# ("MASTER"|"BACKUP"|"FAULT")
notify /path/notify.sh
單個版本

#!/bin/bash vip=192.168.5.1 content="root@localhost" notify () { mailbody="vrrp tansaction, $vip floated to `hostname`" subject="`hostname` is $vip MASTER" echo $mailbody | mail -s $subject $content } notify
通用版本

vip=192.168.56.100 contact="root@localhost" notify() { mailsubject="`hostname` to be $1: $vip floating" mailbody="`date +%F` : vrrp transition, `hostname` changed to be $1" echo $mailbody | mail -s "$mailsubject" $contact } case "$1" in master) notify master exit 0 ;; backup) notify backup /etc/init.d/nginx restart #只是在Keepalived 監控本機的nginx exit 0 ;; fault) notify fault exit 0 ;; esac