1. 程式人生 > 實用技巧 >LVS+KeepAlived+Nginx高可用實現方案

LVS+KeepAlived+Nginx高可用實現方案

LVS+KeepAlived+Nginx高可用實現方案

文章目錄

這是一段血淚教程…


概念

LVS
  • 什麼是lvs
    LVS是Linux Virtual Server的簡寫,意即Linux虛擬伺服器,是一個虛擬的伺服器集群系統。本專案在1998年5月由章文嵩博士成立,是中國國內最早出現的自由軟體專案之一。

  • 宗旨

    1. 使用叢集技術和Linux作業系統實現一個高效能、高可用的伺服器.
    2. 很好的可伸縮性(Scalability)
    3. 很好的可靠性(Reliability)
    4. 很好的可管理性(Manageability)。
  • 特點
    可伸縮網路服務的幾種結構,它們都需要一個前端的負載排程器(或者多個進行主從備份)。我們先分析實現虛擬網路服務的主要技術,指出IP負載均衡技術是在負載排程器的實現技術中效率最高的。在已有的IP負載均衡技術中,主要有通過網路地址轉換(Network Address Translation)將一組伺服器構成一個高效能的、高可用的虛擬伺服器,我們稱之為VS/NAT技術(Virtual Server via Network Address Translation)。在分析VS/NAT的缺點和網路服務的非對稱性的基礎上,我們提出了通過IP隧道實現虛擬伺服器的方法VS/TUN (Virtual Server via IP Tunneling),和通過直接路由實現虛擬伺服器的方法VS/DR(Virtual Server via Direct Routing),它們可以極大地提高系統的伸縮性。VS/NAT、VS/TUN和VS/DR技術是LVS叢集中實現的三種IP負載均衡技術。

  • 其他
    更多其他特點請參考百度百科-Lvs

KeepAlived
  • 什麼是keepAlived
    keepalived是一個類似於layer3, 4 & 5交換機制的軟體,也就是我們平時說的第3層、第4層和第5層交換。Keepalived是自動完成,不需人工干涉。
  • 簡介
    Keepalived的作用是檢測伺服器的狀態,如果有一臺web伺服器宕機,或工作出現故障,Keepalived將檢測到,並將有故障的伺服器從系統中剔除,同時使用其他伺服器代替該伺服器的工作,當伺服器工作正常後Keepalived自動將伺服器加入到伺服器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修復故障的伺服器。
  • 工作原理
    Layer3,4,5工作在IP/TCP協議棧的IP層,TCP層,及應用層,原理分別如下:
    • Layer3:Keepalived使用Layer3的方式工作式時,Keepalived會定期向伺服器群中的伺服器傳送一個ICMP的資料包(既我們平時用的Ping程式),如果發現某臺服務的IP地址沒有啟用,Keepalived便報告這臺伺服器失效,並將它從伺服器群中剔除,這種情況的典型例子是某臺伺服器被非法關機。Layer3的方式是以伺服器的IP地址是否有效作為伺服器工作正常與否的標準。
    • Layer4:如果您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP埠的狀態來決定伺服器工作正常與否。如web server的服務埠一般是80,如果Keepalived檢測到80埠沒有啟動,則Keepalived將把這臺伺服器從伺服器群中剔除。
    • Layer5:Layer5對指定的URL執行HTTP GET。然後使用MD5演算法對HTTP GET結果進行求和。如果這個總數與預期值不符,那麼測試是錯誤的,伺服器將從伺服器池中移除。該模組對同一服務實施多URL獲取檢查。如果您使用承載多個應用程式伺服器的伺服器,則此功能很有用。此功能使您能夠檢查應用程式伺服器是否正常工作。MD5摘要是使用genhash實用程式(包含在keepalived軟體包中)生成的。
      SSL_GET與HTTP_GET相同,但使用SSL連線到遠端Web伺服器。
      MISC_CHECK:此檢查允許使用者定義的指令碼作為執行狀況檢查程式執行。結果必須是0或1.該指令碼在導演盒上執行,這是測試內部應用程式的理想方式。可以使用完整路徑(即/path_to_script/script.sh)呼叫可以不帶引數執行的指令碼。那些需要引數的需要用雙引號括起來(即“/path_to_script/script.sh arg 1 … arg n”)
  • 作用
    主要用作RealServer的健康狀態檢查以及LoadBalance主機和BackUP主機之間failover的實現。
    高可用web架構:LVS+keepalived+nginx+apache+php+eaccelerator(+nfs可選 可不選)

為什麼要使用

當我們的伺服器意外掛了之後,我們要怎麼做?
當然是找一臺新的機器,替代現有的機器,然後做新的環境部署,埠對映,域名解析等等一系列的工作,再將服務重新啟動;但是如果這一系列的操作都是手動完成的,那麼等你把這些工作搞好,可能服務已經停止個把小時了,這會兒估計運營早就提著菜刀架在你脖子上了;
但是如果使用了KeepAlived之後,然後提前將備用機準備好,當主的機器掛掉之後,自動將VIP給你切換到備用機,並且以郵件的形式告訴你說主服務已經掛了,你得趕緊恢復起來;這時候你就可以慢慢的去找主服務的問題,這時候並不會影響到你的正常業務執行。


準備


軟體安裝

在192.168.1.128及192.168.1.129上安裝keepalived
在192.168.1.130及192.168.1.131上安裝nginx

KeepAlived 安裝
  • 基礎軟體安裝
    yum install -y gcc
    yum install -y openssl-devel
    yum install -y libnl libnl-devel
    yum install -y libnfnetlink-devel
    yum install -y net-tools
    yum install -y vim wget
原始碼安裝
  • 將以上下載的2.0.10的版本拷貝至/use/local/src下
  • 安裝
    • 解壓編譯、安裝
        cd /use/local/src
        tar -zxvf keepalived-2.0.10.tar.gz
        mv keepalived-2.0.10 ../keepalived
        cd /use/local/keepalived/
        ./configure
        make && make install

      • 常見錯誤1
        !!! OpenSSL is not properly installed on your system. !!!
        !!! Can not include OpenSSL headers files. !!!
        解決方法:
        yum -y install openssl-devel
      • 常見錯誤2
        this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.(此版本不支援使用IPv6的IPVS。 請安裝libnl / libnl-3 dev庫以支援帶IPVS的IPv6。)
        解決方法:
        yum -y install libnl libnl-devel
      • 常見問題三
        configure: error: libnfnetlink headers missing
        解決方法:
        yum install -y libnfnetlink-devel
    • keepalived配置
      將keepalived配置檔案拷貝到etc/keepalived下
      mkdir /etc/keepalived
      cp /usr/local/keepalived/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
      
    • 開機啟動項
      把 keepalived的啟動檔案複製到init.d下,加入開機啟動項
      cp /usr/local/keepalived/keepalived/etc/init.d/keepalived /etc/rc.d/init.d/
      
    • 將keepalived檔案拷貝到etc下
      cp /usr/local/keepalived/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
      
    • 把keepalived加入系統命令目錄
      cp /usr/local/sbin/keepalived /usr/sbin/
      

      • 常見問題
        error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
        解決方式:
        ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1
        ln -s /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
yum安裝

這裡的教程使用的上面的原始碼安裝

yum install -y keepalived

服務啟動、重啟、關閉

這裡只是測試服務是否能正常啟動,後續還需要更改keepalived的配置之後才能正常的使用

  • 啟動
    /etc/init.d/keepalived start
    
  • 重啟
    /etc/init.d/keepalived restart
    
  • 啟動
    /etc/init.d/keepalived stop
    
安裝ipvsadm

用於檢視lvs轉發及代理情況的工具
只需要在192.168.1.128及192.168.1.129上安裝即可

yum install ipvsadm -y

nginx安裝

只需要在192.168.1.130及192.168.1.131上安裝nginx即可
請參考基於CentOS 7 web服務環境搭建(包含JDK+Nginx+Tomcat+Mysql+Redis)中nginx的安裝部分
或者
請參考OpenResty(Nginx+Lua)高併發最佳實踐直接安裝OpenResty即可包含了nginx部分,這裡選用的是這種方式


防火牆(iptables)

  • 停用firewalld
    systemctl stop firewalld.service
    systemctl disable firewalld.service
    systemctl mask firewalld.service
    
  • 安裝iptables防火牆
    #檢視iptables相關的安裝包
    yum list iptables*
    #安裝
    yum install -y iptables-services
    
防火牆配置(方式一)
  • 編輯防火牆,增加埠
    • keepalived伺服器下的配置
      192.168.1.128和192.168.1.129下的新增以下配置
      vi /etc/sysconfig/iptables
      #允許vrrp多播心跳(如果防火牆開啟,這裡不配置這個,就會出現裂腦)
      -A INPUT -p vrrp -j ACCEPT
      #開啟80埠的訪問(如果防火牆開啟,不配置這個,vip的80埠將無法正常訪問)
      -I INPUT -p tcp --dport 80 -j ACCEPT
      
    • nginx伺服器下配置
      192.168.1.130和192.168.1.131下的新增以下配置
      vi /etc/sysconfig/iptables
      #nginx預設監聽的80埠 這裡直接開啟80埠的外網訪問(不開啟外網將無法正常反問對應伺服器的nginx)
      -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
      
    • 重啟防火牆
      systemctl restart iptables.service
      
防火牆配置(方式二)

直接關閉所有防火牆,這種方式僅僅用於測試;不推薦用於實際專案

systemctl stop iptables.service


配置nginx伺服器(>>這裡很重要!很重要!很重要!!!<<)

以下操作需要在角色為Web伺服器的兩臺中進行
即192.168.1.130和192.168.1.131這兩臺伺服器上配置即可

  • 啟動nginx服務
    確保nginx已經正常運行了
    ps -ef|grep nginx
    
  • 編輯realserver指令碼檔案兩臺機器都要搞
    • 進入init資料夾
      cd /etc/init.d/

    • 編輯指令碼
      vim realserver
      新增以下指令碼

      #虛擬的vip 根據自己的實際情況定義
      SNS_VIP=192.168.1.200
      /etc/rc.d/init.d/functions
      case "$1" in
      start)
             ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
             /sbin/route add -host $SNS_VIP dev lo:0
             echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
             echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
             echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
             echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
             sysctl -p >/dev/null 2>&1
             echo "RealServer Start OK"
             ;;
      stop)
             ifconfig lo:0 down
             route del $SNS_VIP >/dev/null 2>&1
             echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
             echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
             echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
             echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
             echo "RealServer Stoped"
             ;;
      *)
             echo "Usage: $0 {start|stop}"
             exit 1
      esac
      exit 0
      
    • 儲存並設定指令碼的執行許可權

      chmod 755 /etc/init.d/realserver
      // 因為realserver指令碼中用到了/etc/rc.d/init.d/functions,所以一併設定許可權
      chmod 755 /etc/rc.d/init.d/functions
      
    • 執行指令碼

      service realserver start
      
    • 檢視執行結果
      ip a
      如果看到以下效果,說明指令碼已經執行成功了


最後關鍵一步,配置keepalived

配置MASTER
  • 進入192.168.1.128伺服器
    cd /etc/keepalived
    #備份預設的keepalived配置
    mv keepalived.conf keepalived-back.conf
    vim keepalived.conf
    
  • 新增以下配置:
    global_defs {
       notification_email {
             [email protected]
       }
       notification_email_from [email protected]
       smtp_server 192.168.80.1
       smtp_connection_timeout 30
       router_id LVS_DEVEL  # 設定lvs的id,在一個網路內應該是唯一的
    }
    vrrp_instance VI_1 {
        state MASTER   #指定Keepalived的角色,MASTER為主,BACKUP為備 記得大寫
        interface eno16777736  #網絡卡id 不同的電腦網絡卡id會有區別 可以使用:ip a檢視
        virtual_router_id 51  #虛擬路由編號,主備要一致
        priority 100  #定義優先順序,數字越大,優先順序越高,主DR必須大於備用DR
        advert_int 1  #檢查間隔,預設為1s
        authentication {   #這裡配置的密碼最多為8位,主備要一致,否則無法正常通訊
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.1.200  #定義虛擬IP(VIP)為192.168.1.200,可多設,每行一個
        }
    }
    # 定義對外提供服務的LVS的VIP以及port
    virtual_server 192.168.1.200 80 {
        delay_loop 6 # 設定健康檢查時間,單位是秒
        lb_algo rr # 設定負載排程的演算法為wlc
        lb_kind DR # 設定LVS實現負載的機制,有NAT、TUN、DR三個模式
        nat_mask 255.255.255.0
        persistence_timeout 0
        protocol TCP
        real_server 192.168.1.130 80 {  # 指定real server1的IP地址
            weight 3   # 配置節點權值,數字越大權重越高
            TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
            }
        }
        real_server 192.168.1.131 80 {  # 指定real server2的IP地址
            weight 3  # 配置節點權值,數字越大權重越高
            TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
            }
         }
    }
    
配置BACKUP
  • 進入192.168.1.129伺服器
    cd /etc/keepalived
    #備份預設的keepalived配置
    mv keepalived.conf keepalived-back.conf
    vim keepalived.conf
    
  • 新增以下配置:
    global_defs {
       notification_email {
             [email protected]
       }
       notification_email_from [email protected]
       smtp_server 192.168.80.1
       smtp_connection_timeout 30
       router_id LVS_DEVEL  # 設定lvs的id,在一個網路內應該是唯一的
    }
    vrrp_instance VI_1 {
        state BACKUP #指定Keepalived的角色,MASTER為主,BACKUP為備 記得大寫
        interface eno16777736  #網絡卡id 不同的電腦網絡卡id會有區別 可以使用:ip a檢視
        virtual_router_id 51  #虛擬路由編號,主備要一致
        priority 50  #定義優先順序,數字越大,優先順序越高,主DR必須大於備用DR
        advert_int 1  #檢查間隔,預設為1s
        authentication {   #這裡配置的密碼最多為8位,主備要一致,否則無法正常通訊
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.1.200  #定義虛擬IP(VIP)為192.168.1.200,可多設,每行一個
        }
    }
    # 定義對外提供服務的LVS的VIP以及port
    virtual_server 192.168.1.200 80 {
        delay_loop 6 # 設定健康檢查時間,單位是秒
        lb_algo rr # 設定負載排程的演算法為wlc
        lb_kind DR # 設定LVS實現負載的機制,有NAT、TUN、DR三個模式
        nat_mask 255.255.255.0
        persistence_timeout 0
        protocol TCP
        real_server 192.168.1.130 80 {  # 指定real server1的IP地址
            weight 3   # 配置節點權值,數字越大權重越高
            TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
            }
        }
        real_server 192.168.1.131 80 {  # 指定real server2的IP地址
            weight 3  # 配置節點權值,數字越大權重越高
            TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
            }
         }
    }
    
配置注意項
  • router_id
    後面跟的自定義的ID在同一個網路下是一致的
  • state
    state後跟的MASTER和BACKUP必須是大寫;否則會造成配置無法生效的問題
  • interface
    網絡卡ID;這個值不能完全拷貝我的配置,要根據自己的實際情況來看,可以使用以下方式查詢
    ip a
  • priority
    主備優先順序
    MASTER中配置的priority必須比BACKUP大;差值最好>=50
  • authentication
    主備之間的認證方式
    一般使用PASS即可;主備的配置必須一致;否則無法通訊,會導致裂腦;密碼不能大於8位
  • virtual_ipaddress
    配置的VIP;允許配置多個

啟動keepalived

在192.168.1.128和192.168.1.129下分別執行以下指令啟動keepalived

/etc/init.d/keepalived start

  • 檢查主keepalived 啟動後的配置情況
    ip a
    // 如果網絡卡下出現192.168.1.200(VIP)說明主已經啟動成功
    
  • 檢查備keepalived 啟動後的配置情況
    ip a
    
  • 備伺服器的網絡卡下沒有出現192.168.1.200(VIP)的ip,說明備服務正常
    注:如果這裡也出現了VIP,那麼說明裂腦了,需要檢查防火牆是否配置正確;是否允許了vrrp的多播通訊

LVS管理工具-ipvsadm

安裝
yum install ipvsadm -y

檢視統計
  • 檢視當前配置的虛擬服務和各個RS的權重
    ipvsadm -Ln
    
  • 檢視當前ipvs模組中記錄的連線(可用於觀察轉發情況)
    ipvsadm -lnc
    
  • 檢視ipvs模組的轉發情況統計
    ipvsadm -Ln --stats | --rate
    
lvs超時配置
  • 檢視lvs的超時時間
    ipvsadm -L --timeout
    
  • 優化連線超時時間
    ipvsadm --set 1 10 300
    

  • 這裡的TCP的連線超時時間最好和keepalived中的persistence_timeout超時時間保持一致;persistence_timeout的超時時間表示指定時間內,同ip的請求會轉發到同一個服務;
  • 更多ipvsadm的操作請參考以下文章
    https://www.cnblogs.com/lipengxiang2009/p/7353373.html

測試

正常代理轉發

使用我linux虛擬機器的windows宿主機進行測試

  • 測試vip

    ping 192.168.1.200
    
  • 測試vip監聽的埠

    telnet 192.168.1.200 80
    
  • 請求虛擬IP檢視轉發的服務

    KeepAlived高可用測試
    • 停掉主keepalived

      /etc/init.d/keepalived stop
      
    • vip漂移至備伺服器

      此時網頁訪問:192.168.1.200依然能夠正常訪問;卻分發依然正常

    • 重啟主keepalived
      主服務恢復之後;vip又會自動漂移回主服務


LVS監控真實服務測試
  • 檢視最新的虛擬ip對應的RealServer的情況
    ipvsadm -l
    

  • 可以看出192.168.1.130和192.168.1.131兩臺正式服務都還在
  • 測試停掉192.168.1.130
  • 再次檢視虛擬ip對應的RealServer的情況

    可以看出192.168.1.130這臺已經掛掉的伺服器已經被移除了
  • 測試訪問虛擬ip

    所有的訪問都只會轉發到131的真實伺服器
  • 恢復192.168.1.130
    lvs又會自動監控並加入192.168.1.130


常見問題

  • 裂腦
    主備keepalived伺服器同時出現了VIP;導致vip無法正常使用
    常見原因為防火牆配置所致導致多播心跳失敗
  • vip能ping通,但是vip監聽的埠不通
    • 第一個原因:nginx1和nginx2兩臺伺服器的服務沒有正常啟動
    • 第二個原因:請參考上面Nginx伺服器那一大項中所說的配置,可能沒有配置好
  • vip ping不通
    核對是否出現裂腦
    核對keepalived的配置是否正確
    • 原文連結 https://blog.csdn.net/lupengfei1009/article/details/86514445