|
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas -->
<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
|
級別: 中級
Eli Dow
(
emdow@us.ibm.com
), 軟件工程師, IBM Linux Test and Integration Center
Frank LeFevre
(
lefevre@us.ibm.com
), 高級軟件工程師, IBM
2007 年 9 月 17 日
使用 Linux Virtual Server 和 Heartbeat v2,分 5 個步驟跨越多個物理或虛擬 Linux? 服務器輕松構建高度可用的 Apache Web 服務器集群。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
通過在多個處理器之間分擔工作負載并采用多種軟件恢復技術,能夠提供高度可用的環境并提高環境的總體 RAS(可靠性、可用性和可服務性)。可以得到的好處包括:更快地從意外中斷中恢復運行,以及將意外中斷對終端用戶的影響降至最低。
為了更好地理解這篇文章,您需要熟悉 Linux 和連網的基本知識,還需要配置好 Apache 服務器。本文的示例基于標準的 SUSE Linux Enterprise Server 10 (SLES10) 安裝,但是使用其他版本的明智用戶也應該可以采用文中展示的方法。
本文展示了健壯的 Apache Web 服務器堆棧,它擁有 6 個 Apache 服務器節點(雖然 3 個節點就足以支持文中闡述的步驟),以及 3 個 Linux Virtual Server (LVS) 控制器。我們使用 6 個 Apache 服務器節點,可以在測試時實現更高的工作負載吞吐量,從而模擬更大型的部署。文中展示的架構應該可以支持更多的控制器和后端 Apache 服務器(在資源允許的情況下),但是我們并未進行更深入的嘗試。圖 1 展示了使用 Linux Virtual Server 和 linux-ha.org 組件的實現。
圖 1. Linux Virtual Servers 和 Apache
如圖 1 所示,外部客戶機向單個 IP 地址發送通信量,而該 IP 地址可能存在于某個 LVS 控制器機器上。控制器機器積極地監控接收其發送工作的 Web 服務器池。
注意,圖 1 左側的工作負載進程指向右側。此集群的浮動資源地址在一個給定時間將位于某個 LVS 控制器實例上。可以使用一個圖形化的配置工具手動地移動服務地址,或者(這種方法更常見)自行管理服務地址,視 LVS 控制器的狀態而定。如果某個控制器變得不合格(由于連接丟失、軟件故障或類似原因),那么服務地址將自動地被重新分配給一個合格的控制器。
浮動服務地址必須跨越兩個或多個離散的硬件實例,以便在一個物理機器連接丟失的情況下繼續操作。使用本文展示的配置決策,每個 LVS 控制器都可以將包轉發給任何的實際 Apache Web 服務器,并且與服務器的物理位置或服務器與提供浮動服務地址的活動控制器的接近程度無關。本文展示了每個 LVS 控制器如何積極地監控 Apache 服務器,以確保只向正常運作的后端服務器發送請求。
使用這種配置,技術人員可以成功地讓整個 Linux 實例失效,而且不會中斷在浮動服務地址上啟用的用戶服務(通常是 http 和 https Web 請求)。
|
Linux Virtual Server 術語新手必讀
LVS 控制器:
Linux Virtual Server 控制器是一種系統,該系統接受任意的引入通信量并將其傳遞給任意數量的 realserver。然后接受來自 realserver 的響應并將其傳回發出請求的客戶機。控制器需要以一種透明的方式執行任務,使客戶機永遠不會知道執行實際工作負載處理的是 realserver。
LVS 控制器本身需要能夠實現資源(具體而言,指的是用于偵聽引入通信量的虛擬 IP 地址)之間的浮動,從而避免單點故障。LVS 控制器實現浮動 IP 地址的方法是利用 LVS 的 Heartbeat 組件。這允許每個配置好的、運行 Heartbeat 的控制器確保有且只有一個控制器聲明處理引入請求的虛擬 IP 地址。
除了能夠浮動服務 IP 地址外,控制器還需要能夠監控執行實際工作負載處理的 realserver 的狀態。控制器必須要了解哪些 realserver 可以一直用于工作負載處理。為監控 realserver 使用了 mon 包。繼續閱讀,了解關于
配置 Heartbeat
和
配置 mon
的細節。
Realserver:
這些系統是提供 HA 服務的真正的 Web 服務器實例。使用多個 realserver 提供 HA 所需的服務。在本文的環境中,實現了 6 個 realserver,但是一旦 LVS 基礎設施的其余部分就緒后,添加更多的 realserver 就是小事一樁了。
在本文中,假定 realserver 運行的都是 Apache Web Server,但是其他服務實現起來也同樣容易(實際上,作為文中展示的方法的附加測試,受支持的 SSH 服務也很容易實現)。
使用的 realserver 是常用的 Apache Web 服務器,只有一個明顯的區別,即它們被配置為以類似 LVS 控制器的浮動 IP 地址的形式進行響應,或以控制器使用的浮動 IP 地址所對應的虛擬主機名的形式響應。更改 Apache 配置文件中的一行即可完成這一操作。
|
|
您可以使用一個完全開源的軟件組合復制這些配置,該軟件組合包括,linux-ha.org 所提供的 Heartbeat 技術組件,以及通過 mon 和 Apache 進行監控的服務器。正如前面提到的,我們將使用 SUSE Linux Enterprise Server 測試配置。
LVS 場景中使用的所有機器都位于同一個子網中,使用的是 Network Address Translation (NAT) 配置。在 Linux Virtual Server Web 站點(請參閱
參考資料
)上描述了很多其他網絡結構;為簡便起見我們使用 NAT。為了更加安全,您應該限制穿過防火墻的通信量,只允許浮動 IP 地址在 LVS 控制器之間傳遞。
Linux Virtual Server 套件提供了幾種不同的方法以完成透明的 HA 后端基礎設施。每種方法都各有利弊。LVS-NAT 操作控制器服務器的方式是,獲取發往特定配置的端口的引入包,并動態地在包的頭部重寫目的地址。控制器本身并不處理包的數據內容,而是將其傳給 realserver。包中的目的地址被重寫為指向集群中的一個給定的 realserver。然后將包放回網絡中以傳遞給 realserver,而 realserver 并沒有意識到發生了什么情況。對于 realserver,它只是直接從外部接收請求。接著,realserver 的回復被發回控制器,在控制器中重寫回復,使其具有客戶機所指向的浮動 IP 地址的源地址,然后再發往原始客戶機。
使用 LVS-NAT 方法意味著 realserver 需要簡單的 TCP/IP 功能。LVS 操作的其他模式,即 LVS-DR 和 LVS-Tun,需要更加復雜的連網概念。選擇 LVS-NAT 的最主要的好處是只需對 realserver 配置做很少量的更改。實際上,最難的部分是牢記適當地設置路由語句。
步驟 1:構建 realserver 圖像
以構建 Linux 服務器實例池開始,每個實例運行 Apache Web 服務器,并確保服務器按預想的情況運作,將 Web 瀏覽器指向每個 realserver 的 IP 地址。通常,標準安裝被配置為在自己的 IP 地址上偵聽 80 端口(換言之,為每個 realserver 使用不同的 IP)。
接下來,在每個服務器上配置默認的 Web 頁面以顯示一個靜態頁面,其中包含了為頁面提供服務的機器的主機名。這確保了您可以一直了解測試期間您所連接的機器。
為防萬一,檢查在這些系統上轉發的 IP 是否為 OFF,方法是發出以下命令:
# cat /proc/sys/net/ipv4/ip_forward
如果不是 OFF 并且您需要禁用它,請發出以下命令:
# echo "0" >/proc/sys/net/ipv4/ip_forward
確保每個 realserver 都正常地偵聽 http 端口 (80) 的一個簡單方法是,使用外部系統并執行掃描。在一些與您的服務器連網的其他系統中,可以使用 nmap 工具以確保服務器執行偵聽操作。
清單 1. 使用 nmap 確保服務器執行偵聽操作
# nmap -P0 192.168.71.92Starting nmap 3.70 ( http://www.insecure.org/nmap/ ) at 2006-01-13 16:58 ESTInteresting ports on 192.168.71.92:(The 1656 ports scanned but not shown below are in state: closed)PORT STATE SERVICE22/tcp open ssh80/tcp filtered http111/tcp open rpcbind631/tcp open ipp
|
要注意的是,某些組織不贊成使用端口掃描工具,如 nmap:在使用工具之前請獲取組織的批準。
接下來,將 Web 瀏覽器指向每個 realserver 的實際 IP 地址,從而確保每個 realserver 按照預期為相應頁面提供服務。完成此操作后請轉到步驟 2。
步驟 2:安裝和配置 LVS 控制器
現在,您可以構建所需的 3 個 LVS 控制器實例。如果您第一次為每個 LVS 控制器安裝 SUSE Linux Enterprise Server 10,在初始安裝時,請確保選擇與 heartbeat、ipvsadm 和 mon 相關的高可用性包。如果您擁有現有的安裝,您就可以一直使用包管理工具,如 YAST,在完成基礎安裝之后添加這些包。強烈建議您將每個 realserver 添加到 /etc/hosts 文件中。這將確保為引入請求提供服務時,不會產生 DNS 相關的延遲。
此時,再次檢查每個目錄是否都能對每個 realserver 執行即時的 ping 操作:
清單 2. 對 realserver 執行 Ping 操作
# ping -c 1 $REAL_SERVER_IP_1 # ping -c 1 $REAL_SERVER_IP_2 # ping -c 1 $REAL_SERVER_IP_3 # ping -c 1 $REAL_SERVER_IP_4 # ping -c 1 $REAL_SERVER_IP_5 # ping -c 1 $REAL_SERVER_IP_6
|
完成此操作后,從服務器中的本地包管理工具中安裝 ipvsadm、Heartbeat 和 mon。回想一下,Heartbeat 將被用于控制器內部通信,而 mon 將被每個控制器用于維護關于每個 realserver 的狀態信息。
步驟 3:在控制器上安裝和配置 Heartbeat
如果您以前使用過 LVS,請記住,在 SLES10 上配置 Heartbeat Version 2 與在 SLES9 上配置 Heartbeat Version 1 截然不同。其中,Heartbeat Version 1 使用的文件(haresource、ha.cf 和 authkey)存儲在 /etc/ha.d/ 目錄中,而 Version 2 使用新的基于 XML 的 Cluster Information Base (CIB)。推薦的升級方法是使用 haresource 文件生成新的 cib.xml 文件。典型的 ha.cf 文件的內容如清單 3 所示。
我們從 SLES9 系統中獲取 ha.cf 文件,并且為 Version 2 添加底部的 3 行(
respawn
、
pingd
和
crm
)。如果您擁有現有的 version 1 配置,您也可以選擇執行同樣的操作。如果您要使用這些指令執行新安裝,您可以復制清單 3 并進行修改以適應您的生產環境。
清單 3. /etc/ha.d/ha.cf config 文件樣例
# Log to syslog as facility "daemon" use_logd on logfacility daemon # List our cluster members (the realservers) node litsha22 node litsha23 node litsha21 # Send one heartbeat each second keepalive 3 # Warn when heartbeats are late warntime 5 # Declare nodes dead after 10 seconds deadtime 10 # Keep resources on their "preferred" hosts - needed for active/active #auto_failback on # The cluster nodes communicate on their heartbeat lan (.68.*) interfaces ucast eth1 192.168.68.201 ucast eth1 192.168.68.202 ucast eth1 192.168.68.203 # Failover on network failures # Make the default gateway on the public interface a node to ping # (-m) -> For every connected node, add <integer> to the value set # in the CIB, * Default=1 # (-d) -> How long to wait for no further changes to occur before # updating the CIB with a changed attribute # (-a) -> Name of the node attribute to set, * Default=pingd respawn hacluster /usr/lib/heartbeat/pingd -m 100 -d 5s # Ping our router to monitor ethernet connectivity ping litrout71_vip #Enable version 2 functionality supporting clusters with > 2 nodes crm yes</integer>
|
respawn
指令在運行時指定某個程序的運行和監控。如果此程序退出時的退出碼不是 100,程序將自動重啟。第一個參數是運行程序的用戶 id,第二個參數是要運行的程序。
-m
參數將
pingd
屬性設為從當前機器可獲得的 ping 節點數的 100 倍,而 -
d
參數在修改 CIB 中的
pingd
屬性之前將延遲 5 秒。
ping
指令用于聲明 Heartbeat 的 PingNode,而
crm
指令指定了 Heartbeat 應運行 1.x-style 集群管理器或 2.x-style 集群管理器,后者支持 2 個以上的節點。
對于所有的控制器這個文件都應該相同。適當地設置權限使 hacluster 守護程序可以讀取文件也絕對重要。否則將導致日志文件中出現大量難于調試的警告。
對于某個版本的 1-style Heartbeat 集群,haresources 文件指定了節點名和連網信息(浮動 IP、關聯接口和廣播)。對我們而言,此文件仍然沒有變化:
litsha21 192.168.71.205/24/eth0/192.168.71.255
此文件將只用于生成 cib.xml 文件。
authkeys 文件指定了一個共享的密匙以允許控制器之間進行通信。共享密鑰就是一個密碼,所有的 heartbeat 節點都知道這個密碼并使用它進行相互通信。密鑰的使用避免了無關方對 heartbeat 服務器節點的影響。此文件也沒有變化:
auth 1
1 sha1 ca0e08148801f55794b23461eb4106db
接下來的幾步將向您展示如何將 version 1 的 haresources 文件轉換為 version 2 的基于 XML 的配置格式 (cib.xml)。雖然可以直接復制并使用清單 4 中的配置文件作為起點,但是強烈建議您針對自己的部署進行配置調整。
為了將文件格式轉換為部署中使用的基于 XML 的 CIB (Cluster Information Base) 文件,請發出以下命令:
python /usr/lib64/heartbeat/haresources2cib.py /etc/ha.d/haresources > /var/lib/heartbeat/crm/test.xml
將會生成一個類似清單 4 所示的配置文件,并置于 /var/lib/heartbeat/crm/test.xml 中。
清單 4. CIB.xml 樣例文件
<cib admin_epoch="0" have_quorum="true" num_peers="3" cib_feature_revision="1.3" generated="true" ccm_transition="7" dc_uuid="114f3ad1-f18a-4bec-9f01-7ecc4d820f6c" epoch="280" num_updates="5205" cib-last-written="Tue Apr 3 16:03:33 2007"><configuration><crm_config><cluster_property_set id="cib-bootstrap-options"><attributes><nvpair id="cib-bootstrap-options-symmetric_cluster" name="symmetric_cluster" value="true"></nvpair><nvpair id="cib-bootstrap-options-no_quorum_policy" name="no_quorum_policy" value="stop"></nvpair><nvpair id="cib-bootstrap-options-default_resource_stickiness" name="default_resource_stickiness" value="0"></nvpair><nvpair id="cib-bootstrap-options-stonith_enabled" name="stonith_enabled" value="false"></nvpair><nvpair id="cib-bootstrap-options-stop_orphan_resources" name="stop_orphan_resources" value="true"></nvpair><nvpair id="cib-bootstrap-options-stop_orphan_actions" name="stop_orphan_actions" value="true"></nvpair><nvpair id="cib-bootstrap-options-remove_after_stop" name="remove_after_stop" value="false"></nvpair><nvpair id="cib-bootstrap-options-transition_idle_timeout" name="transition_idle_timeout" value="5min"></nvpair><nvpair id="cib-bootstrap-options-is_managed_default" name="is_managed_default" value="true"></nvpair><attributes><cluster_property_set><crm_config><nodes><node uname="litsha21" type="normal" id="01ca9c3e-8876-4db5-ba33-a25cd46b72b3"><instance_attributes id="standby-01ca9c3e-8876-4db5-ba33-a25cd46b72b3"><attributes><nvpair name="standby" id="standby-01ca9c3e-8876-4db5-ba33-a25cd46b72b3" value="off"></nvpair><attributes><instance_attributes><node><node uname="litsha23" type="normal" id="dc9a784f-3325-4268-93af-96d2ab651eac"><instance_attributes id="standby-dc9a784f-3325-4268-93af-96d2ab651eac"><attributes><nvpair name="standby" id="standby-dc9a784f-3325-4268-93af-96d2ab651eac" value="off"></nvpair><attributes><instance_attributes><node><node uname="litsha22" type="normal" id="114f3ad1-f18a-4bec-9f01-7ecc4d820f6c"><instance_attributes id="standby-114f3ad1-f18a-4bec-9f01-7ecc4d820f6c"><attributes><nvpair name="standby" id="standby-114f3ad1-f18a-4bec-9f01-7ecc4d820f6c" value="off"></nvpair><attributes><instance_attributes><node><nodes><resources><primitive class="ocf" provider="heartbeat" type="IPaddr" id="IPaddr_1"><operations><op id="IPaddr_1_mon" interval="5s" name="monitor" timeout="5s"></op><operations><instance_attributes id="IPaddr_1_inst_attr"><attributes><nvpair id="IPaddr_1_attr_0" name="ip" value="192.168.71.205"></nvpair><nvpair id="IPaddr_1_attr_1" name="netmask" value="24"></nvpair><nvpair id="IPaddr_1_attr_2" name="nic" value="eth0"></nvpair><nvpair id="IPaddr_1_attr_3" name="broadcast" value="192.168.71.255"></nvpair><attributes><instance_attributes><primitive><resources><constraints><rsc_location id="rsc_location_IPaddr_1" rsc="IPaddr_1"><rule id="prefered_location_IPaddr_1" score="200"><expression attribute="#uname" id="prefered_location_IPaddr_1_expr" operation="eq" value="litsha21"></expression><rule><rsc_location><rsc_location id="my_resource:connected" rsc="IPaddr_1"><rule id="my_resource:connected:rule" score_attribute="pingd"><expression id="my_resource:connected:expr:defined" attribute="pingd" operation="defined"></expression><rule><rsc_location><constraints><configuration><cib></cib></configuration></constraints></rsc_location></rule></rule></rsc_location></rsc_location></rule></rule></rsc_location></constraints></resources></primitive></instance_attributes></attributes></attributes></instance_attributes></operations></operations></primitive></resources></nodes></node></instance_attributes></attributes></attributes></instance_attributes></node></node></instance_attributes></attributes></attributes></instance_attributes></node></node></instance_attributes></attributes></attributes></instance_attributes></node></nodes></crm_config></cluster_property_set></attributes></attributes></cluster_property_set></crm_config></configuration></cib>
|
一旦生成配置文件后,將 test.xml 移到 cib.xml 中,將所有者改為 hacluster,將組改為 haclient,然后重啟 heartbeat 進程。
現已完成 heartbeat 配置,對 heartbeat 進行設置,使其在每個控制器的引導階段啟動。為此,在每個控制器上發出以下命令(或相對您的發行版的等效命令):
# chkconfig heartbeat on
重啟每個 LVS 控制器以確保 heartbeat 服務在引導階段正常啟動。通過首先暫停保存浮動資源 IP 地址的機器,您可以等候其他 LVS Director 映像建立 quorum,然后在幾秒鐘內實例化最新選擇的主節點上的服務地址。當您將暫停的控制器映像重新聯機時,機器將在所有的節點間重新建立 quorum,此時浮動資源 IP 可能傳輸回來。整個過程只會耗費幾秒鐘。
另外,此時,您可能希望使用圖形化工具處理 heartbeat 進程 hb_gui(如圖 2 所示),手動地將 IP 地址在集群中移動,方法是將各種節點設置為備用或活動狀態。多次重試這些步驟,禁用并重新啟用活動的或不活動的各種機器。因為先前選中了配置策略,只要可以建立 quorum,并且至少有一個節點合格,那么浮動資源 IP 地址就保持正常運作。在測試期間,您可以使用簡單的 ping 確保不會發生丟失包的情況。當您完成試驗后,應該對配置的健壯性有一個深刻的體會。在繼續操作之前請確保浮動資源 IP 的 HA 配置適當。
圖 2. 用于 heartbeat 進程的圖形化配置工具 hb_gui
圖 2 展示了登錄后的圖形控制臺的外觀,上面顯示了托管資源和相關的配置選項。注意,當您首次啟動應用程序時,必須登錄到 hb_gui 控制臺;使用何種憑證將取決于您的部署。
注意,圖 2 中 litsha2* 系統集群中的每個節點都處于運行狀態。標記為 litsha21 的系統目前是活動節點,如 (IPaddr_1) 正下方鋸齒狀的附加資源所示。
另外要注意標記為 “No Quorum Policy” 的選項的值為 “stop”。這指的是任何單獨的節點將釋放它所擁有的資源。這個決策的含義是,在任何給定時間,必須有 2 個 heartbeat 節點是活動狀態,以便建立 quorum(換言之,一種 “少數服從多數” 的投票規則)。即使只有一個節點是活動的,完全運行的節點也會由于網絡故障丟失它與同級系統之間的連接,或者,如果兩個非活動的同級系統同時暫停,資源將被自動釋放。
步驟 4:使用 ipvsadm 命令創建 LVS 規則
下一步是獲取浮動資源 IP 地址并在其上進行構建。因為 LVS 要求對遠端 Web 瀏覽器客戶機透明,所以所有的 Web 請求都必須經過控制器過濾并傳給一個 realserver。然后,所有結果都需要傳回控制器,后者向發出 Web 頁面請求的客戶機返回響應。
為了完成上述的請求和響應流程,首先配置每個 LVS 控制器,從而發出以下命令啟用 IP 轉發(因此允許將請求傳給 realserver):
# echo "1" >/proc/sys/net/ipv4/ip_forward
# cat /proc/sys/net/ipv4/ip_forward
如果所有的操作都成功,那么第二個命令將返回一個 “1” 作為終端輸出。要永久性地添加此選項,請添加:
'' IP_FORWARD="yes"
到 /etc/sysconfig/sysctl 中。
接下來,要通知控制器將引入的 HTTP 請求傳遞給 HA 浮動 IP 地址,接著再傳給 realserver,使用
ipvsadm
命令。
首先,清除舊的 ipvsadm 表:
# /sbin/ipvsadm -C
在配置新表之前,您需要決定希望 LVS 控制器使用何種工作負載分配。收到來自客戶機的連接請求后,控制器根據一個 “進度表” 將 realserver 指派給客戶機,然后使用
ipvsadm
命令設置調度程序類型。可用的調度程序包括:
-
Round Robin (RR)
:新的引入連接被依次指派給每個 realserver。
-
Weighted Round Robin (WRR)
:使用附加的權重因子進行 RR 調度以補償各種 realserver 功能(如附加 CPU、更多內存等)的差異。
-
Least Connected (LC)
:新連接指向具有最少連接數量的 realserver。不要求是最空閑的 realserver,但是以此為方向。
-
Weighted Least Connection
(WLC):帶權重的 LC。
使用 RR 調度進行測試是個不錯的方法,因為易于確認。您可能希望將 WRR 和 LC 添加到測試例程中以確認它們能夠按預期運作。此處給出的示例使用 RR 調度及類似調度。
接下來,創建腳本以啟用轉發至 realserver 的 ipvsadm 服務,并且在每個 LVS 控制器中放置一個副本。當完成 mon 的后續配置以自動監控活動的 realserver 后,就不需要再使用這個腳本,但在此之前它會有助于測試 ipvsadm 組件。請記住在執行此腳本之前重新檢查網絡和 http/https 與每個 realserver 之間的連接是否正常。
清單 5. HA_CONFIG.sh 文件
#!/bin/sh # The virtual address on the director which acts as a cluster address VIRTUAL_CLUSTER_ADDRESS=192.168.71.205 REAL_SERVER_IP_1=192.168.71.220 REAL_SERVER_IP_2=192.168.71.150 REAL_SERVER_IP_3=192.168.71.121 REAL_SERVER_IP_4=192.168.71.145 REAL_SERVER_IP_5=192.168.71.185 REAL_SERVER_IP_6=192.168.71.186 # set ip_forward ON for vs-nat director (1 on, 0 off). cat /proc/sys/net/ipv4/ip_forward echo "1" >/proc/sys/net/ipv4/ip_forward # director acts as the gw for realservers # Turn OFF icmp redirects (1 on, 0 off), if not the realservers might be clever and # not use the director as the gateway! echo "0" >/proc/sys/net/ipv4/conf/all/send_redirects echo "0" >/proc/sys/net/ipv4/conf/default/send_redirects echo "0" >/proc/sys/net/ipv4/conf/eth0/send_redirects # Clear ipvsadm tables (better safe than sorry) /sbin/ipvsadm -C # We install LVS services with ipvsadm for HTTP and HTTPS connections with RR # scheduling /sbin/ipvsadm -A -t $VIRTUAL_CLUSTER_ADDRESS:http -s rr /sbin/ipvsadm -A -t $VIRTUAL_CLUSTER_ADDRESS:https -s rr # First realserver # Forward HTTP to REAL_SERVER_IP_1 using LVS-NAT (-m), with weight=1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_1:http -m -w 1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_1:https -m -w 1 # Second realserver # Forward HTTP to REAL_SERVER_IP_2 using LVS-NAT (-m), with weight=1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_2:http -m -w 1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_2:https -m -w 1 # Third realserver # Forward HTTP to REAL_SERVER_IP_3 using LVS-NAT (-m), with weight=1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_3:http -m -w 1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_3:https -m -w 1 # Fourth realserver # Forward HTTP to REAL_SERVER_IP_4 using LVS-NAT (-m), with weight=1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_4:http -m -w 1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_4:https -m -w 1 # Fifth realserver # Forward HTTP to REAL_SERVER_IP_5 using LVS-NAT (-m), with weight=1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_5:http -m -w 1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_5:https -m -w 1 # Sixth realserver # Forward HTTP to REAL_SERVER_IP_6 using LVS-NAT (-m), with weight=1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_6:http -m -w 1 /sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_6:https -m -w 1 # We print the new ipvsadm table for inspection echo "NEW IPVSADM TABLE:" /sbin/ipvsadm
|
如清單 5 中所示,腳本只是啟用了 ipvsadm 服務,然后實際上使用了相同的代碼節以便將 Web 和 SSL 請求轉發給每個單個的 realserver。我們使用了
-m
選項指定 NAT,并給每個 realserver 賦以權重 1(
-w 1
)。使用正常的輪循調度時,指定的權重會出現冗余(因為默認的權重總是 1)。顯示此選項的惟一目的是讓您傾向于選擇加權的輪循。 為此,在關于使用輪循的注釋下的 2 個連續的行中將
rr
改為
wrr
,當然不要忘了相應地調整權重。有關各種調度程序的更多信息,請查詢 ipvsadm 手冊。
您現在已經配置了每個控制器,可以處理引入的對浮動服務 IP 的 Web 和 SSL 請求,方法是重寫這些請求并連續地將工作傳遞給 realserver。但是為了從 realserver 收回通信量,并且為了在將請求返回給發出請求的客戶機之前執行相反的過程,您需要對控制器更改幾個連網設置。其原因是需要在平面網絡拓撲結構中實現 LVS 控制器和 realserver(即,同一子網上的所有組件)。我們需要執行以下步驟以強制 Apache 通過控制器返回響應通信量,而不是自己直接應答:
echo "0" > /proc/sys/net/ipv4/conf/all/send_redirects
echo "0" > /proc/sys/net/ipv4/conf/default/send_redirects
echo "0" > /proc/sys/net/ipv4/conf/eth0/send_redirects
執行此操作的目的是為了防止活動的 LVS 控制器通知 realserver 和浮動服務 IP 直接相互通信,從而獲取 TCP/IP 捷徑(因為它們位于同一個子網中)。一般情況下,重定向是有用的,因為它們通過清除網絡連接中不必要的中間件提高了性能。但是此時,它可能阻礙了響應通信量的重寫,而這又是對客戶機透明所必需的。實際上,如果在 LVS 控制器上沒有禁用重定向,那么從 realserver 直接發往客戶機的通信量將被客戶機視為未被請求的網絡響應而被丟棄。
此時,可將每個 realserver 的默認路由設為指向服務的浮動 IP 地址,從而確保所有的響應都被傳回控制器以進行包重寫,然后再傳回最初發出請求的客戶機。
一旦在控制器上禁用重定向,并且 realserver 被配置為通過浮動服務 IP 發送所有的通信量,那么您可能需要測試 HA LVS 環境。要測試迄今為止所做的工作,可讓一個遠端客戶機上的 Web 瀏覽器指向 LVS 控制器的浮動服務地址。
為了在實驗室進行測試,我們使用的是基于 Gecko 的瀏覽器(Mozilla),但是任何其他瀏覽器也可以滿足要求。為了確保部署成功,在瀏覽器中禁用緩存,并多次單擊刷新按鈕。在每次刷新時,您應看見顯示的 Web 頁面是 realserver 上配置的一個自識別頁面。如果您要使用 RR 調度,您應可以看到連續通過每個 realserver 的頁面循環。
您是否正在思考確保 LVS 配置在引導時自動啟動?現在千萬別這樣做!還有一個步驟尚未完成(步驟 5),此步驟將執行 realserver 的活動監控(因此保留一個動態 Apache 節點列表,其中的節點可以為工作請求提供服務)。
步驟 5:在 LVS 控制器上安裝和配置 mon
迄今為止,您已經建立了一個高度可用的服務 IP 地址,并將其綁定到 realserver 實例池。但是在任何給定時間您決不能信任任何單個的 Apache 服務器是正常運作的。通過選擇 RR 調度,如果任何給定的 realserver 被禁用,或者以一種即時的方式停止響應網絡通信量,那么 1/6 的 HTTP 請求將會失敗!
因此有必要實施 realserver 對每個 LVS 控制器的監控,以便動態地將其添加到服務池中或從中刪除。另一個著名的稱為 mon 的開源包很適合這項任務。
mon 解決方案一般用于監控 LVS 真實節點。Mon 的配置相對容易,并且對于熟悉 shell 腳本編程的人而言可擴展性很好。讓所有組件正常運作大致分以下三個主要步驟:安裝、服務監控配置和警報創建。使用包管理工具處理 mon 的安裝。完成安裝后,您只需要調整監控配置,并創建一些警報腳本。當監視器確定 realserver 已經脫機或恢復聯機時,將觸發警報腳本。
注意,安裝 heartbeat v2 后,監控 realserver 可通過構建所有的 realserver 服務資源來完成。 或者,您可以使用 Heartbeat ldirectord 包。
默認情況下,mon 附帶了幾個可以直接使用的監視器機制。我們修改了 /etc/mon.cf 中的樣例配置文件以使用 HTTP 服務。
在 mon 配置文件中,確保標題可以反映正確的路徑。SLES10 是一個 64 位的 Linux 圖像,但是隨附的樣例配置用于默認的(31 位或 32 位)位置。配置文件樣例假定警報和監視器位于 /usr/lib 中,這對于我們的特定安裝而言并不正確。我們修改的參數如下:
alertdir = /usr/lib64/mon/alert.d
mondir = /usr/lib64/mon/mon.d
如您所見,我們只是將
lib
更改為
lib64
。對于您所使用的版本可能不需要這種更改。
對配置文件的下一個更改是指定要監控的 realserver 列表。這可以通過以下 6 個指令完成:
清單 6. 指定要監控的 realserver
hostgroup litstat1 192.168.71.220 # realserver 1 hostgroup litstat2 192.168.71.150 hostgroup litstat3 192.168.71.121 hostgroup litstat4 192.168.71.145 hostgroup litstat5 192.168.71.185 hostgroup litstat6 192.168.71.186 # realserver 6
|
如果您希望添加額外的 realserver,直接在此添加額外的條目即可。
一旦您處理好所有的定義,就需要告知 mon 如何查看故障,以及如何處理故障。為此,添加以下的監視器段(分別針對每個 realserver)。完成后,您需要將 mon 配置文件和警報置于每個 LVS heartbeat 節點之上,啟用每個 heartbeat 集群節點以獨立地監控所有的 realserver。
清單 7. /etc/mon/mon.cf 文件
# # global options # cfbasedir = /etc/mon
alertdir = /usr/lib64/mon/alert.d
mondir = /usr/lib64/mon/mon.d statedir = /var/lib/mon logdir = /var/log maxprocs = 20 histlength = 100 historicfile = mon_history.log randstart = 60s # # authentication types: # getpwnam standard Unix passwd, NOT for shadow passwords # shadow Unix shadow passwords (not implemented) # userfile "mon" user file # authtype = getpwnam # # downtime logging, uncomment to enable # if the server is running, don't forget to send a reset command # when you change this # #dtlogfile = downtime.log dtlogging = yes # # NB: hostgroup and watch entries are terminated with a blank line (or # end of file). Don't forget the blank lines between them or you lose. # # # group definitions (hostnames or IP addresses) # example: # # hostgroup servers www mail pop server4 server5 # # For simplicity we monitor each individual server as if it were a "group" # so we add only the hostname and the ip address of an individual node for each. hostgroup litstat1 192.168.71.220 hostgroup litstat2 192.168.71.150 hostgroup litstat3 192.168.71.121 hostgroup litstat4 192.168.71.145 hostgroup litstat5 192.168.71.185 hostgroup litstat6 192.168.71.186 # # Now we set identical watch definitions on each of our groups. They could be # customized to treat individual servers differently, but we have made the # configurations homogeneous here to match our homogeneous LVS configuration. # watch litstat1 service http description http check servers interval 6s
monitor http.monitor -p 80 -u /index.html
allow_empty_group period wd {Mon-Sun}
alert dowem.down.alert -h
upalert dowem.up.alert -h
alertevery 600s alertafter 1 watch litstat2 service http description http check servers interval 6s monitor http.monitor -p 80 -u /index.html allow_empty_group period wd {Mon-Sun} alert dowem.down.alert -h upalert dowem.up.alert -h alertevery 600s alertafter 1 watch litstat3 service http description http check servers interval 6s monitor http.monitor -p 80 -u /index.html allow_empty_group period wd {Mon-Sun} alert dowem.down.alert -h upalert dowem.up.alert -h alertevery 600s alertafter 1 watch litstat4 service http description http check servers interval 6s monitor http.monitor -p 80 -u /index.html allow_empty_group period wd {Mon-Sun} alert dowem.down.alert -h upalert dowem.up.alert -h alertevery 600s alertafter 1 watch litstat5 service http description http check servers interval 6s monitor http.monitor -p 80 -u /index.html allow_empty_group period wd {Mon-Sun} alert dowem.down.alert -h upalert dowem.up.alert -h alertevery 600s alertafter 1 watch litstat6 service http description http check servers interval 6s monitor http.monitor -p 80 -u /index.html allow_empty_group period wd {Mon-Sun} alert dowem.down.alert -h upalert dowem.up.alert -h alertevery 600s alertafter 1
|
清單 7 告知 mon 使用 http.monitor,默認情況下它由 mon 附帶。另外,指定使用端口 80。清單 7 還提供了要請求的特殊頁面;您可能會選擇為 Web 服務器傳輸一小段更有效率的 html 作為操作成功的證明,而不是傳輸一個復雜的默認 html 頁面。
alert
和
upalert
行調用的腳本必須置于配置文件頂部指定的
alertdir
中。其目錄通常是發行版所默認的目錄,比如 “/usr/lib64/mon/alert.d”。警報負責告知 LVS 將 Apache 服務器添加到合格的列表中或從中刪除(方法是調用
ipvsadm
命令,我們很快就要介紹到)。
當一個 realserver 的 http 測試失敗時,
dowem.down.alert
將由 mon 使用幾個參數自動執行。同樣地,當監視器確定 realserver 已經恢復聯機時,mon 進程使用大量的參數自動執行 dowem.up.alert。您可以隨意地修改警報腳本的名稱以適應您的部署。
保存此文件,在 alertdir 中創建警報(使用簡單的 bash 腳本編程)。清單 8 展示了一個 bash 腳本警報,重新建立 realserver 連接時由 mon 調用。
清單 8. 簡單警報:已連接上
#! /bin/bash # The h arg is followed by the hostname we are interested in acting on # So we skip ahead to get the -h option since we don't care about the others REALSERVER=192.168.71.205 while [ $1 != "-h" ] ; do shift done ADDHOST=$2 # For the HTTP service /sbin/ipvsadm -a -t $REALSERVER:http -r $ADDHOST:http -m -w 1 # For the HTTPS service /sbin/ipvsadm -a -t $REALSERVER:https -r $ADDHOST:https -m -w 1
|
清單 9 展示了一個 bash 腳本警報,當 realserver 連接丟失時由 mon 調用。
清單 9. 簡單警報:連接已丟失
#! /bin/bash # The h arg is followed by the hostname we are interested in acting on # So we skip ahead to get the -h option since we dont care about the others REALSERVER=192.168.71.205 while [ $1 != "-h" ] ; do shift done BADHOST=$2 # For the HTTP service /sbin/ipvsadm -d -t $REALSERVER:http -r $BADHOST # For the HTTPS service /sbin/ipvsadm -d -t $REALSERVER:https -r $BADHOST
|
這兩組腳本都使用
ipvsadm
命令行工具動態地將 realserver 添加到 LVS 表中或從中刪除。注意,這些腳本遠談不上完美。mon 只對于簡單的 Web 請求監控 http 端口,此處闡述的架構在下述情形中容易受到攻擊:給定的 realserver 對于 http 請求可能正常運作,但對于 SSL 請求卻不行。在這些情況下,我們將無法從 https 備選列表中刪除有問題的 realserver。當然,除了為 mon 配置文件中的每個 realserver 啟用另一個 https 監視器外,構建更多專門針對每種類型的 Web 請求的高級警報也可以輕松地解決這個問題。這可以留給讀者作為練習。
為確保監視器已被激活,依次為每個 realserver 啟用并禁用 Apache 進程,觀察每個控制器對事件的反應。只有當您確認每個控制器正常地監控每個 realserver 后,您才可以使用
chkconfig
命令確保 mon 進程可以在引導時自動啟動。使用的特定命令為
chkconfig mon on
,但是這可能隨發行版的不同而有所區別。
完成這個最后的部分后,您就已完成構建跨系統的高度可用的 Web 服務器基礎設施的任務。當然,您現在可能想要執行一些更高級的工作。例如,您可能已經注意到,mon 守護程序本身沒有被監控(heartbeat 項目可以為您監控 mon),但是最后的步驟已為此打下基礎。
故障診斷
活動節點在一個 HA 集群中不能正常運作有多種原因,自愿的或非自愿的。節點可能丟失與其他節點的網絡連接,heartbeat 進程可能被停止,可能出現任何環境事件等等。要故意地讓活動節點失效,您可以要求該節點暫停,或將其設為備用模式,方法是使用
hb_gui
(完全關閉)命令。如果您希望測試環境的健壯性,您可能需要一些更激進的方式。
指示器和故障恢復
系統管理員可以使用兩種日志文件指示器配置 Linux HA heartbeat 系統。日志文件與系統是否為浮動資源 IP 地址的接收方有關。沒有接收浮動資源 IP 地址的集群成員的日志結果類似于:
清單 10. 落選者的日志結果
litsha21:~ # cat /var/log/messages Jan 16 12:00:20 litsha21 heartbeat: [3057]: WARN: node litsha23: is dead Jan 16 12:00:21 litsha21 cib: [3065]: info: mem_handle_event: Got an event OC_EV_MS_NOT_PRIMARY from ccm Jan 16 12:00:21 litsha21 cib: [3065]: info: mem_handle_event: instance=13, nodes=3, new=1, lost=0, n_idx=0, new_idx=3, old_idx=6 Jan 16 12:00:21 litsha21 crmd: [3069]: info: mem_handle_event: Got an event OC_EV_MS_NOT_PRIMARY from ccm Jan 16 12:00:21 litsha21 crmd: [3069]: info: mem_handle_event: instance=13, nodes=3, new=1, lost=0, n_idx=0, new_idx=3, old_idx=6 Jan 16 12:00:21 litsha21 crmd: [3069]: info: crmd_ccm_msg_callback:callbacks.c Quorum lost after event=NOT PRIMARY (id=13) Jan 16 12:00:21 litsha21 heartbeat: [3057]: info: Link litsha23:eth1 dead. Jan 16 12:00:38 litsha21 ccm: [3064]: debug: quorum plugin: majority Jan 16 12:00:38 litsha21 ccm: [3064]: debug: cluster:linux-ha, member_count=2, member_quorum_votes=200 Jan 16 12:00:38 litsha21 ccm: [3064]: debug: total_node_count=3, total_quorum_votes=300 .................. Truncated For Brevity .................. Jan 16 12:00:40 litsha21 crmd: [3069]: info: update_dc:utils.c Set DC to litsha21 (1.0.6) Jan 16 12:00:41 litsha21 crmd: [3069]: info: do_state_transition:fsa.c litsha21: State transition S_INTEGRATION -> S_FINALIZE_JOIN [ input=I_INTEGRATED cause=C_FSA_INTERNAL origin=check_join_state ] Jan 16 12:00:41 litsha21 crmd: [3069]: info: do_state_transition:fsa.c All 2 cluster nodes responded to the join offer. Jan 16 12:00:41 litsha21 crmd: [3069]: info: update_attrd:join_dc.c Connecting to attrd... Jan 16 12:00:41 litsha21 cib: [3065]: info: sync_our_cib:messages.c Syncing CIB to all peers Jan 16 12:00:41 litsha21 attrd: [3068]: info: attrd_local_callback:attrd.c Sending full refresh .................. Truncated For Brevity .................. Jan 16 12:00:43 litsha21 pengine: [3112]: info: unpack_nodes:unpack.c Node litsha21 is in standby-mode Jan 16 12:00:43 litsha21 pengine: [3112]: info: determine_online_status:unpack.c Node litsha21 is online Jan 16 12:00:43 litsha21 pengine: [3112]: info: determine_online_status:unpack.c Node litsha22 is online Jan 16 12:00:43 litsha21 pengine: [3112]: info: IPaddr_1 (heartbeat::ocf:IPaddr): Stopped Jan 16 12:00:43 litsha21 pengine: [3112]: notice: StartRsc:native.c litsha22 Start IPaddr_1 Jan 16 12:00:43 litsha21 pengine: [3112]: notice: Recurring:native.c litsha22 IPaddr_1_monitor_5000 Jan 16 12:00:43 litsha21 pengine: [3112]: notice: stage8:stages.c Created transition graph 0. .................. Truncated For Brevity .................. Jan 16 12:00:46 litsha21 mgmtd: [3070]: debug: update cib finished Jan 16 12:00:46 litsha21 crmd: [3069]: info: do_state_transition:fsa.c litsha21: State transition S_TRANSITION_ENGINE -> S_IDLE [ input=I_TE_SUCCESS cause=C_IPC_MESSAGE origin=do_msg_route ] Jan 16 12:00:46 litsha21 cib: [3118]: info: write_cib_contents:io.c Wrote version 0.53.593 of the CIB to disk (digest: 83b00c386e8b67c42d033a4141aaef90)
|
如清單 10 所示,獲取了一份名單,有足夠的 quorum 成員可以投票。獲取投票,不需要執行其他操作即可恢復正常運作。
相反,接收了浮動資源 IP 地址的集群成員的日志結果如下:
清單 11. 資源持有者的日志文件
litsha22:~ # cat /var/log/messages Jan 16 12:00:06 litsha22 syslog-ng[1276]: STATS: dropped 0 Jan 16 12:01:51 litsha22 heartbeat: [3892]: WARN: node litsha23: is dead Jan 16 12:01:51 litsha22 heartbeat: [3892]: info: Link litsha23:eth1 dead. Jan 16 12:01:51 litsha22 cib: [3900]: info: mem_handle_event: Got an event OC_EV_MS_NOT_PRIMARY from ccm Jan 16 12:01:51 litsha22 cib: [3900]: info: mem_handle_event: instance=13, nodes=3, new=3, lost=0, n_idx=0, new_idx=0, old_idx=6 Jan 16 12:01:51 litsha22 crmd: [3904]: info: mem_handle_event: Got an event OC_EV_MS_NOT_PRIMARY from ccm Jan 16 12:01:51 litsha22 crmd: [3904]: info: mem_handle_event: instance=13, nodes=3, new=3, lost=0, n_idx=0, new_idx=0, old_idx=6 Jan 16 12:01:51 litsha22 crmd: [3904]: info: crmd_ccm_msg_callback:callbacks.c Quorum lost after event=NOT PRIMARY (id=13) Jan 16 12:02:09 litsha22 ccm: [3899]: debug: quorum plugin: majority Jan 16 12:02:09 litsha22 crmd: [3904]: info: do_election_count_vote:election.c Election check: vote from litsha21 Jan 16 12:02:09 litsha22 ccm: [3899]: debug: cluster:linux-ha, member_count=2, member_quorum_votes=200 Jan 16 12:02:09 litsha22 ccm: [3899]: debug: total_node_count=3, total_quorum_votes=300 Jan 16 12:02:09 litsha22 cib: [3900]: info: mem_handle_event: Got an event OC_EV_MS_INVALID from ccm Jan 16 12:02:09 litsha22 cib: [3900]: info: mem_handle_event: no mbr_track info Jan 16 12:02:09 litsha22 cib: [3900]: info: mem_handle_event: Got an event OC_EV_MS_NEW_MEMBERSHIP from ccm Jan 16 12:02:09 litsha22 cib: [3900]: info: mem_handle_event: instance=14, nodes=2, new=0, lost=1, n_idx=0, new_idx=2, old_idx=5 Jan 16 12:02:09 litsha22 cib: [3900]: info: cib_ccm_msg_callback:callbacks.c LOST: litsha23 Jan 16 12:02:09 litsha22 cib: [3900]: info: cib_ccm_msg_callback:callbacks.c PEER: litsha21 Jan 16 12:02:09 litsha22 cib: [3900]: info: cib_ccm_msg_callback:callbacks.c PEER: litsha22 .................. Truncated For Brevity .................. Jan 16 12:02:12 litsha22 crmd: [3904]: info: update_dc:utils.c Set DC to litsha21 (1.0.6) Jan 16 12:02:12 litsha22 crmd: [3904]: info: do_state_transition:fsa.c litsha22: State transition S_PENDING -> S_NOT_DC [ input=I_NOT_DC cause=C_HA_MESSAGE origin=do_cl_join_finalize_respond ] Jan 16 12:02:12 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client: 3069, call:25): 0.52.585 -> 0.52.586 (ok) .................. Truncated For Brevity .................. Jan 16 12:02:14 litsha22 IPaddr[3998]: INFO: /sbin/ifconfig eth0:0 192.168.71.205 netmask 255.255.255.0 broadcast 192.168.71.255 Jan 16 12:02:14 litsha22 IPaddr[3998]: INFO: Sending Gratuitous Arp for 192.168.71.205 on eth0:0 [eth0] Jan 16 12:02:14 litsha22 IPaddr[3998]: INFO: /usr/lib64/heartbeat/send_arp -i 500 -r 10 -p /var/run/heartbeat/rsctmp/send_arp/send_arp-192.168.71.205 eth0 192.168.71.205 auto 192.168.71.205 ffffffffffff Jan 16 12:02:14 litsha22 crmd: [3904]: info: process_lrm_event:lrm.c LRM operation (3) start_0 on IPaddr_1 complete Jan 16 12:02:14 litsha22 kernel: send_arp uses obsolete (PF_INET,SOCK_PACKET) Jan 16 12:02:14 litsha22 kernel: klogd 1.4.1, ---------- state change ---------- Jan 16 12:02:14 litsha22 kernel: NET: Registered protocol family 17 Jan 16 12:02:15 litsha22 crmd: [3904]: info: do_lrm_rsc_op:lrm.c Performing op monitor on IPaddr_1 (interval=5000ms, key=0:f9d962f0-4ed6-462d-a28d-e27b6532884c) Jan 16 12:02:15 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client: 3904, call:18): 0.53.591 -> 0.53.592 (ok) Jan 16 12:02:15 litsha22 mgmtd: [3905]: debug: update cib finished
|
如清單 11 所示,/var/log/messages 文件展示了此節點已經獲得了浮動資源。
ifconfig
行顯示將動態創建 eth0:0 設備以維持服務。
如清單 11 所示,獲取了一份名單,有足夠的 quorum 成員可以投票。獲取投票后,發出的
ifconfig
命令索要浮動資源 IP 地址。
另外一種指示何時發生故障的方法是,您可以登錄到任何一個集群成員并執行
hb_gui
命令。使用這種方法,您可以通過親自查找擁有浮動資源的系統來確定故障發生時間。
最后,如果我們不展示一個非 quorum 情形的樣例日志文件似乎有些說不過去。如果某個單一節點無法與任何一個其他節點進行通信,那么它就丟失了 quorum(因為在 3 個成員的投票中 2/3 是多數)。在這種情況下,節點獲悉已丟失 quorum,然后調用 no quorum policy 處理程序。清單 12 展示了一個來自這類事件的日志文件示例。丟失 quorum 時,日志條目將會有所顯示。顯示此日志條目的集群節點認為自己不具有浮動資源。
ifconfig down
語句將釋放資源。
清單 12. 顯示丟失 quorum 的日志條目
litsha22:~ # cat /var/log/messages .................... Jan 16 12:06:12 litsha22 ccm: [3899]: debug: quorum plugin: majority Jan 16 12:06:12 litsha22 ccm: [3899]: debug: cluster:linux-ha, member_count=1, member_quorum_votes=100 Jan 16 12:06:12 litsha22 ccm: [3899]: debug: total_node_count=3, total_quorum_votes=300 .................. Truncated For Brevity .................. Jan 16 12:06:12 litsha22 crmd: [3904]: info: crmd_ccm_msg_callback:callbacks.c Quorum lost after event=INVALID (id=15) Jan 16 12:06:12 litsha22 crmd: [3904]: WARN: check_dead_member:ccm.c Our DC node (litsha21) left the cluster .................. Truncated For Brevity .................. Jan 16 12:06:14 litsha22 IPaddr[5145]: INFO: /sbin/route -n del -host 192.168.71.205 Jan 16 12:06:15 litsha22 lrmd: [1619]: info: RA output: (IPaddr_1:stop:stderr) SIOCDELRT: No such process Jan 16 12:06:15 litsha22 IPaddr[5145]: INFO: /sbin/ifconfig eth0:0 192.168.71.205 down Jan 16 12:06:15 litsha22 IPaddr[5145]: INFO: IP Address 192.168.71.205 released Jan 16 12:06:15 litsha22 crmd: [3904]: info: process_lrm_event:lrm.c LRM operation (6) stop_0 on IPaddr_1 complete Jan 16 12:06:15 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client: 3904, call:32): 0.54.599 -> 0.54.600 (ok) Jan 16 12:06:15 litsha22 mgmtd: [3905]: debug: update cib finished
|
如清單 12 所示,當某個給定節點丟失 quorum 時,它將放棄所有資源,因為選擇了 no quorum policy 配置。是否選擇 no quorum policy 完全取決于您自己。
Fail-back 動作和消息
正確配置的 Linux HA 系統的一個更有趣的含義是,您不需要執行任何操作就可重新實例化集群成員。只需要激活 Linux 實例即可讓節點自動地重新加入其他節點。如果您配置了一個主節點(即,一個可以優先于其他節點獲得浮動資源的節點),它將自動重新獲得浮動資源。非優先的系統將只是加入合格節點池并正常運作。
將其他的 Linux 實例往回添加到池中將使每個節點獲得通知,并且如果可能的話,重新建立 quorum。如果可以重新建立 quorum,那么將在某個節點上重新建立浮動資源。
清單 13. 重新建立 Quorum
litsha22:~ # tail -f /var/log/messages Jan 16 12:09:02 litsha22 heartbeat: [3892]: info: Heartbeat restart on node litsha21 Jan 16 12:09:02 litsha22 heartbeat: [3892]: info: Link litsha21:eth1 up. Jan 16 12:09:02 litsha22 heartbeat: [3892]: info: Status update for node litsha21: status init Jan 16 12:09:02 litsha22 heartbeat: [3892]: info: Status update for node litsha21: status up Jan 16 12:09:22 litsha22 heartbeat: [3892]: debug: get_delnodelist: delnodelist= Jan 16 12:09:22 litsha22 heartbeat: [3892]: info: Status update for node litsha21: status active Jan 16 12:09:22 litsha22 cib: [3900]: info: cib_client_status_callback:callbacks.c Status update: Client litsha21/cib now has status [join] Jan 16 12:09:23 litsha22 heartbeat: [3892]: WARN: 1 lost packet(s) for [litsha21] [36:38] Jan 16 12:09:23 litsha22 heartbeat: [3892]: info: No pkts missing from litsha21! Jan 16 12:09:23 litsha22 crmd: [3904]: notice: crmd_client_status_callback:callbacks.c Status update: Client litsha21/crmd now has status [online] .................... Jan 16 12:09:31 litsha22 crmd: [3904]: info: crmd_ccm_msg_callback:callbacks.c Quorum (re)attained after event=NEW MEMBERSHIP (id=16) Jan 16 12:09:31 litsha22 crmd: [3904]: info: ccm_event_detail:ccm.c NEW MEMBERSHIP: trans=16, nodes=2, new=1, lost=0 n_idx=0, new_idx=2, old_idx=5 Jan 16 12:09:31 litsha22 crmd: [3904]: info: ccm_event_detail:ccm.c CURRENT: litsha22 [nodeid=1, born=13] Jan 16 12:09:31 litsha22 crmd: [3904]: info: ccm_event_detail:ccm.c CURRENT: litsha21 [nodeid=0, born=16] Jan 16 12:09:31 litsha22 crmd: [3904]: info: ccm_event_detail:ccm.c NEW: litsha21 [nodeid=0, born=16] Jan 16 12:09:31 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Local-only Change (client:3904, call: 35): 0.54.600 (ok) Jan 16 12:09:31 litsha22 mgmtd: [3905]: debug: update cib finished .................... Jan 16 12:09:34 litsha22 crmd: [3904]: info: update_dc:utils.c Set DC to litsha22 (1.0.6) Jan 16 12:09:35 litsha22 cib: [3900]: info: sync_our_cib:messages.c Syncing CIB to litsha21 Jan 16 12:09:35 litsha22 crmd: [3904]: info: do_state_transition:fsa.c litsha22: State transition S_INTEGRATION -> S_FINALIZE_JOIN [ input=I_INTEGRATED cause=C_FSA_INTERNAL origin=check_join_state ] Jan 16 12:09:35 litsha22 crmd: [3904]: info: do_state_transition:fsa.c All 2 cluster nodes responded to the join offer. Jan 16 12:09:35 litsha22 attrd: [3903]: info: attrd_local_callback:attrd.c Sending full refresh Jan 16 12:09:35 litsha22 cib: [3900]: info: sync_our_cib:messages.c Syncing CIB to all peers ......................... Jan 16 12:09:37 litsha22 tengine: [5119]: info: send_rsc_command:actions.c Initiating action 4: IPaddr_1_start_0 on litsha22 Jan 16 12:09:37 litsha22 tengine: [5119]: info: send_rsc_command:actions.c Initiating action 2: probe_complete on litsha21 Jan 16 12:09:37 litsha22 crmd: [3904]: info: do_lrm_rsc_op:lrm.c Performing op start on IPaddr_1 (interval=0ms, key=2:c5131d14-a9d9-400c-a4b1-60d8f5fbbcce) Jan 16 12:09:37 litsha22 pengine: [5120]: info: process_pe_message:pengine.c Transition 2: PEngine Input stored in: /var/lib/heartbeat/pengine/pe-input-72.bz2 Jan 16 12:09:37 litsha22 IPaddr[5196]: INFO: /sbin/ifconfig eth0:0 192.168.71.205 netmask 255.255.255.0 broadcast 192.168.71.255 Jan 16 12:09:37 litsha22 IPaddr[5196]: INFO: Sending Gratuitous Arp for 192.168.71.205 on eth0:0 [eth0] Jan 16 12:09:37 litsha22 IPaddr[5196]: INFO: /usr/lib64/heartbeat/send_arp -i 500 -r 10 -p /var/run/heartbeat/rsctmp/send_arp/send_arp-192.168.71.205 eth0 192.168.71.205 auto 192.168.71.205 ffffffffffff Jan 16 12:09:37 litsha22 crmd: [3904]: info: process_lrm_event:lrm.c LRM operation (7) start_0 on IPaddr_1 complete Jan 16 12:09:37 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client: 3904, call:46): 0.55.607 -> 0.55.608 (ok) Jan 16 12:09:37 litsha22 mgmtd: [3905]: debug: update cib finished Jan 16 12:09:37 litsha22 tengine: [5119]: info: te_update_diff:callbacks.c Processing diff (cib_update): 0.55.607 -> 0.55.608 Jan 16 12:09:37 litsha22 tengine: [5119]: info: match_graph_event:events.c Action IPaddr_1_start_0 (4) confirmed Jan 16 12:09:37 litsha22 tengine: [5119]: info: send_rsc_command:actions.c Initiating action 5: IPaddr_1_monitor_5000 on litsha22 Jan 16 12:09:37 litsha22 crmd: [3904]: info: do_lrm_rsc_op:lrm.c Performing op monitor on IPaddr_1 (interval=5000ms, key=2:c5131d14-a9d9-400c-a4b1-60d8f5fbbcce) Jan 16 12:09:37 litsha22 cib: [5268]: info: write_cib_contents:io.c Wrote version 0.55.608 of the CIB to disk (digest: 98cb6685c25d14131c49a998dbbd0c35) Jan 16 12:09:37 litsha22 crmd: [3904]: info: process_lrm_event:lrm.c LRM operation (8) monitor_5000 on IPaddr_1 complete Jan 16 12:09:38 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client: 3904, call:47): 0.55.608 -> 0.55.609 (ok) Jan 16 12:09:38 litsha22 mgmtd: [3905]: debug: update cib finished
|
在清單 13 中,您可以看見 quorum 已被重新建立。重新建立 quorum 后,執行投票,而 litsha22 將變為具有浮動資源的活動節點。
結束語
高可用性被視為一系列挑戰,本文介紹的解決方案描述了第一個步驟。從這里開始,在您的開發環境中有多種方法可以繼續操作:您可以選擇安裝冗余的網絡、集群文件系統以支持 realserver,或安裝更高級的中間件直接支持集群。
|