Nginx配置高可用(Nginx+keepalived)
1、高可用的基本介紹
在使用 Nginx 做反向代理或者負(fù)載均衡的時(shí)候,都是以 Nginx 為入口,如果 Nginx 宕機(jī)了,那么所有的服務(wù)都無法正常提供,影響非常嚴(yán)重。所有我們需要保證 nginx 高可用,就是配置備份機(jī),前一個(gè)掛了,還有后一個(gè)。
為了避免負(fù)載均衡服務(wù)器宕機(jī)造成嚴(yán)重影響,就需要建立一個(gè)備份機(jī)。主服務(wù)器和備份機(jī)上都運(yùn)行高可用(High Availability)監(jiān)控程序,通過傳送諸如“I am alive”這樣的信息來監(jiān)控對方的運(yùn)行狀況。當(dāng)備份機(jī)不能在一定的時(shí)間內(nèi)收到這樣的信息時(shí),它就接管主服務(wù)器的服務(wù)IP并繼續(xù)提供負(fù)載均衡服務(wù);當(dāng)備份管理器又從主管理器收到“I am alive”這樣的信息時(shí),它就釋放服務(wù)IP地址,這樣的主服務(wù)器就開始再次提供負(fù)載均衡服務(wù)。
高可用(High Availability)是分布式系統(tǒng)架構(gòu)設(shè)計(jì)中必須考慮的因素之一,它通常是指,通過設(shè)計(jì)減少系統(tǒng)不能提供服務(wù)的時(shí)間。如果一個(gè)系統(tǒng)能夠一直提供服務(wù),那么這個(gè)可用性則是百分之百,但是我們不能保證一個(gè)系統(tǒng)能永遠(yuǎn)不出問題,所以我們只能通過設(shè)計(jì)來盡可能的去減少由于系統(tǒng)的故障所造成的影響。
1.1、keepalived
我們可以通過 keepalived 來實(shí)現(xiàn) Nginx 的高可用,keepalived 是集群管理中保證集群高可用的一個(gè)服務(wù)軟件,用來防止單點(diǎn)故障。Keepalived的作用是檢測 web 服務(wù)器的狀態(tài),如果有一臺(tái) web 服務(wù)器死機(jī)或工作出現(xiàn)故障,Keepalived 將能檢測到,并將有故障的 web 服務(wù)器從系統(tǒng)中剔除,當(dāng)web服務(wù)器工作正常后 Keepalived 會(huì)自動(dòng)將該 web 服務(wù)器加入到服務(wù)器群中。這些工作全部都會(huì)自動(dòng)完成,不需要人工干涉,需要人工做的只是修復(fù)故障的web服務(wù)器。keepalived 可以理解為一個(gè)健康檢查的軟件。
高可用至少需要 2 臺(tái)服務(wù)器,主備都得裝上keepalived,當(dāng)請求訪問主服務(wù)器時(shí),備份服務(wù)器會(huì)一直檢查主服務(wù)器的狀態(tài)。
keepalived 需要綁定一個(gè)虛擬地址 vip ( Virtual IP Address ) ,這個(gè)虛擬 ip 地址綁定在哪臺(tái)服務(wù)器上請求就會(huì)發(fā)送到哪臺(tái)服務(wù)器,一開始會(huì)綁定在主服務(wù)器上。

2、安裝 keepalived
首先準(zhǔn)備兩臺(tái)服務(wù)器,這里我們準(zhǔn)備了兩臺(tái)虛擬機(jī)。分別在這兩臺(tái)服務(wù)器上安裝 Nginx 和 keepalived。
安裝 keepalived 使用 yum 方式直接安裝即可,該方式會(huì)自動(dòng)安裝依賴。安裝 keepalived 命令:
yum -y install keepalived
安裝完成后可以輸入 rpm -q -a keepalived 命令檢驗(yàn)安裝是否成功:

通過 yum 方式安裝的 keepalived 在安裝完成之后,會(huì)在 /ect 目錄下生成一個(gè) keepalive 目錄,該目錄下存放著 keepalived 的配置文件 keepalived.conf :

3、完成高可用配置
首先需要修改 keepalived 的配置文件,keepalived 的配置文件在 /etc/keepalived 目錄下。
主服務(wù)器和備份服務(wù)器的 keepalived 配置文件有一點(diǎn)不同。下面是主服務(wù)器的 keepalived.conf 文件內(nèi)容,直接替代默認(rèn)的 keepalived.conf 配置文件即可。
global_defs { notification_email { # keepalived服務(wù)宕機(jī)異常出現(xiàn)的時(shí)候,發(fā)送通知郵件 可以是多個(gè) acassen@firewall.loc # 收件人郵箱1 failover@firewall.loc # 收件人郵箱2 sysadmin@firewall.loc # 收件人郵箱3 } notification_email_from Alexandre.Cassen@firewall.loc #郵件發(fā)件人 smtp_ server 192.168.32.128 #主服務(wù)器的ip地址。郵件服務(wù)器地址 smtp_connect_timeout 30 # 超時(shí)時(shí)間 router_id LVS_DEVEL # 機(jī)器標(biāo)識(shí) 局域網(wǎng)內(nèi)唯一即可。 LVS_DEVEL這字段在/etc/hosts文件中看;通過它訪問到主機(jī) } vrrp_script chk_http_ port { script "/usr/local/src/nginx_check.sh" #檢測腳本存放的路徑 interval 2 # 檢測腳本執(zhí)行的間隔,即檢測腳本每隔2s會(huì)自動(dòng)執(zhí)行一次 weight 2 #權(quán)重,如果這個(gè)腳本檢測為真,服務(wù)器權(quán)重+2 } vrrp_instance VI_1 { state MASTER # 指定keepalived的角色,MASTER為主,BACKUP為備。備份服務(wù)器上需將MASTER 改為BACKUP interface ens33 # 通信端口 通過ip addr可以看到,根據(jù)自己的機(jī)器配置 virtual_router_id 51 # vrrp實(shí)例id keepalived集群的實(shí)例id必須一致,即主、備機(jī)的virtual_router_id必須相同 priority 100 #優(yōu)先級(jí),數(shù)值越大,獲取處理請求的優(yōu)先級(jí)越高。主、備機(jī)取不同的優(yōu)先級(jí),主機(jī)值較大,備份機(jī)值較小 advert_int 1 #心跳間隔,默認(rèn)為1s。keepalived多機(jī)器集群 通過心跳檢測當(dāng)前服務(wù)器是否還正常工作,如果發(fā)送心跳沒反應(yīng),備份服務(wù)器就會(huì)立刻接管; authentication { # 服務(wù)器之間通信密碼 auth type PASS #設(shè)置驗(yàn)證類型和密碼,MASTER和BACKUP必須使用相同的密碼才能正常通信 auth pass 1111 } virtual_ipaddress { # 自定義虛擬IP。自定義的虛擬ip得根據(jù)真實(shí)ip設(shè)置。比如真實(shí)ip是192.168.91.138,那么虛擬ip可以設(shè)置為192.168.91.139~255,前面三個(gè)數(shù)得一致 192.168.32.50 # 定義虛擬ip(VIP),可多設(shè),每行一個(gè) } }
備份服務(wù)器的 keepalived 配置文件:
global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_ server 192.168.32.130 #備份服務(wù)器的ip地址 smtp_connect_timeout 30 router_id LVS_DEVEL # LVS_DEVEL這字段在/etc/hosts文件中看;通過它訪問到主機(jī) } vrrp_script chk_http_ port { script "/usr/local/src/nginx_check.sh" #檢測腳本 interval 2 # (檢測腳本執(zhí)行的間隔)2s weight 2 #權(quán)重,如果這個(gè)腳本檢測為真,服務(wù)器權(quán)重+2 } vrrp_instance VI_1 { state BACKUP # 指定keepalived的角色,MASTER為主,BACKUP為備。備份服務(wù)器上需將MASTER 改為BACKUP interface ens33 # 當(dāng)前進(jìn)行vrrp通訊的網(wǎng)絡(luò)接口卡(當(dāng)前centos的網(wǎng)卡) 用ifconfig查看你具體的網(wǎng)卡 virtual_router_id 51 # 虛擬路由編號(hào),主、備機(jī)的virtual_router_id必須相同 priority 90 #優(yōu)先級(jí),數(shù)值越大,獲取處理請求的優(yōu)先級(jí)越高。主、備機(jī)取不同的優(yōu)先級(jí),主機(jī)值較大,備份機(jī)值較小 advert_int 1 # 檢查間隔,默認(rèn)為1s(vrrp組播周期秒數(shù)),每隔1s發(fā)送一次心跳 authentication { # 校驗(yàn)方式, 類型是密碼,密碼1111 auth type PASS #設(shè)置驗(yàn)證類型和密碼,MASTER和BACKUP必須使用相同的密碼才能正常通信 auth pass 1111 } virtual_ipaddress { # 虛擬ip 192.168.32.50 # 定義虛擬ip(VIP),可多設(shè),每行一個(gè) } }
將上面的兩個(gè)配置文件分別替換主備服務(wù)器的 keepalived 配置文件。
上面的配置文件中我們配置了檢測腳本的名稱和位置,即 /usr/local/src/nginx_check.sh,根據(jù)配置我們需要往主備服務(wù)器的 /usr/local/src 目錄下分別創(chuàng)建一個(gè) nginx_check.sh 腳本文件,文件內(nèi)容如下:
#! /bin/bash #檢測nginx是否啟動(dòng)了 A=`ps -C nginx -no-header | wc - 1` if [ $A -eq 0];then #如果nginx沒有啟動(dòng)就啟動(dòng)nginx /usr/local/nginx/sbin/nginx #通過Nginx的啟動(dòng)腳本來重啟nginx sleep 2 if [`ps -C nginx --no-header| wc -1` -eq 0 ];then #如果nginx重啟失敗,則下面就會(huì)停掉keepalived服務(wù),進(jìn)行VIP轉(zhuǎn)移 killall keepalived fi fi
上面的檢測腳本的作用是,當(dāng)檢測到 nginx 掛掉但如果此時(shí) keepalived 沒掛掉,該腳本會(huì)主動(dòng)嘗試重啟nginx服務(wù),如果實(shí)在重啟不了nginx,該腳本會(huì)主動(dòng)關(guān)閉 keepalived 好讓備份服務(wù)器的 nginx 替代上來。
最后分別啟動(dòng)主備服務(wù)器的 Nginx 和 keepalived:
cd /usr/local/nginx/sbin # 啟動(dòng)Nginx需要先切換到 Nginx 的腳本目錄下 ./nginx -s stop #因?yàn)橐呀?jīng)啟動(dòng)了,所以先關(guān)閉 Nginx ./nginx #啟動(dòng)Nginx ps -ef | grep nginx #查看 Nginx 進(jìn)程的狀態(tài) systemctl start keepalived.service #啟動(dòng)keepalived ps -ef | grep keepalived #查看 keepalived 進(jìn)程的狀態(tài)
示例如下:

3.1、驗(yàn)證
配置完之后,我們可以在 window 瀏覽器上輸入上面配置的虛擬地址 192.168.32.50 來訪問主服務(wù)器的 Nginx:

如果主服務(wù)器沒有宕機(jī),不管我們刷新幾次,都是訪問的主服務(wù)器上的資源。
如果我們關(guān)閉了主服務(wù)器上的 Nginx 和 keepalived:
systemctl stop keepalived.service # 關(guān)閉keepalived ./nginx -s stop # 關(guān)閉Nginx
示例:

此時(shí)再訪問虛擬 ip 地址 192.168.32.50 仍能正常訪問,因?yàn)閭浞莘?wù)器此時(shí)在工作了。我們可以修改兩個(gè)服務(wù)器上的 Nginx 資源的內(nèi)容以便能區(qū)分是哪個(gè)服務(wù)器的資源,如下可以證明此時(shí)確實(shí)是備份服務(wù)器 192.168.32.130 在工作:

3.2、keepalived 的默認(rèn)配置文件
keepalived 的默認(rèn)配置文件如下:
! Configuration File for keepalived global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.200.16 192.168.200.17 192.168.200.18 } } virtual_server 192.168.200.100 443 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.201.100 443 { weight 1 SSL_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc } url { path /mrtg/ digest 9b3a0c85a887a256d6939da88aabd8cd } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } } virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP sorry_server 192.168.200.200 1358 real_server 192.168.200.2 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.200.3 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } } virtual_server 10.10.10.3 1358 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.200.4 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.200.5 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }

浙公網(wǎng)安備 33010602011771號(hào)