關(guān)于Linux中Keepalived高可用熱備自動(dòng)化部署的一些筆記

寫(xiě)在前面
今天和小伙伴們分享一些 Keepalived 相關(guān)筆記
博文內(nèi)容涉及:
vrrp 協(xié)議由來(lái)
Ansible 方式 Keepalived安裝部署
Keepalived 腳本方式配置服務(wù)檢查
Keepalived 自動(dòng)化部署 Ansible 角色編寫(xiě)
食用方式:
需要 Linux、Ansible 基礎(chǔ)知識(shí)
理解不足小伙伴幫忙指正
「 勿忘國(guó)恥,銘記歷史」


官網(wǎng)幫助文檔:https://www.keepalived.org/manpage.html

「關(guān)于keepalived是什么,在官網(wǎng)中這樣描述」:

Keepalived 是一個(gè)用 C 語(yǔ)言編寫(xiě)的路由軟件。該項(xiàng)目的主要目標(biāo)是為 Linux 系統(tǒng)和基于 Linux 的基礎(chǔ)架構(gòu)提供簡(jiǎn)單而強(qiáng)大的負(fù)載平衡和高可用性設(shè)施。

負(fù)載平衡框架依賴(lài)于眾所周知且廣泛使用的Linux 虛擬服務(wù)器 (IPVS) 內(nèi)核模塊,提供第 4 層負(fù)載平衡。Keepalived 實(shí)現(xiàn)了一組檢查器,以根據(jù)其健康狀況動(dòng)態(tài)和自適應(yīng)地維護(hù)和管理負(fù)載平衡的服務(wù)器池。(本文不涉及)

高可用性是通過(guò) VRRP實(shí)現(xiàn)的協(xié)議。VRRP 是路由器故障轉(zhuǎn)移的基礎(chǔ)。此外,Keepalived 實(shí)現(xiàn)了一組與 VRRP 有限狀態(tài)機(jī)的掛鉤,提供低級(jí)和高速協(xié)議交互。為了提供最快的網(wǎng)絡(luò)故障檢測(cè),Keepalived 實(shí)現(xiàn)了BFD協(xié)議。VRRP 狀態(tài)轉(zhuǎn)換可以考慮 BFD 提示來(lái)驅(qū)動(dòng)快速狀態(tài)轉(zhuǎn)換。Keepalived 框架可以單獨(dú)使用,也可以一起使用,以提供彈性基礎(chǔ)架構(gòu)

「Keepalived 是免費(fèi)軟件;您可以根據(jù)自由軟件基金會(huì)發(fā)布的 GNU 通用公共許可條款重新分發(fā)和/或修改它;許可證的第 2 版,或(由您選擇)任何更高版本?!?br>
今天和小伙伴分享的主要是高可用熱備部署,關(guān)于負(fù)載均衡方面的之后和小伙伴們分享,在部署keepalived之前,需要了解下VRRP協(xié)議

vrrp協(xié)議由來(lái)
當(dāng)網(wǎng)關(guān)路由器出現(xiàn)故障時(shí),本網(wǎng)段內(nèi)以該設(shè)備為網(wǎng)關(guān)的主機(jī)都不能與 Internet 進(jìn)行通信。所以需要進(jìn)行容災(zāi)處理,但是通過(guò)部署多網(wǎng)關(guān)的方式實(shí)現(xiàn)網(wǎng)關(guān)的備份,存在一些問(wèn)題:網(wǎng)關(guān)間IP地址沖突;主機(jī)會(huì)頻繁切換網(wǎng)絡(luò)出口。所以為解決網(wǎng)關(guān)路由的單點(diǎn)故障,有了VRRP協(xié)議。

VRRP即虛擬路由冗余協(xié)議,VRRP能夠在不改變組網(wǎng)的情況下,從多臺(tái)網(wǎng)關(guān)設(shè)備里產(chǎn)生一個(gè)虛擬路由器,通過(guò)配置虛擬路由器的IP地址為默認(rèn)網(wǎng)關(guān),實(shí)現(xiàn)網(wǎng)關(guān)的備份。

對(duì)外提供網(wǎng)關(guān)服務(wù)的是這個(gè)虛擬路由器。這樣不管是真實(shí)路由器哪個(gè)出現(xiàn)問(wèn)題,都不會(huì)影響整個(gè)網(wǎng)絡(luò)的運(yùn)行,提高了網(wǎng)絡(luò)結(jié)構(gòu)的穩(wěn)定性。



路由器VRRP配置方式
配置VRRP的成員;
配置VRRP的優(yōu)先級(jí) (默認(rèn)100);
查看VRRP信息
VRRP協(xié)議通過(guò)一種競(jìng)選機(jī)制來(lái)將路由任務(wù)交給某個(gè)vrrp路由器的。

在VRRP物理結(jié)構(gòu)中,有多個(gè)物理的VRRP路由器,其中有一臺(tái)稱(chēng)為“master”(主節(jié)點(diǎn)路由器),其他的都是“backup”(備節(jié)點(diǎn)路由器)

在VRRP虛擬結(jié)構(gòu)中,虛擬路由都是通過(guò)MAC+VRID的形式來(lái)標(biāo)識(shí)的,如54-89-98-6F-3D-B5-{vrid}只有master節(jié)點(diǎn)才會(huì)發(fā)送VRRP包(vrrp advertisement message)當(dāng)master節(jié)點(diǎn)宕掉的時(shí)候,backup中優(yōu)先級(jí)最高的VRRP設(shè)備會(huì)搶占并升級(jí)為master

下面為配置的簡(jiǎn)單Demo

三層交換機(jī)SW1上配置, 主路由器(Master)

#三層交換機(jī)SW1上配置, 主路由器(Master)
<Huawei>system-view #進(jìn)入系統(tǒng)視圖
[Huawei]sysname SW1 #修改設(shè)備名字
[SW1]
[SW1]undo info-center enable #取消信息提示
#給vlan1配置網(wǎng)關(guān)
[SW1]interface Vlanif 1
[SW1-Vlanif1]ip address 192.168.1.252 255.255.255.0
#將三層交換機(jī)SW1配置為VRRP的成員,設(shè)置虛擬IP地址
[SW1-Vlanif1]vrrp vrid 1 virtual-ip 192.168.1.254
#配置VRRP的優(yōu)先級(jí),不寫(xiě)默認(rèn)為100
[SW1-Vlanif1]vrrp vrid 1 priority 105
[SW1-Vlanif1]
#查看VRRP配置信息
[SW1-Vlanif1]display vrrp brief
三層交換機(jī)SW2上配置,,備用路由器(backup)

#三層交換機(jī)SW2上配置,,備用路由器(backup)
<Huawei>system-view #進(jìn)入系統(tǒng)視圖
[Huawei]sysname SW2 #修改設(shè)備名字
[SW2]
[SW2]undo info-center enable #取消信息提示
#給vlan1配置網(wǎng)關(guān)
[SW2]interface Vlanif 1
[SW2-Vlanif1]ip address 192.168.1.253 255.255.255.0
#將三層交換機(jī)SW1配置為VRRP的成員,設(shè)置虛擬IP地址
[SW2-Vlanif1]vrrp vrid 1 virtual-ip 192.168.1.254
#不用設(shè)置優(yōu)先級(jí),默認(rèn)為100
#查看VRRP配置信息
[SW2-Vlanif1]display vrrp brief

keepalived 安裝部署
回到keepalived中,keepalived 通過(guò)VRRP(Virtual Router Redundancy Protocol)虛擬路由冗余協(xié)議來(lái)實(shí)現(xiàn)故障轉(zhuǎn)移。keepalived正常工作時(shí),主節(jié)點(diǎn)(master)會(huì)不斷的發(fā)送心跳信息給備節(jié)點(diǎn)(backup)

┌──[root@vms153.liruilongs.github.io]-[~]
└─$tcpdump -i  ens32 -nn host 224.0.0.18 #組播地址
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens32, link-type EN10MB (Ethernet), capture size 262144 bytes
23:27:36.149062 IP 192.168.26.153 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
23:27:37.150969 IP 192.168.26.153 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
23:27:38.152021 IP 192.168.26.153 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
┌──[root@vms153.liruilongs.github.io]-[~]
└─$
當(dāng)備節(jié)點(diǎn)在一定時(shí)間內(nèi)沒(méi)有收到主節(jié)點(diǎn)的心跳信息時(shí),備節(jié)點(diǎn)會(huì)認(rèn)為主節(jié)點(diǎn)宕了,就會(huì)接管主節(jié)點(diǎn)上的資源,并繼續(xù)向外提供服務(wù)保證其可用性,當(dāng)主節(jié)點(diǎn)恢復(fù)時(shí),備節(jié)點(diǎn)會(huì)自動(dòng)讓出資源并再次自動(dòng)成為備節(jié)點(diǎn)

這里我們通過(guò) ansible 安裝配置,下面的兩臺(tái)機(jī)器為我們要配置的機(jī)器,也就是node組,在master節(jié)點(diǎn)操作

192.168.26.153
192.168.26.154
┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat inventory
[master]
192.168.26.152
[node]
192.168.26.153
192.168.26.154
安裝web服務(wù)測(cè)試用

┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible node -m shell -a "yum -y install httpd"
編寫(xiě)一個(gè)小劇本用于環(huán)境初始化,這個(gè)劇本實(shí)現(xiàn)對(duì)httpd服務(wù)的歡迎頁(yè)進(jìn)行內(nèi)容填充,重啟服務(wù),設(shè)置防火墻域?yàn)閠rusted,即沒(méi)有規(guī)則

┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat httpd.yaml
---
- name: httpd init
  hosts: node
  tasks:
    - name: httpd content
      shell: "echo `hostname` > /var/www/html/index.html"
    - name: Restart service httpd, in all cases
      service:
        name: httpd
        state: restarted
    - name: firewall
      shell: firewall-cmd --set-default-zone=trusted
┌──[root@vms152.liruilongs.github.io]-[~]
└─$
執(zhí)行劇本并測(cè)試填充結(jié)果測(cè)試

┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible-playbook httpd.yaml
........
┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible node -m shell -a 'hostname;cat /var/www/html/index.html'
192.168.26.154 | CHANGED | rc=0 >>
vms154.liruilongs.github.io
vms154.liruilongs.github.io
192.168.26.153 | CHANGED | rc=0 >>
vms153.liruilongs.github.io
vms153.liruilongs.github.io
安裝 keepalived,我們使用的版本為:keepalived-1.3.5-19.el7.x86_64

┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible node -m yum -a 'name=keepalived state=installed'
192.168.26.154 | SUCCESS => {
。。。。。。
編輯配置文件模板,把主備節(jié)點(diǎn)配置文件中不一樣的,或者希望單獨(dú)設(shè)置的內(nèi)容做成變量

┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat keepalived.conf.j2
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL #設(shè)置路由ID,可以和主機(jī)名相同,也可以隨便定義
   vrrp_iptables       #手動(dòng)添加(禁止設(shè)置防火墻規(guī)則,keepalved每次啟動(dòng)都會(huì)自動(dòng)添加防火墻拒絕所有的規(guī)則)
}

vrrp_instance VI_1 {
    state {{ role }}
    interface ens32 #定義網(wǎng)絡(luò)接口,根據(jù)自己虛擬機(jī)上的網(wǎng)卡修改
    virtual_router_id 51  #主備服務(wù)器VRID號(hào)必須保持一致
    priority {{ priority }} #服務(wù)器優(yōu)先級(jí),優(yōu)先級(jí)高則優(yōu)先獲得浮動(dòng)IP
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.26.200
    }
}
編寫(xiě)劇本,復(fù)制模板文件,然后重啟keepalived服務(wù),這里我們通過(guò)兩個(gè)小劇本的方式傳遞不同的變量






┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat keepalived.yaml
---
- name: vms153.liruilongs.github.io config
  hosts: 192.168.26.153
  tags:
    - master
  vars:
    role: MASTER
    priority: 100
  tasks:
    - name: copy keeplived config
      template:
        src: keepalived.conf.j2
        dest: /etc/keepalived/keepalived.conf

    - name: restart keeplived
      service:
        name: keepalived
        state: restarted


- name: vms154.liruilongs.github.io config
  hosts: 192.168.26.154
  tags:
    - backup
  vars:
    role: BACKUP
    priority: 50
  tasks:
    - name: copy keepalived config
      template:
        src: keepalived.conf.j2
        dest: /etc/keepalived/keepalived.conf

    - name: restart keepalived
      service:
        name: keepalived
        state: restarted

運(yùn)行劇本并測(cè)試

┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible-playbook keepalived.yaml
。。。。。。。。。。。
假設(shè)153機(jī)器應(yīng)為某些原因,需要進(jìn)行停機(jī)處理,我們可以直接把 keepalived 干掉,vip自動(dòng)切到154

┌──[root@vms152.liruilongs.github.io]-[~]
└─$curl 192.168.26.200:80
vms153.liruilongs.github.io
┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible 192.168.26.153 -m shell -a "systemctl stop keepalived"
192.168.26.153 | CHANGED | rc=0 >>

┌──[root@vms152.liruilongs.github.io]-[~]
└─$curl 192.168.26.200:80
vms154.liruilongs.github.io
┌──[root@vms152.liruilongs.github.io]-[~]
└─$
如果這個(gè)時(shí)候153機(jī)器恢復(fù),那么我們可以重新拉起keepalived服務(wù),vip回到153

┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible 192.168.26.153 -m shell -a "systemctl start keepalived"
192.168.26.153 | CHANGED | rc=0 >>

┌──[root@vms152.liruilongs.github.io]-[~]
└─$curl 192.168.26.200:80
vms153.liruilongs.github.io
上面的操作,我們可以整合到一個(gè)劇本里

┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat keepalived.yaml
---
- name:  keepalived init
  hosts: node
  tasks:
    - name: install
      yum:
        name:
          - httpd
          - keepalived
        state: installed

    - name: httpd content
      shell: "echo `hostname` > /var/www/html/index.html"
    - name: Restarted  httpd
      service:
        name: httpd
        state: restarted

    - name: firewall clons
      shell: firewall-cmd --set-default-zone=trusted
# 主機(jī)配置
- name: vms153.liruilongs.github.io config
  hosts: 192.168.26.153
  tags:
    - master
  vars:
    role: MASTER
    priority: 100
    vip: 192.168.26.200
    interface: ens32
  tasks:
    - name: copy keeplived config
      template:
        src: keepalived.conf.j2
        dest: /etc/keepalived/keepalived.conf
    - name: restart keepalived
      service:
        name: keepalived
        state: restarted
# 備機(jī)配置
- name: vms154.liruilongs.github.io config
  hosts: 192.168.26.154
  tags:
    - backup
  vars:
    role: BACKUP
    priority: 90
    vip: 192.168.26.200
    interface: ens32
  tasks:
    - name: copy keepalived config
      template:
        src: keepalived.conf.j2
        dest: /etc/keepalived/keepalived.conf
    - name: restart keepalived
      service:
        name: keepalived
        state: restarted    
對(duì)于配置文件也可以更靈活一點(diǎn)

┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat keepalived.conf.j2
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL #設(shè)置路由ID,可以和主機(jī)名相同,也可以隨便定義
   vrrp_iptables       #手動(dòng)添加(禁止設(shè)置防火墻規(guī)則,keepalved每次啟動(dòng)都會(huì)自動(dòng)添加防火墻拒絕所有的規(guī)則)
}

vrrp_instance VI_1 {
    state {{ role }}
    interface {{ interface }} #定義網(wǎng)絡(luò)接口,根據(jù)自己虛擬機(jī)上的網(wǎng)卡修改
    virtual_router_id 51  #主備服務(wù)器VRID號(hào)必須保持一致
    priority {{ priority }} #服務(wù)器優(yōu)先級(jí),優(yōu)先級(jí)高則優(yōu)先獲得浮動(dòng)IP
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        {{ vip }}
    }
}
有小伙伴會(huì)講,這也太水了,每次故障都需要自己去進(jìn)行主備切換,其實(shí)上面的配置為keepalived的最簡(jiǎn)單配置,沒(méi)有使用keepalived 的檢查配置,,告警等其他的功能。

如果是IPVS使用keepalived,可以對(duì)后端RealServer進(jìn)行健康狀況檢查,支持網(wǎng)絡(luò)層、傳輸層、應(yīng)用層進(jìn)行健康檢查。

配置文件解析
熟悉下配置文件,keepalived的配置文件主要由3部分構(gòu)造,ipvs配置,全局配置,VRRP配置。

# 全局配置(全局配置有Global definitions和Static routes/address,全局定義和靜態(tài)路由)
     global_defs                
         {
            ...
         }
        
# 配置vrrp實(shí)例(VRRP實(shí)例和VRRP同步組)
# vrrp instance                  # 虛擬路由器,VRRP實(shí)例
     vrrp_instance  NAME {
          ...
     }
# vrrp synchronization group     # VRRP同步組
     vrrp_sync_group  NAME  {
          ...
     }
# ipvs的相關(guān)配置
# LVS CONFIGURATION:
     # 集群服務(wù),服務(wù)內(nèi)的RS
     Virtual server groups
     Virtual server               #ipvs集群的vs和rs
下面為具體的參數(shù)解釋

┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
# 全局配置(全局配置有Global definitions和Static routes/address,全局定義和靜態(tài)路由)
global_defs {
  # 全局部分定義郵件報(bào)警系統(tǒng),定義郵件發(fā)送目標(biāo),收件人郵箱地址
   notification_email {  
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   # 定義發(fā)件人郵箱地址
   notification_email_from Alexandre.Cassen@firewall.loc
   # 定義郵件發(fā)送服務(wù)器IP,本地發(fā)送寫(xiě)localhost
   smtp_server 192.168.200.1
   # 定義郵件服務(wù)器建立連接的超時(shí)時(shí)長(zhǎng)
   smtp_connect_timeout 30
   # 標(biāo)識(shí)keepalived服務(wù)器的字符串,物理節(jié)點(diǎn)的標(biāo)識(shí)符;
   router_id LVS_DEVEL
   # 如果通告與接收的上一個(gè)通告來(lái)自相同的master路由器,則不執(zhí)行檢查
   vrrp_skip_check_adv_addr
   # 嚴(yán)格遵守VRRP協(xié)議,這一項(xiàng)最好關(guān)閉(加感嘆號(hào)),若不關(guān)閉,可用vip無(wú)法被ping通
   ! vrrp_strict
   # 在一個(gè)接口發(fā)送的兩個(gè)免費(fèi)ARP之間的延遲,可以精確到毫秒級(jí)(默認(rèn)是0)
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   # IPV4多播地址,默認(rèn)224.0.0.18
   vrrp_mcast_group4 225.0.0.18
}

# 檢查調(diào)用
vrrp_script  <SCRIPT_NAME>  {          # 腳本名,后面要基于腳本名來(lái)進(jìn)行調(diào)用
        script  "/etc/keepalived/chk_script.sh"   # 執(zhí)行的命令或腳本
        interval  INT          # 每隔多少時(shí)間,這個(gè)監(jiān)控腳本要執(zhí)行一次
        weight   -INT          # 失敗了,當(dāng)前節(jié)點(diǎn)的權(quán)重要減去多少,對(duì)于“weight”值的設(shè)置,有一個(gè)簡(jiǎn)單的標(biāo)準(zhǔn),即“weight”值的絕對(duì)值要大于Master和Backup節(jié)點(diǎn)“priority”值之差
}


# 虛擬路由器,VRRP實(shí)例
vrrp_instance VI_1 {
    # 定義實(shí)例的角色狀態(tài)是master還是backup,在當(dāng)前VRRP實(shí)例中此節(jié)點(diǎn)的初始狀態(tài)
    state MASTER
    # 定義vrrp綁定的接口,即接收或發(fā)送心跳通告的接口,即HA監(jiān)測(cè)接口
    interface eth0
    # 虛擬路由標(biāo)識(shí)(VRID),同一實(shí)例該數(shù)值必須相同,即master和backup中該值要相同
    virtual_router_id 51
    # 該vrrp實(shí)例中本機(jī)的keepalived的優(yōu)先級(jí),優(yōu)先級(jí)最高的為master(可用范圍0-255)
    # 該選項(xiàng)的優(yōu)先級(jí)高于state選項(xiàng),
    # 即若state指定的是backup,但這里設(shè)置的值最高,則仍為master
    priority 100
    # 心跳信息發(fā)送和接收時(shí)間間隔,單位為秒
    advert_int 1
     # 認(rèn)證方式,同一實(shí)例中這個(gè)配置必須完全一樣才可通過(guò)認(rèn)證,只建議使用PASS認(rèn)證
    authentication {
        # 使用簡(jiǎn)單字符認(rèn)證的方式
        auth_type PASS
        # 最多支持8字符,超過(guò)8字符將只取前8字符
        auth_pass 1111
    }
    # 設(shè)置的VIP,當(dāng)master出現(xiàn)故障后,VIP會(huì)故障轉(zhuǎn)移到backup
    virtual_ipaddress {
       # 一般情況下我們只設(shè)置一個(gè)VIP地址,也可以設(shè)置多個(gè)
       # 這些vip默認(rèn)配置在interface指定的接口別名上,可使用dev選項(xiàng)來(lái)指定網(wǎng)卡: 192.168.200.19/24 dev eth1
       # 使用ip add的方式添加,若要被ifconfig查看,在IP地址后加上label即可
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }

    # 調(diào)用檢查    
    track_script {
        chk_service
    }

    # 使用非搶占模式
    nopreempt   
    #非搶占式:如果backup路由器工作在此模式下,則若Master路由器沒(méi)有出現(xiàn)故障,backup即使隨后被配置了更高的優(yōu)先級(jí)也不會(huì)成為Master     
    
    # 使用延遲搶占模式
    preempt_delay  TIME
    #搶占式:如果backup路由器工作在搶占方式下,當(dāng)它收到VRRP報(bào)文后,會(huì)將主機(jī)的優(yōu)先級(jí)與通告報(bào)文中的優(yōu)先級(jí)進(jìn)行比較,如果主機(jī)的優(yōu)先級(jí)比當(dāng)前的Master路由器的優(yōu)先級(jí)高,就會(huì)主動(dòng)搶占成為Master路由器,否則,將保持Backup狀態(tài)

    notify_master  <STRING>|<QUOTED-STRING>  # 當(dāng)切換到master模式時(shí),執(zhí)行此腳本
    notify_backup  <STRING>|<QUOTED-STRING>  # 當(dāng)切換到backup模式時(shí),執(zhí)行此腳本
    notify_fault  <STRING>|<QUOTED-STRING>   # 當(dāng)切換到fault模式時(shí),執(zhí)行此腳本
    notify  <STRING>|<QUOTED-STRING>

}
服務(wù)檢查
在上面的Demo的基礎(chǔ)上,我們添加一個(gè)檢查腳本,使用下面的檢查策略。來(lái)檢查httpd服務(wù)是否可用

┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl status httpd > /dev/null
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$echo $?
0
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl stop httpd.service
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl status httpd > /dev/null
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$echo $?
3
也可以這樣

┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl is-active  httpd  -q
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$echo $?
3
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl start  httpd
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl is-active  httpd  -q
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$echo $?
0
或者這樣

┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl show httpd -p ActiveState
ActiveState=active
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl show httpd -p ActiveState | sed 's/ActiveState=//g'
active
是否運(yùn)行和是否活躍是兩個(gè)概念,對(duì)于某些一次性服務(wù)可以使用下面的方式驗(yàn)證

┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl show httpd -p ActiveState | cut -d'=' -f2
active
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$systemctl show httpd -p SubState | cut -d'=' -f2
running
┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$
keepalived部署服務(wù)健康檢查劇本






┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat keepaliveds.yaml
---
- name:  keepalived init
  hosts: node
  tasks:
    - name: install
      yum:
        name:
          - httpd
          - keepalived
        state: installed

    - name: httpd content
      shell: "echo `hostname` > /var/www/html/index.html"

    - name: Restarted  httpd
      service:
        name: httpd
        state: restarted

    - name: firewall clons
      shell: firewall-cmd --set-default-zone=trusted
# 主機(jī)配置
- name: vms153.liruilongs.github.io config
  hosts: 192.168.26.153
  tags:
    - master
  vars:
    role: MASTER
    priority: 100
  tasks:
    - name: copy keeplived config
      template:
        src: keepalived.conf.j2
        dest: /etc/keepalived/keepalived.conf
    - name: copy che_service
      copy:
        content: "#!/bin/sh\nsystemctl is-active  httpd  -q"
        dest: /etc/keepalived/che_service.sh
        backup: yes
        mode: '0755'
    - name: restart keepalived
      service:
        name: keepalived
        state: restarted

# 備機(jī)配置
- name: vms154.liruilongs.github.io config
  hosts: 192.168.26.154
  tags:
    - backup
  vars:
    role: BACKUP
    priority: 90
  tasks:
    - name: copy keepalived config
      template:
        src: keepalived.conf.j2
        dest: /etc/keepalived/keepalived.conf
    - name: copy che_service
      copy:
        content: "#!/bin/sh\nsystemctl is-active  httpd  -q"
        dest: /etc/keepalived/che_service.sh
        mode: '0755'
        backup: yes
    - name: restart keepalived
      service:
        name: keepalived
        state: restarted
運(yùn)行測(cè)試

┌──[root@vms152.liruilongs.github.io]-[~]
└─$curl 192.168.26.200
vms153.liruilongs.github.io
┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible 192.168.26.153 -m service -a 'name=httpd state=stopped'
192.168.26.153 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "name": "httpd",
    "state": "stopped",
  .............
┌──[root@vms152.liruilongs.github.io]-[~]
└─$curl 192.168.26.200
vms154.liruilongs.github.io
┌──[root@vms152.liruilongs.github.io]-[~]
└─$
配置文件模板

┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat keepalived.conf.j2
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL #設(shè)置路由ID,可以和主機(jī)名相同,也可以隨便定義
   vrrp_iptables       #手動(dòng)添加(禁止設(shè)置防火墻規(guī)則,keepalved每次啟動(dòng)都會(huì)自動(dòng)添加防火墻拒絕所有的規(guī)則)
}

vrrp_script chk_service {
    script /etc/keepalived/che_service.sh
    interval 2
}

vrrp_instance VI_1 {
    state {{ role }}
    interface ens32 #定義網(wǎng)絡(luò)接口,根據(jù)自己虛擬機(jī)上的網(wǎng)卡修改
    virtual_router_id 51  #主備服務(wù)器VRID號(hào)必須保持一致
    priority {{ priority }} #服務(wù)器優(yōu)先級(jí),優(yōu)先級(jí)高則優(yōu)先獲得浮動(dòng)IP
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.26.200
    }

    track_script {
        chk_service
    }
}
這個(gè)劇本調(diào)了好些時(shí)間,需要注意的是,配置文件不能有其他的非空格的字符,檢查腳本要記得授權(quán),如果沒(méi)有執(zhí)行檢查腳本,可以看下 /var/log/messages 日志文件

┌──[root@vms153.liruilongs.github.io]-[/etc/keepalived]
└─$cat /var/log/messages | grep -C 10 track
keepalived 角色編寫(xiě)
我們也可以把上面的劇本編寫(xiě)為角色,需要把handlers和和其他的東西抽出來(lái)

┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible-galaxy init keepalived --init-path=./roles
- Role keepalived was created successfully
┌──[root@vms152.liruilongs.github.io]-[~]
└─$ansible-galaxy list
# /root/roles
- keepalived, (unknown version)
┌──[root@vms152.liruilongs.github.io]-[~]
└─$
編寫(xiě)task

┌──[root@vms152.liruilongs.github.io]-[~/roles/keepalived]
└─$cat tasks/main.yml
---
# tasks file for keepalived

# 安裝 keepalived
- name: Install keepalived
  yum:
    name: keepalived
    state: latest
  tags: keepalived
  notify: restart keepalived

# copy 配置文件
- name: Keepalived configuration
  template:
    src: keepalived.conf.j2
    dest: /etc/keepalived/keepalived.conf
  notify: restart keepalived
# copy 檢查腳本
- when:  check_service_name | default(False)
  name: Install check script
  copy:
    content: "#!/bin/sh\nsystemctl is-active  {{ check_service_name }}  -q"
    dest: /etc/keepalived/che_service.sh
    backup: yes
    mode: 0755
    owner: root
    group: root
  notify: restart keepalived

# 啟動(dòng) 服務(wù)
- name: Start keepalived
  service:
    name: keepalived
    state: started
    enabled: yes
編寫(xiě)handlers

┌──[root@vms152.liruilongs.github.io]-[~/roles/keepalived]
└─$cat handlers/main.yml
---
# handlers file for keepalived

- name: restart keepalived
  service:
    name: keepalived
    state: restarted
┌──[root@vms152.liruilongs.github.io]-[~/roles/keepalived]
└─$
編寫(xiě)template

┌──[root@vms152.liruilongs.github.io]-[~/roles/keepalived]
└─$cat templates/keepalived.conf.j2
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL #設(shè)置路由ID,可以和主機(jī)名相同,也可以隨便定義
   vrrp_iptables       #手動(dòng)添加(禁止設(shè)置防火墻規(guī)則,keepalved每次啟動(dòng)都會(huì)自動(dòng)添加防火墻拒絕所有的規(guī)則)
}

vrrp_script chk_service {
    script /etc/keepalived/che_service.sh
    interval 2
}

vrrp_instance VI_1 {
    state {{ keep_role }}
    interface {{ keep_interface }} #定義網(wǎng)絡(luò)接口,根據(jù)自己虛擬機(jī)上的網(wǎng)卡修改
    virtual_router_id 51  #主備服務(wù)器VRID號(hào)必須保持一致
    {% if keep_role.lower() == 'master' %}
    priority {{ keep_priority }}
    {% else %}
    priority {{ keep_backup_priority }}
    {% endif %}
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        {{ virtual_ipaddress }} dev {{ keep_interface }}
    }

    track_script {
        chk_service
    }
}
┌──[root@vms152.liruilongs.github.io]-[~/roles/keepalived]
└─$
編寫(xiě)defaults變量

┌──[root@vms152.liruilongs.github.io]-[~/roles/keepalived]
└─$cat defaults/main.yaml
---

keep_role: "master"
keep_priority: 100
keep_backup_priority: 50
keep_interface: "ens32"
virtual_ipaddress: "192.168.26.200"
check_service_name: httpd

編寫(xiě)調(diào)用劇本

┌──[root@vms152.liruilongs.github.io]-[~/roles/keepalived]
└─$cat tests/test.yml
---
- hosts: 192.168.26.153
  vars:
    keep_role: MASTER
  roles:
    - keepalived

- hosts: 192.168.26.154
  vars:
    keep_role: BACKUP
  roles:
    - keepalived
┌──[root@vms152.liruilongs.github.io]-[~/roles/keepalived]
└─$
博文參考
https://www.keepalived.org/manpage.html

https://www.cnblogs.com/hgzero/p/13718516.html

https://unix.stackexchange.com/questions/396630/the-proper-way-to-test-if-a-service-is-running-in-a-script

https://github.com/tcomerma/ansible-keepalived/

https://github.com/demis-svenska/aws-echis/tree/master/src/commcare_cloud/ansible/roles/keepalived

作者:山河已無(wú)恙


歡迎關(guān)注微信公眾號(hào) :山河已無(wú)恙