keepalive簡單入門

解決了任務分發問題,那麼咱們能夠考慮下一個問題了,機器故障怎麼辦。首先考慮realsserver故障,咱們怎麼實時發現rs(realserver)的狀態,當檢測rs到故障後調度器怎麼修改調度規則。而後是考慮dr(director)故障,這就是大問題了一旦故障整個後端服務就所有不可用了,這裏我稱這種節點爲單點。本來的設計因爲故障致使漏洞百出,有人就引入了一個軟件keepalived,幫助lvs解決了單點問題,同時還提供了後端rs故障發現和處理機制。html

# 目錄node

高可用python

keepalivednginx

雙主模型的實踐web

多端口統一調度vim



# 高可用後端

這裏dr一直能夠就成爲高可用,仔細的考慮dr的特色,一是負責調度規則管理,二對外網提供訪問接口,這個訪問接口通常是一個ip。緩存

這裏引入一個概念,也是一個常識,服務可用率A=MTBF/(MTBF+MTTR)bash

MTBF #平均無端障時間,也就是服務器正常提供服務的時間服務器

MTTR #平均故障時間,服務器處於故障和維護的時間


提升A的方法有兩種一種是在保證MTTP不變的狀況下增大MBTF,這種方法經常是硬件級的提升方法,咱們可使用更貴的服務器,而且服務器每一個硬件都有一個冗餘處於熱備。這種方法須要硬件設計商介入,那麼就意味着成本會很是高,由於真正正在使用調度器數量不多,不能經過量產來平攤設計費用,那麼只能承擔硬件設計的高費用。這一種方法顯然不太靠譜。


還有就是減MTTR,這種方法首先咱們要認可一個前提——咱們容許機器故障,減少故障和維護時間那麼就有一個方案,就是準備一個和正在運行dr服務器同樣的服務器,時時等着dr掛掉當即頂替。既然是頂替那麼就會有問題,怎麼判斷dr掛掉了,讓dr實時向備用服務器發送心跳信息,備用服務器一旦收不到心跳信息,當即頂替。


備用dr服務器(backup)怎麼頂替dr(master),頂替dr意味着備用服務器要提供dr的所有功能,而且要繼承dr的提供的外網訪問接口。dr的功能好提供,只要backup服務器運行和master同樣服務提供一樣的配置文件就能夠了。下一項怎麼繼承dr的外網訪問接口,這裏咱們使用vrrp(虛擬路由協議)


vrrp,是多個硬件使用一個ip信息,其實同時只有一個設備可使用ip。這個協議的功能就是讓ip一直可用,一次工做流程。正常狀況master硬件佔有ip,而且不停向backup設備發送心跳信息,當master故障backup收不到心跳信息,backup就會發送arp報文問ip的mac地址是多少,而後本身回答ip的mac是本身的mac,這樣路由就會收到arp信息更新路由表。這樣就把ip搶過來了。




# keepalived

keepalived能夠說是爲lvs量身定製的高可用軟件,之因此這樣說是由於它主要有兩個核心模塊構成以下圖


wKioL1iNrwzT5Q4-AACEnxrS1kM787.jpg


其中vrrp Stack主要是爲了實現vrrp功能;Checkers是爲了實現監控後端服務器狀態的的模塊,當後端服務器故障能夠實時更改lvs規則,再也不向故障的後端服務器調度請求。



### keepalived配置文件的結構

GLOBAL CONFIGURATION

Global definitions

Static routes/addresses

VRRPD CONFIGURATION

VRRP synchronization group(s) #vrrp同步組;

VRRP instance(s) #每一個vrrp instance即一個vrrp路由器;

LVS CONFIGURATION

Virtual server group(s)

Virtual server(s) #ipvs集羣的vs和rs;



### 配置虛擬路由器:

vrrp_instance <STRING> {

....

}

state MASTER|BACKUP:當前節點在此虛擬路由器上的初始狀態;只能有一個是MASTER,餘下的都應該爲BACKUP;

interface IFACE_NAME:綁定爲當前虛擬路由器使用的物理接口;

virtual_router_id VRID:當前虛擬路由器的唯一標識,範圍是0-255;

priority 100:當前主機在此虛擬路徑器中的優先級;範圍1-254;

advert_int 1:vrrp通告的時間間隔;

authentication {

auth_type AH|PASS

auth_pass <PASSWORD>

}



### 虛擬服務器:

virtual_server IP port |

virtual_server fwmark int 

{

...

real_server {

...

}

...

}


經常使用參數:

delay_loop <INT>:服務輪詢的時間間隔;

lb_algo rr|wrr|lc|wlc|lblc|sh|dh:定義調度方法;

lb_kind NAT|DR|TUN:集羣的類型;

persistence_timeout <INT>:持久鏈接時長;

protocol TCP:服務協議,僅支持TCP;

sorry_server <IPADDR> <PORT>:備用服務器地址;

real_server <IPADDR> <PORT>

{

weight <INT>

notify_up <STRING>|<QUOTED-STRING>

notify_down <STRING>|<QUOTED-STRING>

HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... }:定義當前主機的健康狀態檢測方法;

}

HTTP_GET|SSL_GET:應用層檢測

HTTP_GET|SSL_GET {

url {

path <URL_PATH>:定義要監控的URL;

status_code <INT>:判斷上述檢測機制爲健康狀態的響應碼;

digest <STRING>:判斷上述檢測機制爲健康狀態的響應的內容的校驗碼;

}

nb_get_retry <INT>:重試次數;

delay_before_retry <INT>:重試以前的延遲時長;

connect_ip <IP ADDRESS>:向當前RS的哪一個IP地址發起健康狀態檢測請求

connect_port <PORT>:向當前RS的哪一個PORT發起健康狀態檢測請求

bindto <IP ADDRESS>:發出健康狀態檢測請求時使用的源地址;

bind_port <PORT>:發出健康狀態檢測請求時使用的源端口;

connect_timeout <INTEGER>:鏈接請求的超時時長;

}


TCP_CHECK {

connect_ip <IP ADDRESS>:向當前RS的哪一個IP地址發起健康狀態檢測請求

connect_port <PORT>:向當前RS的哪一個PORT發起健康狀態檢測請求

bindto <IP ADDRESS>:發出健康狀態檢測請求時使用的源地址;

bind_port <PORT>:發出健康狀態檢測請求時使用的源端口;

connect_timeout <INTEGER>:鏈接請求的超時時長;

}


# 雙主模型的實踐

wKiom1iNrsGhTdiUAACQZedCi-k947.png-wh_50


這裏我使用lvs的dr模型


### dr1和dr2的設置命令

兩臺主機keepalived的配置只有不多的一點不一樣,不一樣的時候我會標出,這裏以dr1的爲例

yum -y install keepalived httpd ipvsadm #安裝keepalived、httpd和ipvsadm,ipvsadm非必須的,是爲了方便咱們查看lvs的規則
vim keepalived.conf
! Configuration File for keepalived
global_defs { #全局配置
   notification_email {
        root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id node1
   vrrp_mcast_group4 224.0.29.29
}
vrrp_instance VI_1 { #第一個虛擬網絡配置
    #dr2的配置,state BACKUP 
    state MASTER
    interface eno16777736
    virtual_router_id 51
    #dr2的配置,priority 90
    priority 100 
    authentication {
        auth_type PASS
        auth_pass oldking1
    }
    virtual_ipaddress {
        172.16.29.3/16 dev eno16777736 label eno16777736:0
    }
}
#第二個虛擬網絡的配置
vrrp_instance VI_2 { 
#dr2的配置,state MASTER
    state BACKUP 
    interface eno16777736
    virtual_router_id 52
    #dr2的配置,priority 100
    priority 90 
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass oldking2
    }
    virtual_ipaddress {
        172.16.29.4/16 dev eno16777736 label eno16777736:1
    }
}
virtual_server 172.16.29.3 80 { #第一個虛擬網絡對應的服務配置
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.0.0
    protocol TCP
    sorry_server 127.0.0.1 80
    real_server 172.16.29.1 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 1
            nb_get_retry 1
            delay_before_retry 1
        }
    }
    real_server 172.16.29.2 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 1
            nb_get_retry 1
            delay_before_retry 1
        }
    }
}
virtual_server 172.16.29.4 80 { #第二個虛擬網絡對應的服務配置
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.0.0
    protocol TCP
    sorry_server 127.0.0.1 80
    real_server 172.16.29.1 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 1
            nb_get_retry 1
            delay_before_retry 1
        }
    }
    real_server 172.16.29.2 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 1
            nb_get_retry 1
            delay_before_retry 1
        }
    }
}
echo '<h1>dr1</h1>' > /var/www/html/index.html #提供網頁文件,rs2的話,執行echo '<h1>dr2</h1>' > /var/www/html/index.html
systemctl start keepalived.service
systemctl start httpd.service



### rs1和rs2服務器的配置

yum install httpd -y
vim setrs.sh #一鍵配置dr腳步
#!/bin/bash
#
vip=172.16.29.3
vip1=172.16.29.4
mask='255.255.255.255'
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 lo:0 $vip netmask $mask broadcast $vip up
    route add -host $vip dev lo:0
    ifconfig lo:1 $vip1 netmask $mask broadcast $vip1 up
    route add -host $vip1 dev lo:1
    ;;  
stop)
    ifconfig lo:0 down
    ifconfig lo:1 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 "Usage $(basename $0) start|stop"
    exit 1
    ;;
esac
bash -x setrs.sh
echo '<h1>rs1</h1>' > /var/www/html/index.html #提供網頁文件,rs2的話,執行echo '<h1>rs2</h1>' > /var/www/html/index.html
systemctl start httpd.service



# 多端口統一調度

首先使用iptables給某幾個端口的服務打上同一個標籤,大標籤的命令

iptables -t mangle -A PREROUTING -i eth2 -p tcp --dport 80 -j MARK --set-mark 20
iptables -t mangle -A PREROUTING -i eth2 -p tcp --dport 443 -j MARK --set-mark 20

而後再編輯keepalived配置文件

#這裏不使用ip加port直接使用以下配置
virtual_server fwmark 20 {
...
}




# nginx的雙主模型

架構圖和lvs雙主模型的如出一轍,只是把代理服務器更替爲nginx

yum install nginx keepalived
vim /etc/nginx/nginx.conf
#在全局配置段添加以下內容
    upstream web {
        server 172.16.29.1:80;
        server 172.16.29.2:80;
    } 
    #在server段更改location的配置以下
        location / { 
    proxy_pass http://web;
    }
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   notification_email {
        root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id node1
   vrrp_mcast_group4 224.0.29.29
#這個腳本是爲了維護後端服務器時使用的
    vrrp_script chk_down {
        script "[[ -f /etc/nginx/down ]] && exit 1 || exit 0"
        interval 1
        weight  -5
    }
#這個腳本是爲了檢測代理服務器Nginx的狀態
    vrrp_script chk_nginx {
        script "killall -0 nginx && exit 0 || exit 1"
        interval 1
        weight -20
    }
}
#第一個虛擬網絡配置
vrrp_instance VI_1 { 
    #dr2的配置,state BACKUP 
    state MASTER
    interface eno16777736
    virtual_router_id 51
    #dr2的配置,priority 90
    priority 100 
    authentication {
        auth_type PASS
        auth_pass oldking1
    }
    virtual_ipaddress {
        172.16.29.3/16 dev eno16777736 label eno16777736:0
    }
}
#第二個虛擬網絡的配置
vrrp_instance VI_2 { 
#dr2的配置,state MASTER
    state BACKUP 
    interface eno16777736
    virtual_router_id 52
    #dr2的配置,priority 100
    priority 90 
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass oldking2
    }
    virtual_ipaddress {
        172.16.29.4/16 dev eno16777736 label eno16777736:1
    }
}
#調用chk_down和chk_nginx的運行
    track_script {
        chk_down
        chk_nginx
    }
}


# 總結

keepalived的是很基本的服務,是咱們使用最多的高可用服務,由於它足夠輕量級而且可定製性很高,咱們能夠是keepalived調用咱們定義的python腳步實現高級功能,拿高可用nginx服務爲例子,備用節點的Nginx服務一直運行着,當主服務器故障,直接獲取主服務器的ip,而且向緩存服務器加載session就行了。

相關文章
相關標籤/搜索