[TOC]html
最近由於工做須要在看keepalived,而官方文檔一頁把所有的配置和說明列了出來,沒有分類,東西不少但殊不知道那些是我須要的,網上找文章,發現也很少,並且仍是有些坑,因而記錄一下,順便吐槽下這個markdown,流程圖都不支持,排版還有些問題。python
摘自: http://seanlook.com/2015/5/18/nginx-keepalived-ha/linux
Keepalived是一個基於VRRP協議來實現的服務高可用方案,能夠利用其來避免IP單點故障,相似的工具還有heartbeat、corosync、pacemaker。可是它通常不會單獨出現,而是與其它負載均衡技術(如lvs、haproxy、nginx)一塊兒工做來達到集羣的高可用。nginx
摘自: http://seanlook.com/2015/5/18/nginx-keepalived-ha/git
VRRP全稱 Virtual Router Redundancy Protocol,即 虛擬路由冗餘協議。能夠認爲它是實現路由器高可用的容錯協議,即將N臺提供相同功能的路由器組成一個路由器組(Router Group),這個組裏面有一個master和多個backup,但在外界看來就像一臺同樣,構成虛擬路由器,擁有一個虛擬IP(vip,也就是路由器所在局域網內其餘機器的默認路由),佔有這個IP的master實際負責ARP相應和轉發IP數據包,組中的其它路由器做爲備份的角色處於待命狀態。master會發組播消息,當backup在超時時間內收不到vrrp包時就認爲master宕掉了,這時就須要根據VRRP的優先級來選舉一個backup當master,保證路由器的高可用。shell
在VRRP協議實現裏,虛擬路由器使用 00-00-5E-00-01-XX 做爲虛擬MAC地址,XX就是惟一的 VRID (Virtual Router IDentifier),這個地址同一時間只有一個物理路由器佔用。在虛擬路由器裏面的物理路由器組裏面經過多播IP地址 224.0.0.18 來定時發送通告消息。每一個Router都有一個 1-255 之間的優先級別,級別最高的(highest priority)將成爲主控(master)路由器。經過下降master的優先權可讓處於backup狀態的路由器搶佔(pro-empt)主路由器的狀態,兩個backup優先級相同的IP地址較大者爲master,接管虛擬IP。json
graph TD C1[客戶端1] --> B(虛擬IP: 10.0.0.100) C2[客戶端2] --> B B --> K1[keepalived主機] B --> K2[keepalived備機] K1 --> A1[服務1: 10.0.0.1] K1 --> A2[服務1: 10.0.0.2] K2 --> A3[服務2: 10.0.0.3] K2 --> A4[服務1: 10.0.0.4]
上面是markdown的流程圖,這個編輯器不支持,下面是我從新截的圖: vim
經過對虛擬IP的訪問,便可訪問到後端對應的服務;後端
注意,防火牆也處理好對應的端口,好比: 後端服務: 10.0.0.1:8080,則10.0.0.1要開放8080端口,由於須要被keepalived主機訪問;同時keepalived主機也須要開啓8080端口,由於須要被客戶端訪問。安全
sudo yum -y install keepalived
官網下載最新版2.0.0版的[keepalived](http://keepalived.com/download 最新版2.0.12有bug,每次重啓keepalived後都須要從新reload firewalld。建議使用2.0.0版本。
解壓
進入目錄
開始安裝,依次執行
# 須要跑這個才能自動生成系統服務文件(keepalived.service) # 2.0.0版本沒有這個,直接執行下面的步驟便可,也會自動創建系統服務文件 #./build_setup # 安裝配置,默認就能夠 ./configure # 編譯安裝 sudo make && sudo make install
安裝過程當中可能會失敗,提示缺乏依賴,依賴在解壓的目錄下的INSTALL文件有說明,在這裏貼一下RedHat發行版及其衍生版的,其餘發行版的本身看吧:
RedHat based systems (RedHat Enterprise/CentOS/Fedora) ------------------------------------------------------ The following build packages are needed: make autoconf automake (to build from git source tree rather than tarball) The following libraries need to be installed: openssl-devel libnl3-devel ipset-devel iptables-devel libnfnetlink-devel For magic file identification support: file-devel For SNMP support: net-snmp-devel For DBUS support: glib2-devel For JSON support: json-c-devel For PCRE support pcre2-devel For nftables support libnftnl-devel libmnl-devel For building the documentation, the following packages need to be installed: Fedora: python-sphinx (will pull in: python2-sphinx_rtd_theme) CentOS-and-friends: python-sphinx epel-release python-sphinx_rtd_theme For latex or pdf files, the following are also needed: Fedora: latexmk python-sphinx-latex CentOS-and-friends: latexmk texlive texlive-titlesec texlive-framed texlive-threeparttable texlive-wrapfig texlive-multirow
安裝完成後的主要目錄:
配置文件 /usr/local/etc/keepalived/keepalived.conf keepalived啓動配置文件 /usr/local/etc/sysconf/keepalived
由於keepalived的默認配置文件位置是: /etc/keepalived/keepalived.conf,因此須要將實際的文件文職軟鏈接到這裏,固然也能夠在/usr/local/etc/syscofig/keepalived裏面配置增長選項: -f 配置文件路徑,這樣的形式來更改配置文件路徑。本文是以創建軟鏈接的方式
sudo ln -s /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
這樣就算是安裝完成了。
sudo firewall-cmd --reload
固然,測試機器關閉防火牆也就一勞永逸了,記得要同時關閉selinux。selinux的保護機制致使跟蹤腳本不能執行某些操做(例如:重啓某項服務等),解決方法是修改對應腳本的安全上下文類型,詳細看下面的配置說明(2.0.0版本不須要修改安全上下文類型了)。
# Centos 7 systemctl start keepalived.service
或者
# Centos 6 service keepalived start
摘自: http://seanlook.com/2015/5/18/nginx-keepalived-ha/,有額外添加和補充。
global_defs項
- notification_email : keepalived在發生諸如切換操做時須要發送email通知地址,後面的 smtp_server 相比也都知道是郵件服務器地址。也能夠經過其它方式報警,畢竟郵件不是實時通知的。
- router_id : 機器標識,一般可設爲hostname。故障發生時,郵件通知會用到。
vrrp_instance項
- state : 只能爲兩個值之一:MASTER或BACKUP(必須大寫)。指定instance(Initial)的初始狀態,就是說在配置好後,這臺服務器的初始狀態就是這裏指定的,但這裏指定的不算,仍是得要經過競選經過優先級來肯定。若是這裏設置爲MASTER,但如若他的優先級不及另一臺,那麼這臺在發送通告時,會發送本身的優先級,另一臺發現優先級不如本身的高,那麼他會就回搶佔爲MASTER。
- interface : 實例綁定的網卡,由於在配置虛擬IP的時候必須是在已有的網卡上添加的。
- mcast_src_ip : 發送多播數據包時的源IP地址(默認是224.0.0.28,使用默認的就能夠了)。這裏注意了,這裏實際上就是在那個地址上發送VRRP通告,這個很是重要,必定要選擇穩定的網卡端口來發送,這裏至關於heartbeat的心跳端口,若是沒有設置那麼就用默認的綁定的網卡的IP,也就是interface指定的IP地址。
- virtual_router_id :0~255, 這裏設置VRID,這裏很是重要,相同的VRID爲一個組,他將決定多播的MAC地址。
- priority : 1~254,數字越大優先級越高。設置本節點的優先級,優先級高的爲master
- advert_int : 檢查間隔,默認爲1秒。這就是VRRP的定時器,MASTER每隔這樣一個時間間隔,就會發送一個advertisement報文以通知組內其餘路由器本身工做正常。
- authentication : 定義認證方式和密碼,主從必須同樣。
- virtual_ipaddress : 這裏設置的就是VIP,也就是虛擬IP地址,他隨着state的變化而增長刪除,當state爲master的時候就添加,當state爲backup的時候刪除,這裏主要是有優先級來決定的,和state設置的值沒有多大關係,這裏能夠設置多個IP地址。
- track_script : 引用VRRP腳本,即在 vrrp_script 部分指定的名字。按期運行它們來改變優先級,並最終引起主備切換。
- uncast_src_ip : 單播地址,即本機ip。
- uncast_peer : 接收單播地址(BACKUP ip),配置在{}裏面,能夠多個。
vrrp_script
告訴 keepalived 在什麼狀況下切換,因此尤其重要。能夠有多個 vrrp_script。
- script : 本身寫的檢測腳本。也能夠是一行命令如killall -0 nginx。
- interval 2 : 每2s檢測一次。
- weight -5 : 檢測失敗(腳本返回非0)則優先級 -5。
- fall 2 : 檢測連續 2 次失敗纔算肯定是真失敗。會用weight減小優先級(1-255之間)。
- rise 1 : 檢測 1 次成功就算成功。但不修改優先級。
這裏要說明一下script通常有2種寫法:
上文 vrrp_script 配置部分,killall -0 nginx屬於第1種狀況,/etc/keepalived/check_nginx.sh屬於第2種狀況(腳本中關閉keepalived)。我的更傾向於經過shell腳本判斷,但有異常時exit 1,正常退出exit 0,而後keepalived根據動態調整的 vrrp_instance 優先級選舉決定是否搶佔VIP:
其餘狀況,本來配置的優先級不變,即配置文件中priority對應的值。
提示:
以上能夠作到利用腳本檢測業務進程的狀態,並動態調整優先級從而實現主備切換。
如下打上勾爲必須配置,其餘爲可選配置。
修改虛擬ip(vip)實例:
vrrp_instance_VI_1 { state MASTER # 若是是備機,則改成BACKUP, 必須大寫 # 主機能夠啓用非搶佔模式,當主機宕機,備機提高爲主機後,宕機的主機又恢復了正常了,這是會發生再次搶佔;主機開啓非搶佔模式,就能避免在正常運行狀態的的切換了 nopreempt # 非搶佔模式 instance enp0s3 # 修改爲對應的網卡名稱 # 其餘配置 # ... virtual_ipaddress { 10.0.0.100 # 修改爲指定的ip地址(同網段) } # 可選配置,定時執行指定的腳本配置 # 能夠用於指定執行間隔地執行服務檢查腳本 # 腳本檢查到某些服務狀態或者進程狀態,能夠作相應的處理: # 1.返回正常或非正常的退出碼(exit code),能夠用於更新當前機器的優先級, # 前提是配置爲搶佔模式,前提是沒有配置爲非搶佔模式(默認就是搶佔模式) # 2.檢查到服務或進程異常,就關閉當前的keepalived進程,而後備機會經過選舉來提高爲主機 # 3.其餘操做 # 重要:若是要配置,則必須在vrrp_instance_XX前聲明: # vrrp_script 腳本名稱 { # 腳本內容 # } # 而後在下面節點內聲明腳本名稱,能夠聲明多個,用空格或者回車隔開 track_script { 腳本名稱 } }
vrrp script示例,必須聲明在vrrp_instance節點前:
vrrp_script check-nginx { script "pidof nginx" }
或
vrrp_script check-nginx { script "/etc/keepalived/check_nginx.sh" interval 3 # 要比arp通告時間長,腳本里面若是有sleep的話,也要比sleep的時間長 weight 50 # 檢測正常或者異常(exit code = 0 或者 = 1),正常,優先級加50;反之,減50 fall 2 # 跟蹤腳本返回2次exit code = 1,纔算是一次異常;即發生兩次exit code = 1,優先級才減一次50 rise 1 # 跟蹤腳本返回1次exit code = 0, 算是一次正常;即發生兩次exit code = 0, 優先級加一次50; # user root 腳本執行用戶,取默認就好 }
簡單檢查nginx進程是否存在,實際上nginx進程正常運行並不表明服務就是正常的,應該同時檢查後端服務時候正常,check_nginx.sh:
#!/bin/bash count=$(ps -C nginx --no-heading | wc -l) if [ "$count" = "0" ]; then systemctl start nginx.service sleep 2 count=$(ps -C nginx --no-heading | wc -l) exit 1 else exit 0 fi
若是須要再虛擬一個其餘網卡的vip,能夠複製多一份vrrp_instance進行修改。
修改完後,複製或者同步修改好的配置文件到備機,記得修改備機的state爲BACKUP和優先級prority, 優先級必須比主機的優先級低。
若是在不關閉主機keepalived進程的狀況下,想要使某臺備機提高爲主機,能夠修改優先級大於當前主機優先級50,重啓備機keepalived便可。官方文檔:
#for electing MASTER, highest priority wins. #to be MASTER, make this 50 more than on other machines. priority 100
若是防火牆使用firewalld管理:
firewall-cmd --zone=public --add-port=80/tcp --permanent
開啓80端口
所有部署了keepalived的主機都須要開啓vrrp支持。
# 添加規則 firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface enp0s3 --destination 224.0.0.18 --protocol vrrp -j ACCEPT # 重啓防火牆 firewall-cmd --reload
enp0s3對應網卡名稱, 224.0.0.18是keepalived的組播地址。
vim /etc/sysconfig/iptables # 添加配置 -A INPUT -i 網卡名稱 -p vrrp -s 主/備IP -j ACCEPT
# master uncast_src_ip 10.0.0.1 uncast_peer { 10.0.0.2 } # backup uncast_src_ip 10.0.0.2 uncast_peer { 10.0.0.1 }
keepalived的默認日誌路徑是: /var/log/message
如下以日誌路徑/var/log/keepalived.log
爲例:
keepalived --help 能夠查看支持的配置
修改前: KEEPALIVED_OPTIONS="-D"
, 修改後: KEEPALIVED_OPTIONS="-D -d -S 0"
上面的0表示的是系統級別的日誌存放路徑local0.*
, 在/etc/rsyslog.conf
裏面最後面增長:
local0.* /var/log/keepalived.log
sudo systemctl restart rsyslog.service
再重啓keepalived服務:
sudo systemctl restart keepalived.service
若是上述必需配置都已經配置好了,還 是不能訪問,那就是配置有問題了,請檢查各個配置是否有拼寫錯誤等緣由。
日誌: Healthcheck child process(14203) died: Respawning
解決方法: 刪除多無或無效的vrrp_server節點。 vrrp_server是用於lvs的負載均衡的,如無用能夠刪掉。 參考這裏
/../../檢查腳本.sh exited due to signal 15
解決方法: 腳本里的休眠時間要小於vrrp_script裏面設置的執行間隔interval;
緣由:selinux的保護機制。
解決方法: 1.關閉selinux。臨時關閉: setenfource 0; 永久關閉: 修改
/etc/selinux/config
裏的SELINUX屬性,enfourcing爲強制開啓,permissive爲寬容,disabled爲關閉,設置爲後兩個之一就能夠。2.修改跟蹤腳本的安全上下文的類型爲
keepalived_unconfined_script_exec_t
,以腳本'/etc/keepalived/check_nginx.sh'爲例: sudo chcon -v -t keepalived_unconfined_script_exec_t /etc/keepalived/check_nginx.sh 使用ls命令的Z選項查看,發現已經修改了,以下圖:
2019-02-17更新:新版本(2.0.12)不須要修改安全上下文類型也可使用跟蹤腳本重啓nginx。
2019-02-18更新:版本2.0.0可使用,相比1.3版本,主機恢復正常運行狀態,從新搶佔期間服務不可用的時間短了不少,幾乎無感,相比最新版本2.0.12,不須要修改腳本安全上下文類型的同時,每次重啓也無需reload firewalld。建議使用此版本。
ip addr
發`現網卡上也已經產生了虛擬ip,但卻訪問不了,ip也ping不通:檢查防火牆是否已經開啓了vrrp協議支持,就算以前已經配置好了,從新安裝後也須要reload一下防火牆配置
sudo firewall-cmd --reload
,坑。 2019-02-17更新: 這個是新版本keepalived的問題,每次從新啓動都須要reload一下firwalld,還沒找到官方的解決方案,不知道是否是bug,只能新建腳原本啓動了,記得修改keepalived.service對應項,或者下降keepalived的版本,不知道具體從哪一個版本開始有這個問題,1.3或者1.4的沒問題。
2019-02-18更新: 建議使用2.0.0版本,暫時未發現bug,每次重啓keepalived也不用reload firewald, 主機恢復後搶佔期間服務不可用的狀況,幾乎無感。
諸如"received 1 ahtu, exception 0!", 或者 "bogus ..., exception 1!"
解決方法: 統一所有主機的keepalived版本。(這種狀況也有多是virtual_route_id衝突,若是版本同樣的狀況下, 檢查一下。)