天天看點

Linux 高可用(HA)叢集之keepalived+lvs

一:前言

  Keepalived使用的vrrp協定方式,虛拟路由備援協定 (Virtual Router Redundancy Protocol,簡稱VRRP);Keepalived的目的是模拟路由器的高可用,一般Keepalived是實作前端高可用,常用的前端高可用的組合有,就是我們常見的LVS+Keepalived、Nginx+Keepalived、HAproxy+Keepalived。總結一下,Keepalived中實作輕量級的高可用,一般用于前端高可用,且不需要共享存儲,一般常用于兩個節點的高可用。

  提到高可用我們再來把Heartbeat、Corosync、Keepalived這三個叢集元件互相比較一下.

Linux 高可用(HA)叢集之keepalived+lvs

二:keepalived

    Keepalived 是一個基于VRRP協定來實作的LVS服務高可用方案,可以利用其來避免單點故障。一個LVS服務會有2台伺服器運作Keepalived,一台為主伺服器(MASTER),一台為備份伺服器(BACKUP),但是對外表現為一個虛拟IP,主伺服器會發送特定的消息給備份伺服器,當備份伺服器收不到這個消息的時候,即主伺服器當機的時候, 備份伺服器就會接管虛拟IP,繼續提供服務,進而保證了高可用性。

    在路由器上配上靜态路由就會産生單點故障,那該怎麼辦呢?VRRP就應用而生了,VRRP通過一競選(election)協定來動态的将路由任務交給LAN中虛拟路由器中的某台VRRP路由器.

     VRRP工作原理, 在一個VRRP虛拟路由器中,有多台實體的VRRP路由器,但是這多台的實體的機器并不能同時工作,而是由一台稱為MASTER的負責路由工作,其它的都是BACKUP,MASTER并非一成不變,VRRP讓每個VRRP路由器參與競選,最終獲勝的就是MASTER。MASTER擁有一些特權,比如,擁有虛拟路由器的IP位址,我們的主機就是用這個IP位址作為靜态路由的。擁有特權的MASTER要負責轉發發送給網關位址的包和響應ARP請求。

       VRRP通過競選協定來實作虛拟路由器的功能,所有的協定封包都是通過IP多點傳播(multicast)包(多點傳播位址224.0.0.18)形式發送的。虛拟路由器由VRID(範圍0-255)和一組IP位址組成,對外表現為一個周知的MAC位址。是以,在一個虛拟路由 器中,不管誰是MASTER,對外都是相同的MAC和IP(稱之為VIP)。用戶端主機并不需要因為MASTER的改變而修改自己的路由配置,對用戶端來說,這種主從的切換是透明的。

       在一個虛拟路由器中,隻有作為MASTER的VRRP路由器會一直發送VRRP通告資訊(VRRPAdvertisement message),BACKUP不會搶占MASTER,除非它的優先級(priority)更高。當MASTER不可用時(BACKUP收不到通告資訊), 多台BACKUP中優先級最高的這台會被搶占為MASTER。這種搶占是非常快速的(<1s),以保證服務的連續性。由于安全性考慮,VRRP包使用了加密協定進行加密

三:為什麼要用keepalived+lvs

  lvs是一個在四層上實作後端realserver的負載均衡的叢集,lvs遺留下兩個問題,一個是lvs的單點故障;第二個是lvs不能檢測後端realserver的健康狀态檢查。

解決lvs的單點故障就用到了高可用叢集:

①、可以是heartbeat+ldirectord這種重量級的;

②、可以是keepalived+lvs這種輕量級的解決方案。(本部落客要寫keepalived+lvs輕量級的解決方案),

解決lvs不能檢測後端realserver的健康狀态也後很多種方法:

①、可以在lvs上寫腳本ping後端realserver的ip位址,ping幾次發現ip位址ping不通則在ipvs規則裡面删除,當後端伺服器可以ping了,則把後端realserver添加到ipvs規則裡面。

②、可以在lvs上寫腳本請求後端realserver的測試幾次網頁檔案,檢視狀态碼是否為200,不是則在ipvs規則裡面清楚,當測試網頁傳回的狀态嗎是200之後,則把後端realserver添加到ipvs規則裡面

③、以上兩種方法都是依賴于腳本,keepalived的出現解決了不依賴于腳本,也可以對後端realserver的健康狀态檢查,keepalived的配置檔案裡面可以自行生成ipvs的規則,并且自行檢測後端realserver的狀态,當後端realserver不能提供服務了,keepalived會自行将其在ipvs規則裡面删除,當後端realserver可以提供服務了,又自行的在ipvs規則裡面添加。

三:配置keepalived實作HTTP高可用

1) 環境準備

CentOS 6.5 X86_64

ipvsadm.x86_64 0:1.25-10.el6                  

keepalived.x86_64 0:1.2.7-3.el6      

httpd-2.2.15-29.el6.centos.x86_64

2)試驗拓撲圖

Linux 高可用(HA)叢集之keepalived+lvs

 試驗拓撲圖中VIP為172.16.16.7.節點node1為172.16.16.1,節點node2為172.16.16.5

3)配置master

vim /etc/keepalived/keepalived.conf
global_defs
 {
     notification_email
         {
           [email protected]                    #接收郵件位址
         }
    notification_email_from [email protected]  #發送郵件位址
    smtp_connect_timeout 3
    smtp_server 127.0.0.1
    router_id LVS_DEVEL
}
vrrp_script chk_mantaince_down {                           #定義檢測機制
   script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
   interval 1     #每個多長時間檢測一次
   weight -2      #當在/etc/keepalived/下建立一個down檔案時執行下面的指令權重減2.
   fall     3     #從正常到失敗檢測幾次完成 
   raise  3       #從失敗到正常需要檢測幾次
   
}
vrrp_instance VI_1 {
interface eth1
state MASTER # BACKUP for slave routers          #當在被節點上修改為BACKUP
priority 101 # 100 for BACKUP                    #被節點的priority數值要小于主節點
virtual_router_id 16                             #主機routeID,
garp_master_delay 1                           
authentication {
auth_type PASS
auth_pass password                               #輸入驗證密碼
}
track_interface {
eth0                                             #配置IP位址所在的網卡
}
virtual_ipaddress {
172.16.16.7/16 dev eth0 label eth0:0             #配置的IP位址
}
track_script {                                   #調用檢測機制
chk_mantaince_down            
}
notify_master "/etc/rc.d/init.d/httpd start"     # 當成為master時就啟動http服務
notify_backup "/etc/rc.d/init.d/httpd stop"      # 當成為backup時就關閉http服務
notify_fault "/etc/rc.d/init.d/httpd stop"
}      

4)将配置檔案同步到slave

scp /etc/keepalived/keepalived.conf [email protected]:/etc/keepalived/
修改配置檔案
global_defs
 {
     notification_email
         {
           [email protected]                         #接收郵件位址
         }
    notification_email_from [email protected]  #發送郵件位址
    smtp_connect_timeout 3
    smtp_server 127.0.0.1
    router_id LVS_DEVEL
}
vrrp_script chk_mantaince_down {                           #定義檢測機制
   script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
   interval 1     #每個多長時間檢測一次
   weight -2      #當在/etc/keepalived/下建立一個down檔案時執行下面的指令權重減2.
   fall     3     #從正常到失敗檢測幾次完成 
   raise  3       #從失敗到正常需要檢測幾次
   
}
vrrp_instance VI_1 {
interface eth1
state BACKUP # BACKUP for slave routers          #此處修改為BACKUP
priority 100 # 100 for BACKUP                    #此處修改為100
virtual_router_id 16                             #主機routeID,
garp_master_delay 1                           
authentication {
auth_type PASS
auth_pass password                               #輸入驗證密碼
}
track_interface {
eth0                                             #配置IP位址所在的網卡
}
virtual_ipaddress {
172.16.16.7/16 dev eth0 label eth0:0             #配置的IP位址
}
track_script {                                   #調用檢測機制
chk_mantaince_down            
}
notify_master "/etc/rc.d/init.d/httpd start"     # 當成為master時就啟動http服務
notify_backup "/etc/rc.d/init.d/httpd stop"      # 當成為backup時就關閉http服務
notify_fault "/etc/rc.d/init.d/httpd stop"
}      

5)啟動keepalive

[root@node1 ~]# service keepalived start  
正在啟動 keepalived:                                      [确定]
[root@node2 ~]# service keepalived start  
正在啟動 keepalived:                                      [确定]      

四:keepalive+lvs 實作LVS雙主高可用

1)試驗拓撲圖

Linux 高可用(HA)叢集之keepalived+lvs

2)配置RIP1服務

 因為RIP伺服器配置的有VIP位址是以外面有請求VIP時他也會進行相應,而我們這裡是為了實作DR轉發,不能讓他進行響應,我們需要對RIP的端口資訊進行隐藏。
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore  #忽略其他端口發來的請求資訊
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce #不廣播自己的端口資訊
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce  
ifconfig eth0 192.168.16.2/24 up
ifconfig lo:0 172.16.16.7 netmask 255.255.255.255 broadcast 172.16.16.7
route add -host 172.16.16.7 dev lo:0  響應的資訊通過lo:0端口 ,為了使響應的IP位址為VI
ifconfig lo:1 172.16.16.8 netmask 255.255.255.255 broadcast 172.16.16.8
route add -host 172.16.16.8 dev lo:1      

3)配置RIP2服務

echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore  #忽略其他端口發來的請求資訊
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce #不廣播自己的端口資訊
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce  
ifconfig eth0 192.168.16.3/24 up
ifconfig lo:0 172.16.16.7 netmask 255.255.255.255 broadcast 172.16.16.7
route add -host 172.16.16.7 dev lo:0  響應的資訊通過lo:0端口 ,為了使響應的IP位址為VI
ifconfig lo:1 172.16.16.8 netmask 255.255.255.255 broadcast 172.16.16.8
route add -host 172.16.16.8 dev lo:1      
global_defs 
{ 
   notification_email 
        {
          [email protected]@126.com
          }
           notification_email_from [email protected]
           smtp_connect_timeout 3smtp_server 127.0.0.1
           router_id LVS_DEVEL
 }
vrrp_script chk_schedown 
 { 
      script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
                                                             #建立down檔案權重減2
      interval 2
      weight -2
  }
vrrp_instance VI_1
 { 
        interface eth0          
         state MASTER  #此節點為主節點          
         priority 101          
         virtual_router_id 51           
         garp_master_delay 1
         
         
 authentication 
  {         
       auth_type PASS        
       auth_pass password               
   }
 track_interface 
   { 
        eth0                          
    } 

 virtual_ipaddress 
   { 
       172.16.16.7/16 dev eth0 label eth0:0 #配置對外的VIP位址                               } 

 track_script 
    { 
         chk_schedown 
           } 
} 
vrrp_instance VI_2
 { 
          interface eth0
          state BACKUP           #此節點為被節點
          priority 100
          virtual_router_id 50
           garp_master_delay 1
authentication {      
          auth_type PASS
         auth_pass 12345678
                }

track_interface { 
         eth0
                          } 

virtual_ipaddress { 
            172.16.16.8/16 dev eth0 label eth0:1 #配置對外的VIP位址
                              } 

track_script { 
                       chk_schedown 
                    } 
} 

virtual_server 172.16.16.7 80  #配置一個VIP 工作在TCP的80端口上 
 {                 
               
    delay_loop 6 #lb_algo rr #負載均衡的排程算法
    lb_kind DR #工作在DR模型上
    persistence_timeout 50 #是否啟用IPVS持久連接配接
    protocol TCP  #采用的是TCP協定
    # sorry_server 192.168.16.2 1358 #所有服務挂了 ,出現的提示頁面.要在這台伺服器上開啟http服務 
real_server 192.168.16.2 80      #後面RIP位址
 { 
      weight 1 #權重
      HTTP_GET 
      {
          url 
              {         
                 path /    
                 status_code 200 #取得首頁面的狀态,狀态碼為200就意味着請求成功;也可寫入md5碼,但要制定靜态碼
               }
         connect_timeout 3 #每次測試3秒        
         nb_get_retry 3 #測試次數       
         delay_before_retry 3 #測試失敗在測試3次                         
      }
  } 

real_server 192.168.16.3 80 
    { 
                      weight 1 
   HTTP_GET 
        { 
           url
            { 
              path /
              status_code 200     
             }
                 connect_timeout 3nb_get_retry 3delay_before_retry 3    
         } 
     } 
} 
virtual_server 172.16.16.8 80  #配置一個VIP 工作在TCP的80端口上 
 {                 
               
       delay_loop 6 #
       lb_algo rr #負載均衡的排程算法
       lb_kind DR #工作在DR模型上
       #persistence_timeout 50 #是否啟用IPVS持久連接配接,這項要登出.連接配接50S才會切換
       protocol TCP  #采用的是TCP協定
       # sorry_server 192.168.16.2 1358 #所有服務挂了 ,出現的提示頁面.要在這台伺服器上開啟http服務
 
real_server 192.168.16.2 80          #後面RIP位址
 { 
    weight 1 #權重
        HTTP_GET
           {
              url 
                  {
                     path /
                     status_code 200 #取得首頁面的狀态,狀态碼為200就意味着請求成功;也可寫入md5碼,但要制定靜态碼
                    }
                   connect_timeout 3 #每次測試3秒
                    nb_get_retry 3 #測試次數
                    delay_before_retry 3 #測試失敗在測試3次
             }
 } 

real_server 192.168.16.3 80 
  { 
              weight 1 
HTTP_GET 
         { 
           url 
               { 
                  path /
                  status_code 200
                }
                 connect_timeout 3
                 nb_get_retry 3
                 delay_before_retry 3
          }
   } 
}      
global_defs 
{ 
   notification_email 
        {
          [email protected]@126.com
          }
           notification_email_from [email protected]
           smtp_connect_timeout 3smtp_server 127.0.0.1
           router_id LVS_DEVEL
 }
vrrp_script chk_schedown 
 { 
    script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
     #建立down檔案權重減2
     interval 2
     weight -2
  }
vrrp_instance VI_1
 { 
        interface eth0          
         state BACKUP  #此節點為被節點          
         priority 100          
         virtual_router_id 51           
         garp_master_delay  1
         
         
 authentication 
  {         
       auth_type PASS        
       auth_pass password               
   }
 track_interface 
   { 
        eth0                          
    } 

 virtual_ipaddress 
   { 
       172.16.16.7/16 dev eth0 label eth0:0 #配置對外的VIP位址                               } 

 track_script 
          { 
              chk_schedown 
           } 
} 
vrrp_instance VI_2
 { 
          interface eth0
          state MASTER           #此節點為主節點
          priority 101
          virtual_router_id 50
           garp_master_delay 1
authentication {      
                   auth_type PASS
                   auth_pass 12345678
                }

track_interface { 
                     eth0
                 } 

virtual_ipaddress { 
            172.16.16.8/16 dev eth0 label eth0:1 #配置對外的VIP位址
                              } 

track_script { 
                       chk_schedown 
                    } 
} 

virtual_server 172.16.16.7 80  #配置一個VIP 工作在TCP的80端口上 
 {                 
               
    delay_loop 6 #lb_algo rr #負載均衡的排程算法
    lb_kind DR #工作在DR模型上
    persistence_timeout 50 #是否啟用IPVS持久連接配接
    protocol TCP  #采用的是TCP協定
    # sorry_server 192.168.16.2 1358 #所有服務挂了 ,出現的提示頁面.要在這台伺服器上開啟http服務 
    real_server 192.168.16.2 80      #後面RIP位址
    { 
      weight 1 #權重
      HTTP_GET 
      {
          url 
              {         
                 path /    
                 status_code 200 
               }
         connect_timeout 3        
         nb_get_retry 3        
         delay_before_retry 3                         
      }
   } 

real_server 192.168.16.3 80 
    { 
                      weight 1 
   HTTP_GET 
        { 
           url
            { 
              path /
              status_code 200     
             }
                 connect_timeout 3nb_get_retry 3delay_before_retry 3    
         } 
     } 
} 
virtual_server 172.16.16.8 80  #配置一個VIP 工作在TCP的80端口上 
 {                 
               
       delay_loop 6 
       lb_algo rr 
       lb_kind DR 
       #persistence_timeout 50  
       protocol TCP  
       # sorry_server 192.168.16.2 1358 
real_server 192.168.16.2 80          #後面RIP位址
 { 
        weight 1 #權重
        HTTP_GET
            {
              url 
                  {
                     path /
                     status_code 200
                    }
                    connect_timeout 3 #每次測試3秒
                    nb_get_retry 3 #測試次數
                    delay_before_retry 3 #測試失敗在測試3次
             }
 } 

real_server 192.168.16.3 80 
  { 
              weight 1 
HTTP_GET 
         { 
           url 
               { 
                  path /
                  status_code 200
                }
                 connect_timeout 3
                 nb_get_retry 3
                 delay_before_retry 3
          }
   } 
}      

繼續閱讀