[TOC]html
在本文中,我將會講述如何在Centos 7下基於Keepalived和LVS技術,實現Web服務的高可用和負載均衡,咱們的目標拓撲結構以下圖所示node
本文將會持續修正和更新,最新內容請參考個人 GITHUB 上的 程序猿成長計劃 項目,歡迎 Star,更多精彩內容請 follow me。nginx
若是你以爲一步一步按照下面的操做來搭建太過麻煩,能夠直接下載 mylxsw/keepalived-example 項目,而後執行
make create
便可一鍵搭建起整個演示環境。git
使用Vagrant建立四臺虛擬機用於測試使用,Vagrant 配置文件格式以下github
Vagrant.configure("2") do |config| config.vm.box = "centos/7" config.vm.network "private_network", ip: "IP地址" end
對於每一個配置,須要替換配置文件中的IP地址web
目錄 | IP | 用途 |
---|---|---|
keepalived | 192.168.88.8 | 負載均衡Master |
keepalived-backup | 192.168.88.9 | 負載均衡Backup |
node-1 | 192.168.88.10 | web服務器 |
node-2 | 192.168.88.11 | web服務器 |
client | 192.168.88.2 | 客戶端,也能夠直接用本身的電腦,IP地址任意均可 |
VIP爲 192.168.88.100
,客戶端IP爲 192.168.88.2
。算法
啓動Vagrant服務器須要進入服務器所在目錄,執行
vagrant up
命令,登陸到服務器須要執行vagrant ssh
命令。若是你尚未接觸過Vagrant,那麼能夠看看這篇文章 Vagrant入門。因爲本文中不少命令都須要使用root
權限進行操做,所以建議執行命令su root
直接提高到root權限(密碼爲 vagrant ),不然須要在全部命令前添加sudo
來執行。centos
分別登陸每臺服務器,設置其hostname
,方便後面咱們區分不一樣的服務器服務器
# 在192.168.88.8上執行 hostnamectl set-hostname keepalived # 在192.168.88.9上執行 hostnamectl set-hostname keepalived-backup # 在192.168.88.10上執行 hostnamectl set-hostname node-1 # 在192.168.88.11上執行 hostnamectl set-hostname node-2
而後退出從新登陸,就能夠看到hostname生效了。網絡
在 keepalived 和 keepalived-backup 兩個虛擬機上,安裝keepalived服務
yum install -y keepalived ipvsadm
安裝完成後,能夠看到生成了/etc/keepalived/keepalived.conf
配置文件,不過這個文件是Keepalived提供的示例,後面咱們須要修改。
將 Keepalived 服務添加到開機自啓動
systemctl enable keepalived
在兩臺web服務器 node-1 和 node-2 上,咱們就簡單安裝一個 nginx,而後開放80端口,提供簡單的web服務用於測試
yum install yum-utils yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo yum install -y openresty
爲了方便查看效果,咱們將 nginx 的默認web頁面修改成顯示服務器的IP
ip addr show eth1 | grep '192.168.88.' | awk '{print $2}' > /usr/local/openresty/nginx/html/index.html
而後,啓動web服務
systemctl enable openresty systemctl start openresty
在這裏,咱們實現Keepalive服務(keepalived 和 keepalived-backup 兩臺服務器)的高可用,也就是爲負載均衡服務提供主備服務,當master掛掉以後,backup自動成爲新的master繼續提供服務。
下面是Keepalived配置文件內容
global_defs { router_id LVS_8808 } vrrp_instance HA_WebServer { state MASTER ! 監聽的網卡,keepalived會將VIP綁定到該網卡上 interface eth1 ! 虛擬路由器ID,同一個實例保持一致,多個實例不能相同 virtual_router_id 18 garp_master_refresh 10 garp_master_refresh_repeat 2 ! VRRP 優先順序的設定值。在選擇主節點的時候,該值大的備用 節點會優先漂移爲主節點 priority 100 ! 發送VRRP通告的間隔。單位是秒 advert_int 1 ! 集羣受權密碼 authentication { auth_type PASS auth_pass 123456 } ! 這裏是咱們配置的VIP,能夠配置多個,每一個IP一行 virtual_ipaddress { 192.168.88.100/24 } }
兩臺 keepalived服務器均使用該配置文件,惟一的不一樣是 priority
的取值在兩臺服務器上是不一樣的,咱們設置 keepalived 服務器的 priority=100
,keepalived-backup 的 priority=99
。
兩臺服務器設置不一樣的優先級以後,只要兩臺服務器都正常工做,則優先級高的爲 主服務器,優先級低的爲 備服務器。
配置完成後,重啓 keepalived 服務
systemctl restart keepalived
而後,咱們能夠看到 keepalived 服務器綁定了VIP 192.168.88.100
keepalived 服務器
keepalived-backup服務器
咱們驗證一下主服務器掛掉以後,備份服務器是否可以正常接替工做,在 keepalived 服務器上,執行 systemctl stop keepalived
命令,中止keepalived服務,模擬服務器掛掉的情景,而後咱們看到
keepalived 服務器
keepalived-backup服務器
VIP成功漂移到了備份服務器,在備份服務器的/var/log/message
日誌中,能夠看到以下信息
重啓 keepalived 服務器的Keepalived服務(systemctl start keepalived
),模擬服務器恢復,咱們能夠看到VIP又從新漂移回了 keepalived 服務器(由於 keepalived 服務器設置的 priority
大於 keepalived-backup 服務器的設置)。查看 keepalived-backup 的日誌,能夠看到下面信息
在兩臺Keepalived服務器的配置文件 /etc/keepalived/keepalived.conf
中,追加如下配置
virtual_server 192.168.88.100 80 { ! 健康檢查的時間間隔 delay_loop 6 ! 負載均衡算法 lb_algo wlc ! LVS模式,支持NAT/DR/TUN模式 lb_kind DR protocol TCP nat_mask 255.255.255.0 ! 真實Web服務器IP,端口 real_server 192.168.88.10 80 { weight 3 ! Web服務健康檢查 HTTP_GET { url { path / status_code 200 } connect_timeout 1 } } ! 真實Web服務器IP,端口 real_server 192.168.88.11 80 { weight 3 ! Web服務健康檢查 HTTP_GET { url { path / status_code 200 } connect_timeout 1 } } }
因爲咱們全部的服務器都在同一個子網中,所以沒法使用NAT(Network Address Translation)模式,這裏咱們使用DSR(Direct Server Return)模式,使用DSR模式(配置時使用DR
),須要web服務器將VIP綁定到本身的本地迴環網卡上去,不然沒法與web服務器通訊。在 node-1 和 node-2 上,執行下面的命令
ip addr add 192.168.88.100/32 dev lo
這裏綁定的VIP只在本次設置有效,服務器重啓後須要再次執行,所以,能夠經過下面的方法永久的添加該IP
在
/etc/sysconfig/network-scripts
目錄下,建立ifcfg-lo:0
文件DEVICE=lo:0 IPADDR=192.168.88.100 NETMASK=255.255.255.255 ONBOOT=yes NAME=loopback而後重啓網絡服務(
systemctl restart network
)讓其生效便可
接下來,重啓兩臺 keepalived 服務器的服務就能夠生效了
systemctl restart keepalived
而後咱們在客戶端訪問如下咱們的web服務,這裏咱們就可使用VIP來訪問了
能夠看到,請求被分配到了兩臺真實的web服務器。在 keepalived 服務器上執行 ipvsadm
若是此時node-1的服務掛了怎麼辦?咱們來模擬一下,在node-1上面,咱們中止web服務
systemctl stop openresty
等幾秒以後(咱們配置健康檢查週期爲6s)而後再來請求
在 keepalived 服務器上執行 ipvsadm
能夠看到,有問題的 node-1 已經被剔除了。
這裏你可能會有兩個疑問:
第一個是爲何沒法使用NAT模式?
使用NAT模式,正常的流程應該是這樣的,在NAT模式下,客戶端(192.168.1.2)請求通過負載均衡器(192.168.88.100)後,負載均衡器會修改目的IP地址爲真實的web服務器IP地址 192.168.88.10,這樣web服務器收到請求後,發現目的IP地址是本身,就能夠處理該請求了。響應報文發送給負載均衡器,負載均衡器修改響應報文的源IP地址爲自身VIP,這樣客戶端收到響應後就可以正常處理了。
咱們的客戶端和服務器都在同一個子網下。處理完成後響應給客戶端時,響應報文的源IP地址爲 192.168.88.10,目的IP爲 192.168.88.2,因爲在同一個子網中,所以不會通過負載均衡器,而是直接將報文發送給了客戶端。所以在響應報文中,源IP地址還沒有通過修改直接發送給了客戶端,致使沒法正常完成通訊。
第二個是爲何使用DSR模式必須將VIP綁定到web服務器的網卡上去?
在DSR模式下,發送給負載均衡器的報文沒有通過任何修改就直接發送給了真實的web服務器,這時候目的IP地址是 VIP 192.168.88.100,Web服務器收到該請求以後,發現目的IP地址不是本身,會認爲這個報文不是發送給本身的,沒法處理該請求。也就是說,在使用DSR模式下,僅僅在負載均衡器上作配置是沒法實現負載均衡的。所以最簡單的方式就是將VIP綁定到真實服務器的迴環接口上。之因此子網掩碼時 255.255.255.255(或者**/32**),是讓其廣播地址是其自身,避免其發送ARP到該子網的廣播域,防止負載均衡器上的VIP和Web服務器的IP衝突。
對於負載均衡算法,咱們這裏採用了wlc
(加權最小鏈接調度)。其它調度算法以下(圖來自 《24小時365天不間斷服務:服務器基礎設施核心技術》一書)
本文將會持續修正和更新,最新內容請參考個人 GITHUB 上的 程序猿成長計劃 項目,歡迎 Star,更多精彩內容請 follow me。
經過本文,相信你已經能夠搭建一套高可用的Web服務了,Keepalived還有不少配置選項等待你們本身去發掘,咱們不只能夠實現Web服務的高可用,還能夠用來實現一些基礎服務組件的高可用,好比MySQL、Redis、RabbitMQ等,本文也只是拋磚引玉了。